@@ -16,131 +16,18 @@ create or replace type body ut_junit_reporter is
1616 limitations under the License.
1717 */
1818
19- constructor function ut_junit_reporter(
20- self in out nocopy ut_junit_reporter,
21- a_version in integer) return self as result is
19+ constructor function ut_junit_reporter(self in out nocopy ut_junit_reporter) return self as result is
2220 begin
2321 self.init($$plsql_unit);
24- junit_version := a_version;
2522 return;
2623 end;
2724
2825 overriding member procedure after_calling_run(self in out nocopy ut_junit_reporter, a_run in ut_run) is
2926 begin
30- if self.junit_version = 1 then
3127 junit_version_one(a_run);
32- else
33- junit_version_four(a_run);
34- end if;
3528 end;
3629
37- member procedure junit_version_four(self in out nocopy ut_junit_reporter,a_run in ut_run) is
38- l_suite_id integer := 0;
39- l_tests_count integer := a_run.results_count.disabled_count + a_run.results_count.success_count +
40- a_run.results_count.failure_count + a_run.results_count.errored_count;
41- function get_common_item_attributes(a_item ut_suite_item) return varchar2 is
42- begin
43- return ' skipped="' || a_item.results_count.disabled_count ||
44- '" error="' || a_item.results_count.errored_count ||
45- '"' || ' failure="' || a_item.results_count.failure_count ||
46- '" name="' || dbms_xmlgen.convert(nvl(a_item.description, a_item.name)) || '"' ||
47- ' time="' || ut_utils.to_xml_number_format(a_item.execution_time()) || '" ';
48- end;
49-
50- function get_path(a_path_with_name varchar2, a_name varchar2) return varchar2 is
51- begin
52- return regexp_substr(a_path_with_name, '(.*)\.' ||a_name||'$',subexpression=>1);
53- end;
54-
55- procedure print_test_elements(a_test ut_test) is
56- l_lines ut_varchar2_list;
57- l_output clob;
58- begin
59- self.print_text('<testcase classname="' || dbms_xmlgen.convert(get_path(a_test.path, a_test.name)) || '" ' || ' assertions="' ||
60- nvl(a_test.all_expectations.count,0) || '"' || get_common_item_attributes(a_test) || case when
61- a_test.result != ut_utils.tr_success then
62- ' status="' || ut_utils.test_result_to_char(a_test.result) || '"' end || '>');
63- if a_test.result = ut_utils.tr_disabled then
64- self.print_text('<skipped/>');
65- end if;
66- if a_test.result = ut_utils.tr_error then
67- self.print_text('<error>');
68- self.print_text('<![CDATA[');
69- self.print_clob(ut_utils.table_to_clob(a_test.get_error_stack_traces()));
70- self.print_text(']]>');
71- self.print_text('</error>');
72- elsif a_test.result > ut_utils.tr_success then
73- self.print_text('<failure>');
74- self.print_text('<![CDATA[');
75- for i in 1 .. a_test.failed_expectations.count loop
76- l_lines := a_test.failed_expectations(i).get_result_lines();
77- for j in 1 .. l_lines.count loop
78- self.print_text(l_lines(j));
79- end loop;
80- self.print_text(a_test.failed_expectations(i).caller_info);
81- end loop;
82- self.print_text(']]>');
83- self.print_text('</failure>');
84- end if;
85- -- TODO - decide if we need/want to use the <system-err/> tag too
86- l_output := a_test.get_serveroutputs();
87- if l_output is not null then
88- self.print_text('<system-out>');
89- self.print_text('<![CDATA[');
90- self.print_clob(l_output);
91- self.print_text(']]>');
92- self.print_text('</system-out>');
93- end if;
94- self.print_text('</testcase>');
95- end;
96-
97- procedure print_suite_elements(a_suite ut_logical_suite, a_suite_id in out nocopy integer) is
98- l_tests_count integer := a_suite.results_count.disabled_count + a_suite.results_count.success_count +
99- a_suite.results_count.failure_count + a_suite.results_count.errored_count;
100- l_suite ut_suite;
101- begin
102- a_suite_id := a_suite_id + 1;
103- self.print_text('<testsuite tests="' || l_tests_count || '"' || ' id="' || a_suite_id || '"' || ' package="' ||
104- dbms_xmlgen.convert(a_suite.path) || '" ' || get_common_item_attributes(a_suite) || '>');
105- if a_suite is of(ut_suite) then
106- l_suite := treat(a_suite as ut_suite);
107-
108- if l_suite.before_all.serveroutput is not null or l_suite.after_all.serveroutput is not null then
109- self.print_text('<system-out>');
110- self.print_text('<![CDATA[');
111- self.print_clob(l_suite.get_serveroutputs());
112- self.print_text(']]>');
113- self.print_text('</system-out>');
114- end if;
115-
116- if l_suite.before_all.error_stack is not null or l_suite.after_all.error_stack is not null then
117- self.print_text('<system-err>');
118- self.print_text('<![CDATA[');
119- self.print_text(trim(l_suite.before_all.error_stack) || trim(chr(10) || chr(10) || l_suite.after_all.error_stack));
120- self.print_text(']]>');
121- self.print_text('</system-err>');
122- end if;
123- end if;
124-
125- for i in 1 .. a_suite.items.count loop
126- if a_suite.items(i) is of(ut_test) then
127- print_test_elements(treat(a_suite.items(i) as ut_test));
128- elsif a_suite.items(i) is of(ut_logical_suite) then
129- print_suite_elements(treat(a_suite.items(i) as ut_logical_suite), a_suite_id);
130- end if;
131- end loop;
132- self.print_text('</testsuite>');
133- end;
134- begin
135- l_suite_id := 0;
136- self.print_text('<testsuites tests="' || l_tests_count || '"' || get_common_item_attributes(a_run) || '>');
137- for i in 1 .. a_run.items.count loop
138- print_suite_elements(treat(a_run.items(i) as ut_logical_suite), l_suite_id);
139- end loop;
140- self.print_text('</testsuites>');
141- end;
142-
143- member procedure junit_version_one(self in out nocopy ut_junit_reporter,a_run in ut_run) is
30+ member procedure junit_version_one(self in out nocopy ut_junit_reporter,a_run in ut_run) is
14431 l_suite_id integer := 0;
14532 l_tests_count integer := a_run.results_count.disabled_count + a_run.results_count.success_count +
14633 a_run.results_count.failure_count + a_run.results_count.errored_count;
@@ -166,7 +53,7 @@ create or replace type body ut_junit_reporter is
16653 return regexp_substr(a_path_with_name, '(.*)\.' ||a_name||'$',subexpression=>1);
16754 end;
16855
169- procedure print_test_elements (a_test ut_test) is
56+ procedure print_test_results (a_test ut_test) is
17057 l_lines ut_varchar2_list;
17158 l_output clob;
17259 begin
@@ -204,34 +91,36 @@ create or replace type body ut_junit_reporter is
20491 self.print_text('</testcase>');
20592 end;
20693
207- procedure print_suite_elements (a_suite ut_logical_suite, a_suite_id in out nocopy integer) is
94+ procedure print_suite_results (a_suite ut_logical_suite, a_suite_id in out nocopy integer) is
20895 l_tests_count integer := a_suite.results_count.disabled_count + a_suite.results_count.success_count +
20996 a_suite.results_count.failure_count + a_suite.results_count.errored_count;
21097 l_suite ut_suite;
21198 begin
212- a_suite_id := a_suite_id + 1;
213- self.print_text('<testsuite tests="' || l_tests_count || '"' || ' id="' || a_suite_id || '"' || ' package="' ||
214- dbms_xmlgen.convert(a_suite.path) || '" ' || get_common_suite_attributes(a_suite) || '>');
215- self.print_text('<properties/>');
216-
99+
217100 for i in 1 .. a_suite.items.count loop
218- if a_suite.items(i) is of(ut_test) then
219- print_test_elements(treat(a_suite.items(i) as ut_test));
220- elsif a_suite.items(i) is of(ut_logical_suite) then
221- print_suite_elements(treat(a_suite.items(i) as ut_logical_suite), a_suite_id);
101+ if a_suite.items(i) is of(ut_logical_suite) then
102+ print_suite_results(treat(a_suite.items(i) as ut_logical_suite), a_suite_id);
222103 end if;
223- end loop;
224-
225- if a_suite is of(ut_suite) then
104+ end loop;
105+
106+ if a_suite is of(ut_suite) then
107+ a_suite_id := a_suite_id + 1;
108+ self.print_text('<testsuite tests="' || l_tests_count || '"' || ' id="' || a_suite_id || '"' || ' package="' ||
109+ dbms_xmlgen.convert(a_suite.path) || '" ' || get_common_suite_attributes(a_suite) || '>');
110+ self.print_text('<properties/>');
111+ for i in 1 .. a_suite.items.count loop
112+ if a_suite.items(i) is of(ut_test) then
113+ print_test_results(treat(a_suite.items(i) as ut_test));
114+ end if;
115+ end loop;
226116 l_suite := treat(a_suite as ut_suite);
227-
228117 if l_suite.before_all.serveroutput is not null or l_suite.after_all.serveroutput is not null then
229118 self.print_text('<system-out>');
230119 self.print_text('<![CDATA[');
231120 self.print_clob(l_suite.get_serveroutputs());
232121 self.print_text(']]>');
233122 self.print_text('</system-out>');
234- else
123+ else
235124 self.print_text('<system-out/>');
236125 end if;
237126
@@ -244,24 +133,24 @@ create or replace type body ut_junit_reporter is
244133 else
245134 self.print_text('<system-err/>');
246135 end if;
136+ self.print_text('</testsuite>');
247137 end if;
138+ end;
248139
249- self.print_text('</testsuite>');
250- end;
251140 begin
252141 l_suite_id := 0;
253142 self.print_text('<testsuites>');
254143 for i in 1 .. a_run.items.count loop
255- print_suite_elements (treat(a_run.items(i) as ut_logical_suite), l_suite_id);
144+ print_suite_results (treat(a_run.items(i) as ut_logical_suite), l_suite_id);
256145 end loop;
257146 self.print_text('</testsuites>');
258147 end;
259148
260149 overriding member function get_description return varchar2 as
261150 begin
262- return 'Provides outcomes in a format conforming with JUnit. Based on attribute a_version we can get output for version 4 or 1 .
263- Version 4 and above is defined in: https://gist.github .com/kuzuha/232902acab1344d6b578.
264- Version 1 is based on windy road junit https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd.';
151+ return 'Provides outcomes in a format conforming with JUnit version for TFS / VSTS .
152+ As defined by specs : https://docs.microsoft .com/en-us/vsts/build-release/tasks/test/publish-test-results?view=vsts
153+ Version is based on windy road junit https://github.com/windyroad/JUnit-Schema/blob/master/JUnit.xsd.';
265154 end;
266155
267156end;
0 commit comments