The XML format used by Jenkins is under-specified. So after loosely googling and a lot of trials and errors here is some improvement of the XML that enhance the user experience on Jenkins.
To experiment, I used a false job to see the results of nitunit for the test cases in tests (where a lot are expected to fails)
* the (ANSI-colored) log: http://gresil.org/jenkins/job/ZZnothing/195/console
* the results: http://gresil.org/jenkins/job/ZZnothing/195/testReport/
The main improvements are:
* messages are open by default (when you click on the + of a failed tests)
* add a time (not impressive but might be useful on real tests)
* all test cases are counted
* more readable names. Compare with http://gresil.org/jenkins/job/ZZnothing/189/testReport/ for instance
Pull-Request: #2182
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
It is expected that the created/updated files are checked since the tests are considered passed.
A VCS like `git` is often a good tool to check the creation and modification of those files.
+### `--no-time`
+Disable time information in XML.
+
+This is used to have reproducible XML results.
+
+This option is automatically activated if `NIT_TESTING` is set.
+
## SUITE GENERATION
### `--gen-suite`
exit(0)
end
+# When testing `nitunit`, disable time.
+if "NIT_TESTING".environ != "" then
+ toolcontext.opt_no_time.value = true
+end
+
"NIT_TESTING".setenv("true")
"NIT_TESTING_ID".setenv(pid.to_s)
"SRAND".setenv("0")
var opt_noact = new OptionBool("Does not compile and run tests", "--no-act")
# opt --nitc
var opt_nitc = new OptionString("nitc compiler to use", "--nitc")
+ # opt --no-time
+ var opt_no_time = new OptionBool("Disable time information in XML", "--no-time")
# Working directory for testing.
fun test_dir: String do
# Additional noteworthy information when a test success.
var info: nullable String = null
+ # Time for the execution, in seconds
+ var real_time: Float = 0.0 is writable
+
# A colorful `[OK]` or `[KO]`.
fun status_tag(color: nullable Bool): String do
color = color or else true
var tc = new HTMLTag("testcase")
tc.attr("classname", xml_classname)
tc.attr("name", xml_name)
+ tc.attr("time", real_time.to_s)
+
+ var output = self.raw_output
+ if output != null then output = output.trunc(8192).filter_nonprintable
var error = self.error
if error != null then
+ var node
if was_exec then
- tc.open("error").append(error)
+ node = tc.open("error").attr("message", error)
else
- tc.open("failure").append(error)
+ node = tc.open("failure").attr("message", error)
end
- end
- var output = self.raw_output
- if output != null then
- tc.open("system-err").append(output.trunc(8192).filter_nonprintable)
+ if output != null then
+ node.append(output)
+ end
+ else if output != null then
+ tc.open("system-err").append(output)
end
return tc
end
import testing_base
import markdown
import html
+import realtime
# Extractor, Executor and Reporter for the tests in a module
class NitUnitExecutor
var file = du.test_file.as(not null)
var i = du.test_arg.as(not null)
toolcontext.info("Execute doc-unit {du.full_name} in {file} {i}", 1)
+ var clock = new Clock
var res2 = toolcontext.safe_exec("{file.to_program_name}.bin {i} >'{file}.out1' 2>&1 </dev/null")
+ if not toolcontext.opt_no_time.value then du.real_time = clock.total
du.was_exec = true
var content = "{file}.out1".to_path.read_all
var res = compile_unitfile(file)
var res2 = 0
if res == 0 then
+ var clock = new Clock
res2 = toolcontext.safe_exec("{file.to_program_name}.bin >'{file}.out1' 2>&1 </dev/null")
+ if not toolcontext.opt_no_time.value then du.real_time = clock.total
du.was_exec = true
end
var ndoc = nclassdef.n_doc
if ndoc != null then
doc_entities += 1
- d2m.extract(ndoc.to_mdoc, "nitunit." + mmodule.full_name + "." + mclassdef.mclass.full_name, "<class>")
+ d2m.extract(ndoc.to_mdoc, "nitunit." + mclassdef.full_name.replace("$", "."), "<class>")
end
end
for npropdef in nclassdef.n_propdefs do
var ndoc = npropdef.n_doc
if ndoc != null then
doc_entities += 1
- d2m.extract(ndoc.to_mdoc, "nitunit." + mmodule.full_name + "." + mclassdef.mclass.full_name, mpropdef.mproperty.full_name)
+ var a = mpropdef.full_name.split("$")
+ d2m.extract(ndoc.to_mdoc, "nitunit." + a[0] + "." + a[1], a[2])
end
end
end
doc_entities += 1
# NOTE: jenkins expects a '.' in the classname attr
- d2m.extract(mdoc, "nitunit." + mgroup.full_name, "<group>")
+ d2m.extract(mdoc, "nitunit." + mgroup.mpackage.name + "." + mgroup.name + ".<group>", "<group>")
d2m.run_tests
import testing_base
import html
private import annotation
+private import realtime
redef class ToolContext
# --pattern
end
write_to_nit
compile
+ if failure != null then
+ for case in test_cases do
+ case.is_done = true
+ case.error = "Compilation Error"
+ case.raw_output = failure
+ toolcontext.modelbuilder.failed_tests += 1
+ toolcontext.clear_progress_bar
+ toolcontext.show_unit(case)
+ end
+ show_status
+ print ""
+ return
+ end
toolcontext.info("Execute test-suite {mmodule.name}", 1)
var before_module = self.before_module
if not before_module == null then before_module.run
fun to_xml: HTMLTag do
var n = new HTMLTag("testsuite")
n.attr("package", mmodule.name)
- var failure = self.failure
- if failure != null then
- var f = new HTMLTag("failure")
- f.attr("message", failure.to_s)
- n.add f
- else
- for test in test_cases do n.add test.to_xml
- end
+ for test in test_cases do n.add test.to_xml
return n
end
var f = new FileReader.open("{file}.out")
var msg = f.read_all
f.close
- # set test case result
- var loc = mmodule.location
if res != 0 then
failure = msg
- toolcontext.warning(loc, "failure", "FAILURE: {mmodule.name} (in file {file}.nit): {msg}")
- toolcontext.modelbuilder.failed_tests += 1
end
- toolcontext.check_errors
end
# Error occured during test-suite compilation.
var method_name = test_method.name
var test_file = test_suite.test_file
var res_name = "{test_file}_{method_name.escape_to_c}"
+ var clock = new Clock
var res = toolcontext.safe_exec("{test_file}.bin {method_name} > '{res_name}.out1' 2>&1 </dev/null")
+ if not toolcontext.opt_no_time.value then real_time = clock.total
+
var raw_output = "{res_name}.out1".to_path.read_all
self.raw_output = raw_output
# set test case result
end
redef fun xml_classname do
- var mclassdef = test_method.mclassdef
- return "nitunit." + mclassdef.mmodule.full_name + "." + mclassdef.mclass.full_name
+ var a = test_method.full_name.split("$")
+ return "nitunit.{a[0]}.{a[1]}"
end
redef fun xml_name do
- return test_method.mproperty.full_name
+ var a = test_method.full_name.split("$")
+ return a[2]
end
end
Test suites: Classes: 1; Test Cases: 3; Failures: 1
[FAILURE] 4/7 tests failed.
`nitunit.out` is not removed for investigation.
-<testsuites><testsuite package="test_nitunit::test_nitunit"><testcase classname="nitunit.test_nitunit::test_nitunit.<module>" name="<module>"><system-err></system-err><system-out>assert true
-</system-out></testcase><testcase classname="nitunit.test_nitunit::test_nitunit.test_nitunit::X" name="<class>"><error>Runtime error in nitunit.out/test_nitunit-2.nit</error><system-err>Runtime error: Assert failed (nitunit.out/test_nitunit-2.nit:5)
-</system-err><system-out>assert false
-</system-out></testcase><testcase classname="nitunit.test_nitunit::test_nitunit.test_nitunit::X" name="test_nitunit::X::foo"><failure>Compilation error in nitunit.out/test_nitunit-3.nit</failure><system-err>nitunit.out/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`.
-</system-err><system-out>assert undefined_identifier
-</system-out></testcase><testcase classname="nitunit.test_nitunit::test_nitunit.test_nitunit::X" name="test_nitunit::X::foo1"><failure>Syntax Error: unexpected operator '!'.</failure><system-out>assert !@#$%^&*()
-</system-out></testcase></testsuite><testsuite package="test_test_nitunit::test_test_nitunit"></testsuite><testsuite package="test_test_nitunit"><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo"><system-err></system-err></testcase><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo1"><error>Runtime Error in file nitunit.out/gen_test_test_nitunit.nit</error><system-err>Runtime error: Assert failed (test_test_nitunit.nit:39)
-</system-err></testcase><testcase classname="nitunit.test_test_nitunit::test_test_nitunit.test_test_nitunit::TestX" name="test_test_nitunit::TestX::test_foo2"><system-err></system-err></testcase></testsuite></testsuites>
\ No newline at end of file
+<testsuites><testsuite package="test_nitunit::test_nitunit"><testcase classname="nitunit.test_nitunit::test_nitunit.<module>" name="<module>" time="0.0"><system-err></system-err><system-out>assert true
+</system-out></testcase><testcase classname="nitunit.test_nitunit.X" name="<class>" time="0.0"><error message="Runtime error in nitunit.out/test_nitunit-2.nit">Runtime error: Assert failed (nitunit.out/test_nitunit-2.nit:5)
+</error><system-out>assert false
+</system-out></testcase><testcase classname="nitunit.test_nitunit.X" name="foo" time="0.0"><failure message="Compilation error in nitunit.out/test_nitunit-3.nit">nitunit.out/test_nitunit-3.nit:5,8--27: Error: method or variable `undefined_identifier` unknown in `Sys`.
+</failure><system-out>assert undefined_identifier
+</system-out></testcase><testcase classname="nitunit.test_nitunit.X" name="foo1" time="0.0"><failure message="Syntax Error: unexpected operator '!'."></failure><system-out>assert !@#$%^&*()
+</system-out></testcase></testsuite><testsuite package="test_test_nitunit::test_test_nitunit"></testsuite><testsuite package="test_test_nitunit"><testcase classname="nitunit.test_test_nitunit.TestX" name="test_foo" time="0.0"><system-err></system-err></testcase><testcase classname="nitunit.test_test_nitunit.TestX" name="test_foo1" time="0.0"><error message="Runtime Error in file nitunit.out/gen_test_test_nitunit.nit">Runtime error: Assert failed (test_test_nitunit.nit:39)
+</error></testcase><testcase classname="nitunit.test_test_nitunit.TestX" name="test_foo2" time="0.0"><system-err></system-err></testcase></testsuite></testsuites>
\ No newline at end of file
Docunits: Entities: 4; Documented ones: 3; With nitunits: 3; Failures: 0
Test suites: Classes: 0; Test Cases: 0
[SUCCESS] All 3 tests passed.
-<testsuites><testsuite package="test_nitunit2::test_nitunit2"><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::foo1"><system-err></system-err><system-out>if true then
+<testsuites><testsuite package="test_nitunit2::test_nitunit2"><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="foo1" time="0.0"><system-err></system-err><system-out>if true then
assert true
end
-</system-out></testcase><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::bar2"><system-err></system-err><system-out>if true then
+</system-out></testcase><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="bar2" time="0.0"><system-err></system-err><system-out>if true then
assert true
end
-</system-out></testcase><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="test_nitunit2::test_nitunit2::Sys::foo3"><system-err></system-err><system-out>var a = 1
+</system-out></testcase><testcase classname="nitunit.test_nitunit2::test_nitunit2.core::Sys" name="foo3" time="0.0"><system-err></system-err><system-out>var a = 1
assert a == 1
assert a == 1
</system-out></testcase></testsuite></testsuites>
\ No newline at end of file
Docunits: Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 0
Test suites: Classes: 0; Test Cases: 0
[SUCCESS] All 3 tests passed.
-<testsuites><testsuite package="test_doc2::test_doc2"><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo1"><system-err></system-err><system-out>assert true # tested
-</system-out></testcase><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo2"><system-err></system-err><system-out>assert true # tested
-</system-out></testcase><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="test_doc2::test_doc2::Sys::foo3"><system-err></system-err><system-out>assert true # tested
+<testsuites><testsuite package="test_doc2::test_doc2"><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="foo1" time="0.0"><system-err></system-err><system-out>assert true # tested
+</system-out></testcase><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="foo2" time="0.0"><system-err></system-err><system-out>assert true # tested
+</system-out></testcase><testcase classname="nitunit.test_doc2::test_doc2.core::Sys" name="foo3" time="0.0"><system-err></system-err><system-out>assert true # tested
</system-out></testcase></testsuite></testsuites>
\ No newline at end of file
Test suites: Classes: 0; Test Cases: 0
[FAILURE] 2/3 tests failed.
`nitunit.out` is not removed for investigation.
-<testsuites><testsuite package="test_nitunit3>"><testcase classname="nitunit.test_nitunit3>" name="<group>"><error>Runtime error in nitunit.out/test_nitunit3-0.nit with argument 1</error><system-err>Runtime error: Assert failed (nitunit.out/test_nitunit3-0.nit:7)
-</system-err><system-out>assert false
+<testsuites><testsuite package="test_nitunit3>"><testcase classname="nitunit.test_nitunit3.test_nitunit3.<group>" name="<group>" time="0.0"><error message="Runtime error in nitunit.out/test_nitunit3-0.nit with argument 1">Runtime error: Assert failed (nitunit.out/test_nitunit3-0.nit:7)
+</error><system-out>assert false
assert true
-</system-out></testcase><testcase classname="nitunit.test_nitunit3>" name="<group>#2"><failure>Syntax Error: unexpected malformed character '\].</failure><system-out>;'\][]
-</system-out></testcase></testsuite><testsuite package="test_nitunit3::test_nitunit3"><testcase classname="nitunit.test_nitunit3::test_nitunit3.<module>" name="<module>"><system-err></system-err><system-out>assert true
+</system-out></testcase><testcase classname="nitunit.test_nitunit3.test_nitunit3.<group>" name="<group>#2" time="0.0"><failure message="Syntax Error: unexpected malformed character '\]."></failure><system-out>;'\][]
+</system-out></testcase></testsuite><testsuite package="test_nitunit3::test_nitunit3"><testcase classname="nitunit.test_nitunit3::test_nitunit3.<module>" name="<module>" time="0.0"><system-err></system-err><system-out>assert true
</system-out></testcase></testsuite></testsuites>
\ No newline at end of file
Test suites: Classes: 0; Test Cases: 0
[FAILURE] 1/1 tests failed.
`nitunit.out` is not removed for investigation.
-<testsuites><testsuite package="test_nitunit_md.md"><testcase classname="nitunit.<file>" name="test_nitunit_md.md"><error>Runtime error in nitunit.out/file-0.nit with argument 1</error><system-err>Runtime error: Assert failed (nitunit.out/file-0.nit:8)
-</system-err><system-out>var a = 1
+<testsuites><testsuite package="test_nitunit_md.md"><testcase classname="nitunit.<file>" name="test_nitunit_md.md" time="0.0"><error message="Runtime error in nitunit.out/file-0.nit with argument 1">Runtime error: Assert failed (nitunit.out/file-0.nit:8)
+</error><system-out>var a = 1
assert 1 == 1
assert false
</system-out></testcase></testsuite></testsuites>
\ No newline at end of file
Test suites: Classes: 0; Test Cases: 0
[FAILURE] 3/3 tests failed.
`nitunit.out` is not removed for investigation.
-<testsuites><testsuite package="test_doc3::test_doc3"><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo1"><failure>Syntax Error: unexpected identifier 'garbage'.</failure><system-out> *garbage*
-</system-out></testcase><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo2"><failure>Syntax Error: unexpected identifier 'garbage'.</failure><system-out>*garbage*
-</system-out></testcase><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="test_doc3::test_doc3::Sys::foo3"><failure>Syntax Error: unexpected identifier 'garbage'.</failure><system-out>*garbage*
+<testsuites><testsuite package="test_doc3::test_doc3"><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="foo1" time="0.0"><failure message="Syntax Error: unexpected identifier 'garbage'."></failure><system-out> *garbage*
+</system-out></testcase><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="foo2" time="0.0"><failure message="Syntax Error: unexpected identifier 'garbage'."></failure><system-out>*garbage*
+</system-out></testcase><testcase classname="nitunit.test_doc3::test_doc3.core::Sys" name="foo3" time="0.0"><failure message="Syntax Error: unexpected identifier 'garbage'."></failure><system-out>*garbage*
</system-out></testcase></testsuite></testsuites>
\ No newline at end of file
+test_nitunit4/test_bad_comp2.nit:19,7--22: Error: a class named `test_nitunit4::TestSuiteBadComp` is already defined in module `test_bad_comp` at test_nitunit4/test_bad_comp.nit:19,1--29,3.
+==== Test-suite of module test_nitunit4::test_bad_comp | tests: 2
+[KO] test_nitunit4$TestSuiteBadComp$test_good
+ test_nitunit4/test_bad_comp.nit:22,2--24,4: Compilation Error
+ Output
+ test_nitunit4/test_bad_comp.nit:27,10--19: Error: method or variable `bad_method` unknown in `TestSuiteBadComp`.
+
+[KO] test_nitunit4$TestSuiteBadComp$test_bad
+ test_nitunit4/test_bad_comp.nit:26,2--28,4: Compilation Error
+ Output
+ test_nitunit4/test_bad_comp.nit:27,10--19: Error: method or variable `bad_method` unknown in `TestSuiteBadComp`.
+
+
+==== Test-suite of module test_nitunit4::test_bad_comp2 | tests: 2
+[KO] test_nitunit4$TestSuiteBadComp$test_good
+ test_nitunit4/test_bad_comp2.nit:22,2--24,4: Compilation Error
+ Output
+ nitunit.out/gen_test_bad_comp2.nit:14,10--17: Error: expected 1 argument(s) for `test_bad(param: Bool)`; got 0. See introduction at `test_nitunit4::TestSuiteBadComp::test_bad`.
+
+[KO] test_nitunit4$TestSuiteBadComp$test_bad
+ test_nitunit4/test_bad_comp2.nit:26,2--28,4: Compilation Error
+ Output
+ nitunit.out/gen_test_bad_comp2.nit:14,10--17: Error: expected 1 argument(s) for `test_bad(param: Bool)`; got 0. See introduction at `test_nitunit4::TestSuiteBadComp::test_bad`.
+
+
==== Test-suite of module test_nitunit4::test_nitunit4 | tests: 4
[KO] test_nitunit4$TestTestSuite$test_foo
test_nitunit4/test_nitunit4.nit:22,2--26,4: Runtime Error in file nitunit.out/gen_test_nitunit4.nit
==== Test-suite of module test_nitunit4::test_nitunit4_base | tests: 0
==== Test-suite of module test_nitunit4::test_nitunit4_base | tests: 0
-Docunits: Entities: 13; Documented ones: 0; With nitunits: 0
-Test suites: Classes: 2; Test Cases: 4; Failures: 3
-[FAILURE] 3/4 tests failed.
+Docunits: Entities: 21; Documented ones: 0; With nitunits: 0
+Test suites: Classes: 4; Test Cases: 8; Failures: 7
+[FAILURE] 7/8 tests failed.
`nitunit.out` is not removed for investigation.
-<testsuites><testsuite package="test_nitunit4>"></testsuite><testsuite package="test_nitunit4::nitunit4"></testsuite><testsuite package="test_nitunit4::test_nitunit4"></testsuite><testsuite package="test_nitunit4"><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_foo"><error>Runtime Error in file nitunit.out/gen_test_nitunit4.nit</error><system-err>Before Test
+<testsuites><testsuite package="test_nitunit4>"></testsuite><testsuite package="test_nitunit4::nitunit4"></testsuite><testsuite package="test_nitunit4::test_bad_comp"></testsuite><testsuite package="test_bad_comp"><testcase classname="nitunit.test_nitunit4.TestSuiteBadComp" name="test_good" time="0.0"><failure message="Compilation Error">test_nitunit4/test_bad_comp.nit:27,10--19: Error: method or variable `bad_method` unknown in `TestSuiteBadComp`.
+</failure></testcase><testcase classname="nitunit.test_nitunit4.TestSuiteBadComp" name="test_bad" time="0.0"><failure message="Compilation Error">test_nitunit4/test_bad_comp.nit:27,10--19: Error: method or variable `bad_method` unknown in `TestSuiteBadComp`.
+</failure></testcase></testsuite><testsuite package="test_nitunit4::test_bad_comp2"></testsuite><testsuite package="test_bad_comp2"><testcase classname="nitunit.test_nitunit4.TestSuiteBadComp" name="test_good" time="0.0"><failure message="Compilation Error">nitunit.out/gen_test_bad_comp2.nit:14,10--17: Error: expected 1 argument(s) for `test_bad(param: Bool)`; got 0. See introduction at `test_nitunit4::TestSuiteBadComp::test_bad`.
+</failure></testcase><testcase classname="nitunit.test_nitunit4.TestSuiteBadComp" name="test_bad" time="0.0"><failure message="Compilation Error">nitunit.out/gen_test_bad_comp2.nit:14,10--17: Error: expected 1 argument(s) for `test_bad(param: Bool)`; got 0. See introduction at `test_nitunit4::TestSuiteBadComp::test_bad`.
+</failure></testcase></testsuite><testsuite package="test_nitunit4::test_nitunit4"></testsuite><testsuite package="test_nitunit4"><testcase classname="nitunit.test_nitunit4.TestTestSuite" name="test_foo" time="0.0"><error message="Runtime Error in file nitunit.out/gen_test_nitunit4.nit">Before Test
Tested method
After Test
Runtime error: Assert failed (test_nitunit4/test_nitunit4_base.nit:31)
-</system-err></testcase><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_bar"><system-err>Before Test
+</error></testcase><testcase classname="nitunit.test_nitunit4.TestTestSuite" name="test_bar" time="0.0"><system-err>Before Test
Tested method
After Test
-</system-err></testcase><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_baz"><error>Difference with expected output: diff -u test_nitunit4/test_baz.res nitunit.out/gen_test_nitunit4_test_baz.out1</error><system-err>Diff
+</system-err></testcase><testcase classname="nitunit.test_nitunit4.TestTestSuite" name="test_baz" time="0.0"><error message="Difference with expected output: diff -u test_nitunit4/test_baz.res nitunit.out/gen_test_nitunit4_test_baz.out1">Diff
--- expected:test_nitunit4/test_baz.res
+++ got:nitunit.out/gen_test_nitunit4_test_baz.out1
@@ -1 +1,3 @@
+Before Test
+Tested method
+After Test
-</system-err></testcase><testcase classname="nitunit.test_nitunit4::test_nitunit4.test_nitunit4::TestTestSuite" name="test_nitunit4::TestTestSuite::test_sav_conflict"><error>Conflicting expected output: test_nitunit4/test_nitunit4.sav/test_sav_conflict.res, test_nitunit4/sav/test_sav_conflict.res and test_nitunit4/test_sav_conflict.res all exist</error><system-err>Before Test
+</error></testcase><testcase classname="nitunit.test_nitunit4.TestTestSuite" name="test_sav_conflict" time="0.0"><error message="Conflicting expected output: test_nitunit4/test_nitunit4.sav/test_sav_conflict.res, test_nitunit4/sav/test_sav_conflict.res and test_nitunit4/test_sav_conflict.res all exist">Before Test
Tested method
After Test
-</system-err></testcase></testsuite><testsuite package="test_nitunit4::test_nitunit4_base"></testsuite><testsuite package="test_nitunit4_base"></testsuite></testsuites>
\ No newline at end of file
+</error></testcase></testsuite><testsuite package="test_nitunit4::test_nitunit4_base"></testsuite><testsuite package="test_nitunit4_base"></testsuite></testsuites>
\ No newline at end of file
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module test_bad_comp is test_suite
+
+import test_suite
+
+class TestSuiteBadComp
+ super TestSuite
+
+ fun test_good do
+ assert true
+ end
+
+ fun test_bad do
+ assert bad_method
+ end
+end
--- /dev/null
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+module test_bad_comp2 is test_suite
+
+import test_suite
+
+class TestSuiteBadComp
+ super TestSuite
+
+ fun test_good do
+ assert true
+ end
+
+ fun test_bad(param: Bool) do
+ assert param
+ end
+end