Skip to content

Commit

Permalink
Merge pull request #1270 from utPLSQL/feature/1257_missing_testcases_…
Browse files Browse the repository at this point in the history
…tfs_reporter

Update TFS reporter to correct format
  • Loading branch information
jgebal committed Feb 18, 2024
2 parents fe4e3e9 + d974ce3 commit eb8bb06
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 45 deletions.
98 changes: 61 additions & 37 deletions source/reporters/ut_tfs_junit_reporter.tpb
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ create or replace type body ut_tfs_junit_reporter is
return regexp_substr(a_path_with_name, '(.*)\.' ||a_name||'$',subexpression=>1);
end;

procedure print_test_results(a_test ut_test) is
function add_test_results(a_test ut_test) return ut_varchar2_rows is
l_results ut_varchar2_rows := ut_varchar2_rows();
begin
self.print_text('<testcase classname="' || dbms_xmlgen.convert(get_path(a_test.path, a_test.name)) || '" ' ||
ut_utils.append_to_list( l_results,'<testcase classname="' || dbms_xmlgen.convert(get_path(a_test.path, a_test.name)) || '" ' ||
get_common_testcase_attributes(a_test) || '>');

/*
According to specs :
- A failure is a test which the code has explicitly failed by using the mechanisms for that purpose.
Expand Down Expand Up @@ -83,64 +84,87 @@ create or replace type body ut_tfs_junit_reporter is

ut_utils.append_to_list( l_results, '</testcase>');

self.print_text_lines(l_results);
return l_results;
end;

procedure print_suite_results(a_suite ut_logical_suite, a_suite_id in out nocopy integer) is
procedure print_suite_results(a_suite ut_logical_suite, a_suite_id in out nocopy integer, a_nested_tests in out nocopy ut_varchar2_rows) is
l_tests_count integer := a_suite.results_count.disabled_count + a_suite.results_count.success_count +
a_suite.results_count.failure_count + a_suite.results_count.errored_count;
l_results ut_varchar2_rows := ut_varchar2_rows();
l_suite ut_suite;
l_outputs clob;
l_errors ut_varchar2_list;
begin

l_tests ut_varchar2_list;
begin
for i in 1 .. a_suite.items.count loop
if a_suite.items(i) is of(ut_logical_suite) then
print_suite_results(treat(a_suite.items(i) as ut_logical_suite), a_suite_id);
if a_suite.items(i) is of(ut_suite_context) then
print_suite_results(treat(a_suite.items(i) as ut_suite_context), a_suite_id, a_nested_tests);
elsif a_suite.items(i) is of(ut_suite) then
print_suite_results(treat(a_suite.items(i) as ut_suite), a_suite_id, a_nested_tests);
elsif a_suite.items(i) is of(ut_logical_suite) then
print_suite_results(treat(a_suite.items(i) as ut_logical_suite), a_suite_id, a_nested_tests);
end if;
end loop;

if a_suite is of(ut_suite) then
a_suite_id := a_suite_id + 1;
self.print_text('<testsuite tests="' || l_tests_count || '"' || ' id="' || a_suite_id || '"' || ' package="' ||
dbms_xmlgen.convert(a_suite.path) || '" ' || get_common_suite_attributes(a_suite) || '>');
self.print_text('<properties/>');
--Due to fact tha TFS and junit5 accepts only flat structure we have to report in suite level only.
if a_suite is of(ut_suite_context) then
for i in 1 .. a_suite.items.count loop
if a_suite.items(i) is of(ut_test) then
print_test_results(treat(a_suite.items(i) as ut_test));
ut_utils.append_to_list( a_nested_tests,(add_test_results(treat(a_suite.items(i) as ut_test))));
end if;
end loop;
l_suite := treat(a_suite as ut_suite);
l_outputs := l_suite.get_serveroutputs();
if l_outputs is not null and l_outputs != empty_clob() then
ut_utils.append_to_list( l_results, '<system-out>');
ut_utils.append_to_list( l_results, ut_utils.to_cdata( l_suite.get_serveroutputs() ) );
ut_utils.append_to_list( l_results, '</system-out>');
else
ut_utils.append_to_list( l_results, '<system-out/>');
end if;

l_errors := l_suite.get_error_stack_traces();
if l_errors is not empty then
ut_utils.append_to_list( l_results, '<system-err>');
ut_utils.append_to_list( l_results, ut_utils.to_cdata( ut_utils.convert_collection( l_errors ) ) );
ut_utils.append_to_list( l_results, '</system-err>');
else
ut_utils.append_to_list( l_results, '<system-err/>');
end if;
ut_utils.append_to_list( l_results, '</testsuite>');

self.print_text_lines(l_results);
elsif a_suite is of(ut_suite) then
for i in 1 .. a_suite.items.count loop
if a_suite.items(i) is of(ut_test) then
ut_utils.append_to_list( a_nested_tests,(add_test_results(treat(a_suite.items(i) as ut_test))));
end if;
end loop;
--TFS doesnt report on empty test suites, however all we want to make sure is that we dont pring parents suites
-- showing test count but not tests.
if (a_nested_tests.count > 0 and l_tests_count > 0) or (a_nested_tests.count = 0 and l_tests_count = 0) then
a_suite_id := a_suite_id + 1;
ut_utils.append_to_list( l_results,'<testsuite tests="' || l_tests_count || '"' || ' id="' || a_suite_id || '"' || ' package="' ||
dbms_xmlgen.convert(a_suite.path) || '" ' || get_common_suite_attributes(a_suite) || '>');
ut_utils.append_to_list( l_results,'<properties/>');
ut_utils.append_to_list(l_results,a_nested_tests);
l_suite := treat(a_suite as ut_suite);
l_outputs := l_suite.get_serveroutputs();
if l_outputs is not null and l_outputs != empty_clob() then
ut_utils.append_to_list( l_results, '<system-out>');
ut_utils.append_to_list( l_results, ut_utils.to_cdata( l_suite.get_serveroutputs() ) );
ut_utils.append_to_list( l_results, '</system-out>');
else
ut_utils.append_to_list( l_results, '<system-out/>');
end if;

l_errors := l_suite.get_error_stack_traces();
if l_errors is not empty then
ut_utils.append_to_list( l_results, '<system-err>');
ut_utils.append_to_list( l_results, ut_utils.to_cdata( ut_utils.convert_collection( l_errors ) ) );
ut_utils.append_to_list( l_results, '</system-err>');
else
ut_utils.append_to_list( l_results, '<system-err/>');
end if;
ut_utils.append_to_list( l_results, '</testsuite>');

self.print_text_lines(l_results);
--We have resolved a context and we now reset value.
a_nested_tests := ut_varchar2_rows();
end if;
end if;
end;

procedure get_suite_results(a_suite ut_logical_suite, a_suite_id in out nocopy integer) is
l_nested_tests ut_varchar2_rows:= ut_varchar2_rows();
begin
print_suite_results(a_suite, l_suite_id,l_nested_tests);
end;

begin
l_suite_id := 0;
self.print_text(ut_utils.get_xml_header(a_run.client_character_set));
self.print_text('<testsuites>');
for i in 1 .. a_run.items.count loop
print_suite_results(treat(a_run.items(i) as ut_logical_suite), l_suite_id);
get_suite_results(treat(a_run.items(i) as ut_logical_suite), l_suite_id);
end loop;
self.print_text('</testsuites>');
end;
Expand Down
161 changes: 153 additions & 8 deletions test/ut3_user/reporters/test_tfs_junit_reporter.pkb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ create or replace package body test_tfs_junit_reporter as

--%test(A test with <tag>)
procedure test_do_stuff;

end;]';
execute immediate q'[create or replace package body check_junit_reporting is
procedure test_do_stuff is
Expand All @@ -18,12 +18,12 @@ create or replace package body test_tfs_junit_reporter as
end;

end;]';

execute immediate q'[create or replace package check_junit_rep_suitepath is
--%suitepath(core)
--%suite(check_junit_rep_suitepath)
--%displayname(Check JUNIT Get path for suitepath)

--%test(check_junit_rep_suitepath)
--%displayname(Check JUNIT Get path for suitepath)
procedure check_junit_rep_suitepath;
Expand All @@ -38,7 +38,7 @@ create or replace package body test_tfs_junit_reporter as
execute immediate q'[create or replace package check_junit_flat_suitepath is
--%suitepath(core.check_junit_rep_suitepath)
--%suite(flatsuitepath)

--%beforeall
procedure donuffin;
end;]';
Expand All @@ -49,8 +49,85 @@ create or replace package body test_tfs_junit_reporter as
end;
end;]';

end;
execute immediate q'[create or replace package check_junit_in_context is
--%suitepath(core.check_junit_rep_suitepath)
--%suite(inctxsuite)
--%displayname(JUNIT test are inside context)

-- %context(incontext)
-- %name(incontext)

--%test(incontext)
--%displayname(Check JUNIT Get path incontext)
procedure check_junit_rep_incontext;

-- %endcontext
end;]';
execute immediate q'[create or replace package body check_junit_in_context is
procedure check_junit_rep_incontext is
begin
ut3_develop.ut.expect(1).to_equal(1);
end;
end;]';

execute immediate q'[create or replace package check_junit_out_context is
--%suitepath(core)
--%suite(outctxsuite)
--%displayname(JUNIT test are outside context)

-- %context(outcontext)
-- %name(outcontext)

-- %endcontext


--%test(outctx)
--%displayname(outctx)
procedure outctx;


end;]';
execute immediate q'[create or replace package body check_junit_out_context is
procedure outctx is
begin
ut3_develop.ut.expect(1).to_equal(1);
end;
end;]';

execute immediate q'[create or replace package check_junit_inout_context is
--%suitepath(core)
--%suite(inoutcontext)
--%displayname(Test in and out of context)

-- %context(incontext)
-- %name(ProductincontextFeatures)

--%test(inctx)
--%displayname(inctx)
procedure inctx;

-- %endcontext


--%test(outctx)
--%displayname(outctx)
procedure outctx;


end;]';
execute immediate q'[create or replace package body check_junit_inout_context is
procedure inctx is
begin
ut3_develop.ut.expect(1).to_equal(1);
end;

procedure outctx is
begin
ut3_develop.ut.expect(1).to_equal(1);
end;
end;]';

end;

procedure escapes_special_chars is
l_results ut3_develop.ut_varchar2_list;
Expand Down Expand Up @@ -92,7 +169,7 @@ create or replace package body test_tfs_junit_reporter as
--Assert
ut.expect(l_actual).to_be_like('%testcase classname="check_junit_reporting"%');
end;

procedure check_flatten_nested_suites is
l_results ut3_develop.ut_varchar2_list;
l_actual clob;
Expand All @@ -111,7 +188,7 @@ create or replace package body test_tfs_junit_reporter as
<system-err/>
</testsuite>%');
end;

procedure check_nls_number_formatting is
l_results ut3_develop.ut_varchar2_list;
l_actual clob;
Expand Down Expand Up @@ -163,5 +240,73 @@ create or replace package body test_tfs_junit_reporter as
reporters.check_xml_encoding_included(ut3_develop.ut_tfs_junit_reporter(), 'UTF-8');
end;

procedure reports_only_test_in_ctx is
l_results ut3_develop.ut_varchar2_list;
l_actual clob;
begin
--Act
select *
bulk collect into l_results
from table(ut3_develop.ut.run('check_junit_in_context',ut3_develop.ut_tfs_junit_reporter()));
l_actual := ut3_tester_helper.main_helper.table_to_clob(l_results);
--Assert
ut.expect(l_actual).to_be_like('<?xml version="1.0"?>
<testsuites>
<testsuite tests="1" id="1" package="core.check_junit_rep_suitepath.check_junit_in_context" errors="0" failures="0" name="JUNIT test are inside context" time="%" timestamp="%" hostname="%" >
<properties/>
<testcase classname="core.check_junit_rep_suitepath.check_junit_in_context.incontext" name="Check JUNIT Get path incontext" time="%">
</testcase>
<system-out/>
<system-err/>
</testsuite>
</testsuites>%');
end;

procedure reports_only_test_out_ctx is
l_results ut3_develop.ut_varchar2_list;
l_actual clob;
begin
--Act
select *
bulk collect into l_results
from table(ut3_develop.ut.run('check_junit_out_context',ut3_develop.ut_tfs_junit_reporter()));
l_actual := ut3_tester_helper.main_helper.table_to_clob(l_results);
--Assert
ut.expect(l_actual).to_be_like('<?xml version="1.0"?>
<testsuites>
<testsuite tests="1" id="1" package="core.check_junit_out_context" errors="0" failures="0" name="JUNIT test are outside context" time="%" timestamp="%" hostname="%" >
<properties/>
<testcase classname="core.check_junit_out_context" name="outctx" time="%">
</testcase>
<system-out/>
<system-err/>
</testsuite>
</testsuites>%');
end;

procedure reports_only_test_inout_ctx is
l_results ut3_develop.ut_varchar2_list;
l_actual clob;
begin
--Act
select *
bulk collect into l_results
from table(ut3_develop.ut.run('check_junit_inout_context',ut3_develop.ut_tfs_junit_reporter()));
l_actual := ut3_tester_helper.main_helper.table_to_clob(l_results);
--Assert
ut.expect(l_actual).to_be_like('<?xml version="1.0"?>
<testsuites>
<testsuite tests="2" id="1" package="core.check_junit_inout_context" errors="0" failures="0" name="Test in and out of context" time="%" timestamp="%" hostname="%" >
<properties/>
<testcase classname="core.check_junit_inout_context.ProductincontextFeatures" name="inctx" time="%">
</testcase>
<testcase classname="core.check_junit_inout_context" name="outctx" time="%">
</testcase>
<system-out/>
<system-err/>
</testsuite>
</testsuites>%');
end;

end;
/
/
9 changes: 9 additions & 0 deletions test/ut3_user/reporters/test_tfs_junit_reporter.pks
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ create or replace package test_tfs_junit_reporter as
--%test(Includes XML header with encoding when encoding provided)
procedure check_encoding_included;

--%test(Reports only testsuites where there are any testcases, all tests are in context)
procedure reports_only_test_in_ctx;

--%test(Reports only testsuites where there are any testcases, all tests are outside context)
procedure reports_only_test_out_ctx;

--%test(Reports only testsuites where there are any testcases, one test in ctx one test outside)
procedure reports_only_test_inout_ctx;

--%afterall
procedure remove_test_package;
end;
Expand Down

0 comments on commit eb8bb06

Please sign in to comment.