1- create or replace type body ut_xunit_reporter is
1+ create or replace type body ut_junit_reporter is
22 /*
33 utPLSQL - Version 3
44 Copyright 2016 - 2017 utPLSQL Project
@@ -15,14 +15,13 @@ create or replace type body ut_xunit_reporter is
1515 See the License for the specific language governing permissions and
1616 limitations under the License.
1717 */
18-
19- constructor function ut_xunit_reporter(self in out nocopy ut_xunit_reporter) return self as result is
18+ constructor function ut_junit_reporter(self in out nocopy ut_junit_reporter) return self as result is
2019 begin
2120 self.init($$plsql_unit);
2221 return;
2322 end;
2423
25- overriding member procedure after_calling_run(self in out nocopy ut_xunit_reporter , a_run in ut_run) is
24+ overriding member procedure after_calling_run(self in out nocopy ut_junit_reporter , a_run in ut_run) is
2625 l_suite_id integer := 0;
2726 l_tests_count integer := a_run.results_count.disabled_count + a_run.results_count.success_count +
2827 a_run.results_count.failure_count + a_run.results_count.errored_count;
@@ -35,9 +34,11 @@ create or replace type body ut_xunit_reporter is
3534 procedure print_test_elements(a_test ut_test) is
3635 l_lines ut_varchar2_list;
3736 l_output clob;
37+ l_cdata_tag_start varchar2(10) := '<![CDATA[';
38+ l_cddata_tag_end varchar2(10) := ']]>';
3839 begin
39- self.print_text('<testcase classname="' || dbms_xmlgen.convert(get_path(a_test.path, a_test.name)) || '" ' || ' assertions="' ||
40- nvl(a_test.all_expectations.count,0) || '"' || self.get_common_item_attributes (a_test) || case when
40+ self.print_text('<testcase classname="' || dbms_xmlgen.convert(get_path(a_test.path, a_test.name)) || '"' || ' assertions="' ||
41+ nvl(a_test.all_expectations.count,0) || '"' || self.get_common_test_attributes (a_test) || case when
4142 a_test.result != ut_utils.gc_success then
4243 ' status="' || ut_utils.test_result_to_char(a_test.result) || '"' end || '>');
4344 if a_test.result = ut_utils.gc_disabled then
@@ -46,16 +47,22 @@ create or replace type body ut_xunit_reporter is
4647 if a_test.result = ut_utils.gc_error then
4748 self.print_text('<error>');
4849 self.print_text('<![CDATA[');
49- self.print_clob(ut_utils.table_to_clob(a_test.get_error_stack_traces()));
50+ self.print_clob(
51+ replace(replace(ut_utils.table_to_clob(a_test.get_error_stack_traces()),l_cdata_tag_start,''),l_cddata_tag_end,'')
52+ );
5053 self.print_text(']]>');
5154 self.print_text('</error>');
5255 elsif a_test.result > ut_utils.gc_success then
5356 self.print_text('<failure>');
5457 self.print_text('<![CDATA[');
5558 for i in 1 .. a_test.failed_expectations.count loop
59+
5660 l_lines := a_test.failed_expectations(i).get_result_lines();
61+
5762 for j in 1 .. l_lines.count loop
58- self.print_text(l_lines(j));
63+ self.print_text(
64+ replace(replace(l_lines(j),l_cdata_tag_start,''),l_cddata_tag_end,'')
65+ );
5966 end loop;
6067 self.print_text(a_test.failed_expectations(i).caller_info);
6168 end loop;
@@ -70,6 +77,17 @@ create or replace type body ut_xunit_reporter is
7077 self.print_clob(l_output);
7178 self.print_text(']]>');
7279 self.print_text('</system-out>');
80+ else
81+ self.print_text('<system-out/>');
82+ end if;
83+ if a_test.before_test.get_error_stack_trace() is not null or a_test.after_test.get_error_stack_trace() is not null then
84+ self.print_text('<system-err>');
85+ self.print_text('<![CDATA[');
86+ self.print_text(trim(a_test.before_test.get_error_stack_trace()) || trim(chr(10) || chr(10) || a_test.after_test.get_error_stack_trace()));
87+ self.print_text(']]>');
88+ self.print_text('</system-err>');
89+ else
90+ self.print_text('<system-err/>');
7391 end if;
7492 self.print_text('</testcase>');
7593 end;
@@ -78,10 +96,35 @@ create or replace type body ut_xunit_reporter is
7896 l_tests_count integer := a_suite.results_count.disabled_count + a_suite.results_count.success_count +
7997 a_suite.results_count.failure_count + a_suite.results_count.errored_count;
8098 l_suite ut_suite;
99+ l_tests ut_suite_items := ut_suite_items();
81100 begin
82101 a_suite_id := a_suite_id + 1;
83102 self.print_text('<testsuite tests="' || l_tests_count || '"' || ' id="' || a_suite_id || '"' || ' package="' ||
84- dbms_xmlgen.convert(a_suite.path) || '" ' || self.get_common_item_attributes(a_suite) || '>');
103+ dbms_xmlgen.convert(a_suite.path) || '" ' || self.get_common_suite_attributes(a_suite) || '>');
104+
105+ -- Becasue testsuites have to appear before test we capture test and leave it for later.
106+ for i in 1 .. a_suite.items.count loop
107+ if a_suite.items(i) is of(ut_test) then
108+ l_tests.extend;
109+ l_tests(l_tests.last) := treat(a_suite.items(i) as ut_test);
110+ elsif a_suite.items(i) is of(ut_logical_suite) then
111+ print_suite_elements(treat(a_suite.items(i) as ut_logical_suite), a_suite_id);
112+ end if;
113+ end loop;
114+
115+ -- Now when all testsuite are printed do the testcases.
116+ for i in 1 .. l_tests.count loop
117+ print_test_elements(treat(l_tests(i) as ut_test));
118+ end loop;
119+
120+ /*for i in 1 .. a_suite.items.count loop
121+ if a_suite.items(i) is of(ut_test) then
122+ print_test_elements(treat(a_suite.items(i) as ut_test));
123+ elsif a_suite.items(i) is of(ut_logical_suite) then
124+ print_suite_elements(treat(a_suite.items(i) as ut_logical_suite), a_suite_id);
125+ end if;
126+ end loop;*/
127+
85128 if a_suite is of(ut_suite) then
86129 l_suite := treat(a_suite as ut_suite);
87130
@@ -91,6 +134,8 @@ create or replace type body ut_xunit_reporter is
91134 self.print_clob(l_suite.get_serveroutputs());
92135 self.print_text(']]>');
93136 self.print_text('</system-out>');
137+ else
138+ self.print_text('<system-out/>');
94139 end if;
95140
96141 if l_suite.before_all.error_stack is not null or l_suite.after_all.error_stack is not null then
@@ -99,36 +144,36 @@ create or replace type body ut_xunit_reporter is
99144 self.print_text(trim(l_suite.before_all.error_stack) || trim(chr(10) || chr(10) || l_suite.after_all.error_stack));
100145 self.print_text(']]>');
101146 self.print_text('</system-err>');
147+ else
148+ self.print_text('<system-err/>');
102149 end if;
103150 end if;
104-
105- for i in 1 .. a_suite.items.count loop
106- if a_suite.items(i) is of(ut_test) then
107- print_test_elements(treat(a_suite.items(i) as ut_test));
108- elsif a_suite.items(i) is of(ut_logical_suite) then
109- print_suite_elements(treat(a_suite.items(i) as ut_logical_suite), a_suite_id);
110- end if;
111- end loop;
112151 self.print_text('</testsuite>');
113152 end;
114153 begin
115154 l_suite_id := 0;
116- self.print_text('<testsuites tests="' || l_tests_count || '"' || self.get_common_item_attributes (a_run) || '>');
155+ self.print_text('<testsuites tests="' || l_tests_count || '"' || self.get_common_suite_attributes (a_run) || '>');
117156 for i in 1 .. a_run.items.count loop
118157 print_suite_elements(treat(a_run.items(i) as ut_logical_suite), l_suite_id);
119158 end loop;
120159 self.print_text('</testsuites>');
121160 end;
122161
123- member function get_common_item_attributes (a_item ut_suite_item) return varchar2 is
162+ member function get_common_suite_attributes (a_item ut_suite_item) return varchar2 is
124163 begin
125- return ' skipped ="' || a_item.results_count.disabled_count
126- || '" error ="' || a_item.results_count.errored_count
127- || '" failure ="' || a_item.results_count.failure_count
164+ return ' disabled ="' || a_item.results_count.disabled_count
165+ || '" errors ="' || a_item.results_count.errored_count
166+ || '" failures ="' || a_item.results_count.failure_count
128167 || '" name="' || dbms_xmlgen.convert(nvl(a_item.description, a_item.name))
129168 || '" time="' || ut_utils.to_xml_number_format(a_item.execution_time()) || '" ';
130169 end;
131170
171+ member function get_common_test_attributes(a_item ut_suite_item) return varchar2 is
172+ begin
173+ return ' name="' || dbms_xmlgen.convert(nvl(a_item.description, a_item.name))
174+ || '" time="' || ut_utils.to_xml_number_format(a_item.execution_time()) || '" ';
175+ end;
176+
132177 overriding member function get_description return varchar2 as
133178 begin
134179 return 'Provides outcomes in a format conforming with JUnit 4 and above as defined in: https://gist.github.com/kuzuha/232902acab1344d6b578';
0 commit comments