Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "TestReports"
uuid = "dcd651b4-b50a-5b6b-8f22-87e9f253a252"
version = "0.5.0"
version = "0.5.1"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
4 changes: 3 additions & 1 deletion src/testsets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ A `ReportingTestSet` has the `description` and `results` fields as per a
- `start_time::DateTime`: the start date and time of the testing (local system time).
- `time_taken::Millisecond`: the time taken in milliseconds to run the `TestSet`.
- `last_record_time::DateTime`: the time when `record` was last called.
- `hostname::String`: the name of host on which the testset was executed.

See also: [`flatten_results!`](@ref), [`recordproperty`](@ref), [`report`](@ref)
"""
Expand All @@ -51,9 +52,10 @@ mutable struct ReportingTestSet <: AbstractTestSet
start_time::DateTime
time_taken::Millisecond
last_record_time::DateTime
hostname::String
end

ReportingTestSet(desc) = ReportingTestSet(desc, [], Dict(), now(), Millisecond(0), now())
ReportingTestSet(desc) = ReportingTestSet(desc, [], Dict(), now(), Millisecond(0), now(), gethostname())
function record(ts::ReportingTestSet, t::Result)
push!(ts.results, ReportingResult(t, now()-ts.last_record_time))
ts.last_record_time = now()
Expand Down
21 changes: 10 additions & 11 deletions src/to_xml.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,36 +28,34 @@ set_attribute!(node, attr, val) = setindex!(node, string(val), attr)
set_attribute!(node, attr, val::Period) = setindex!(node, format_period_for_xml(val), attr)

"""
testsuites_xml(name, id, ntests, nfails, nerrors, x_children)
testsuites_xml(ntests, nfails, nerrors, x_children)

Create the testsuites element of a JUnit XML.
"""
function testsuites_xml(name, id, ntests, nfails, nerrors, x_children)
function testsuites_xml(ntests, nfails, nerrors, x_children)
x_testsuite = ElementNode("testsuites")
link!.(Ref(x_testsuite), x_children)
set_attribute!(x_testsuite, "name", name)
set_attribute!(x_testsuite, "id", id)
set_attribute!(x_testsuite, "tests", ntests)
set_attribute!(x_testsuite, "failures", nfails)
set_attribute!(x_testsuite, "errors", nerrors)
x_testsuite
end

"""
testsuite_xml(name, id, ntests, nfails, nerrors, x_children)
testsuite_xml(name, ntests, nfails, nerrors, x_children)

Create a testsuite element of a JUnit XML.
"""
function testsuite_xml(name, id, ntests, nfails, nerrors, x_children, time, timestamp)
function testsuite_xml(name, ntests, nfails, nerrors, x_children, time, timestamp, hostname)
x_testsuite = ElementNode("testsuite")
link!.(Ref(x_testsuite), x_children)
set_attribute!(x_testsuite, "name", name)
set_attribute!(x_testsuite, "id", id)
set_attribute!(x_testsuite, "tests", ntests)
set_attribute!(x_testsuite, "failures", nfails)
set_attribute!(x_testsuite, "errors", nerrors)
set_attribute!(x_testsuite, "time", time)
set_attribute!(x_testsuite, "timestamp", timestamp)
set_attribute!(x_testsuite, "hostname", hostname)
x_testsuite
end

Expand Down Expand Up @@ -144,18 +142,19 @@ function report(ts::ReportingTestSet)
total_ntests = 0
total_nfails = 0
total_nerrors = 0
testsuiteid = 0 # ID increments from 0
x_testsuites = map(ts.results) do result
x_testsuite, ntests, nfails, nerrors = to_xml(result)
total_ntests += ntests
total_nfails += nfails
total_nerrors += nerrors;
set_attribute!(x_testsuite, "id", testsuiteid)
testsuiteid += 1
x_testsuite
end

xdoc = XMLDocument()
root = setroot!(xdoc, testsuites_xml(ts.description,
"_id_",
total_ntests,
root = setroot!(xdoc, testsuites_xml(total_ntests,
total_nfails,
total_nerrors,
x_testsuites))
Expand Down Expand Up @@ -202,7 +201,7 @@ function to_xml(ts::ReportingTestSet)
x_testcase
end

x_testsuite = testsuite_xml(ts.description, "_id_", total_ntests, total_nfails, total_nerrors, x_testcases, ts.time_taken, ts.start_time)
x_testsuite = testsuite_xml(ts.description, total_ntests, total_nfails, total_nerrors, x_testcases, ts.time_taken, ts.start_time, ts.hostname)
ts isa ReportingTestSet && add_testsuite_properties!(x_testsuite, ts)
x_testsuite, total_ntests, total_nfails, total_nerrors
end
Expand Down
14 changes: 7 additions & 7 deletions test/references/complexexample.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="Example" id="_id_" tests="15" failures="6" errors="5"><testsuite name="Math/Multiplication" id="_id_" tests="3" failures="1" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/Multiplication" time="0.0"/><testcase name="1 * 2 == 5" id="_testcase_id_" classname="Math/Multiplication" time="0.0"><failure message="2 == 5" type="test">Test Failed
<testsuites tests="15" failures="6" errors="5"><testsuite name="Math/Multiplication" tests="3" failures="1" errors="0" time="0.0" timestamp="0" hostname="localhost" id="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/Multiplication" time="0.0"/><testcase name="1 * 2 == 5" id="_testcase_id_" classname="Math/Multiplication" time="0.0"><failure message="2 == 5" type="test">Test Failed
Expression: 1 * 2 == 5
Evaluated: 2 == 5</failure></testcase><testcase name="pass (info lost) (Test 3)" id="_testcase_id_" classname="Math/Multiplication" time="0.0"/></testsuite><testsuite name="Math/addition/negative addition" id="_id_" tests="3" failures="1" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"/><testcase name="1 + -2 == 1" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"><failure message="-1 == 1" type="test">Test Failed
Evaluated: 2 == 5</failure></testcase><testcase name="pass (info lost) (Test 3)" id="_testcase_id_" classname="Math/Multiplication" time="0.0"/></testsuite><testsuite name="Math/addition/negative addition" tests="3" failures="1" errors="0" time="0.0" timestamp="0" hostname="localhost" id="1"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"/><testcase name="1 + -2 == 1" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"><failure message="-1 == 1" type="test">Test Failed
Expression: 1 + -2 == 1
Evaluated: -1 == 1</failure></testcase><testcase name="pass (info lost) (Test 3)" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"/></testsuite><testsuite name="Math/addition" id="_id_" tests="3" failures="1" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/addition" time="0.0"/><testcase name="1 + 2 == 5" id="_testcase_id_" classname="Math/addition" time="0.0"><failure message="3 == 5" type="test">Test Failed
Evaluated: -1 == 1</failure></testcase><testcase name="pass (info lost) (Test 3)" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"/></testsuite><testsuite name="Math/addition" tests="3" failures="1" errors="0" time="0.0" timestamp="0" hostname="localhost" id="2"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/addition" time="0.0"/><testcase name="1 + 2 == 5" id="_testcase_id_" classname="Math/addition" time="0.0"><failure message="3 == 5" type="test">Test Failed
Expression: 1 + 2 == 5
Evaluated: 3 == 5</failure></testcase><testcase name="pass (info lost) (Test 3)" id="_testcase_id_" classname="Math/addition" time="0.0"/></testsuite><testsuite name="Math/other" id="_id_" tests="0" failures="0" errors="4" time="0.0" timestamp="0"><testcase name="sqrt(-1)" id="_testcase_id_" classname="Math/other" time="0.0"><skip/></testcase><error message="Expression evaluated to non-Boolean" type="Expression evaluated to non-Boolean" classname="Math/other" time="0.0"></error><error message="Nooo" type="ErrorException" classname="Math/other" time="0.0">Nooo
Evaluated: 3 == 5</failure></testcase><testcase name="pass (info lost) (Test 3)" id="_testcase_id_" classname="Math/addition" time="0.0"/></testsuite><testsuite name="Math/other" tests="0" failures="0" errors="4" time="0.0" timestamp="0" hostname="localhost" id="3"><testcase name="sqrt(-1)" id="_testcase_id_" classname="Math/other" time="0.0"><skip/></testcase><error message="Expression evaluated to non-Boolean" type="Expression evaluated to non-Boolean" classname="Math/other" time="0.0"></error><error message="Nooo" type="ErrorException" classname="Math/other" time="0.0">Nooo
</error><error message="DimensionMismatch(&quot;B has leading dimension 4, but needs 2&quot;)" type="DimensionMismatch" classname="Math/other" time="0.0">DimensionMismatch("B has leading dimension 4, but needs 2")
</error><error message="Got correct result, please change to @test if no longer broken." type="Unexpected Pass" classname="Math/other" time="0.0"></error></testsuite><testsuite name="Math/Error outside of tests" id="_id_" tests="0" failures="0" errors="1" time="0.0" timestamp="0"><error message="Got exception outside of a @test" type="ErrorException" classname="Math/Error outside of tests" time="0.0">Outside of tests
</error></testsuite><testsuite name="Math/Different failures" id="_id_" tests="2" failures="2" errors="0" time="0.0" timestamp="0"><testcase name="throw(ArgumentError(&quot;1&quot;))" id="_testcase_id_" classname="Math/Different failures" time="0.0"><failure message="Wrong exception type thrown" type="test_throws_wrong">Test Failed
</error><error message="Got correct result, please change to @test if no longer broken." type="Unexpected Pass" classname="Math/other" time="0.0"></error></testsuite><testsuite name="Math/Error outside of tests" tests="0" failures="0" errors="1" time="0.0" timestamp="0" hostname="localhost" id="4"><error message="Got exception outside of a @test" type="ErrorException" classname="Math/Error outside of tests" time="0.0">Outside of tests
</error></testsuite><testsuite name="Math/Different failures" tests="2" failures="2" errors="0" time="0.0" timestamp="0" hostname="localhost" id="5"><testcase name="throw(ArgumentError(&quot;1&quot;))" id="_testcase_id_" classname="Math/Different failures" time="0.0"><failure message="Wrong exception type thrown" type="test_throws_wrong">Test Failed
Expression: throw(ArgumentError("1"))
Expected: DimensionMismatch
Thrown: ArgumentError</failure></testcase><testcase name="true" id="_testcase_id_" classname="Math/Different failures" time="0.0"><failure message="No exception thrown" type="test_throws_nothing">Test Failed
Expression: true
Expected: DimensionMismatch
No exception thrown</failure></testcase></testsuite><testsuite name="Math/using function from a module" id="_id_" tests="1" failures="0" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/using function from a module" time="0.0"/></testsuite><testsuite name="Math" id="_id_" tests="3" failures="1" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math" time="0.0"/><testcase name="sqrt(20) == 5" id="_testcase_id_" classname="Math" time="0.0"><failure message="4.47213595499958 == 5" type="test">Test Failed
No exception thrown</failure></testcase></testsuite><testsuite name="Math/using function from a module" tests="1" failures="0" errors="0" time="0.0" timestamp="0" hostname="localhost" id="6"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/using function from a module" time="0.0"/></testsuite><testsuite name="Math" tests="3" failures="1" errors="0" time="0.0" timestamp="0" hostname="localhost" id="7"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math" time="0.0"/><testcase name="sqrt(20) == 5" id="_testcase_id_" classname="Math" time="0.0"><failure message="4.47213595499958 == 5" type="test">Test Failed
Expression: sqrt(20) == 5
Evaluated: 4.47213595499958 == 5</failure></testcase><testcase name="pass (info lost) (Test 3)" id="_testcase_id_" classname="Math" time="0.0"/></testsuite></testsuites>

2 changes: 1 addition & 1 deletion test/references/singlenest.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="blah" id="_id_" tests="1" failures="0" errors="0"><testsuite name="a" id="_id_" tests="1" failures="0" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="a" time="0.0"/></testsuite></testsuites>
<testsuites tests="1" failures="0" errors="0"><testsuite name="a" tests="1" failures="0" errors="0" time="0.0" timestamp="0" hostname="localhost" id="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="a" time="0.0"/></testsuite></testsuites>
2 changes: 1 addition & 1 deletion test/references/test_with_properties.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="" id="_id_" tests="9" failures="0" errors="0"><testsuite name="Math/Multiplication" id="_id_" tests="2" failures="0" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/Multiplication" time="0.0"/><testcase name="pass (info lost) (Test 2)" id="_testcase_id_" classname="Math/Multiplication" time="0.0"/><properties><property name="File" value="runtests.jl"/><property name="ID" value="1"/></properties></testsuite><testsuite name="Math/addition/negative addition" id="_id_" tests="2" failures="0" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"/><testcase name="pass (info lost) (Test 2)" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"/><properties><property name="File" value="runtests.jl"/><property name="AdditionalNest" value="true"/><property name="ID" value="2"/></properties></testsuite><testsuite name="Math/addition" id="_id_" tests="2" failures="0" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/addition" time="0.0"/><testcase name="pass (info lost) (Test 2)" id="_testcase_id_" classname="Math/addition" time="0.0"/><properties><property name="File" value="runtests.jl"/><property name="ID" value="2"/></properties></testsuite><testsuite name="Math" id="_id_" tests="2" failures="0" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math" time="0.0"/><testcase name="pass (info lost) (Test 2)" id="_testcase_id_" classname="Math" time="0.0"/><properties><property name="File" value="runtests.jl"/></properties></testsuite><testsuite name="Types" id="_id_" tests="1" failures="0" errors="0" time="0.0" timestamp="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Types" time="0.0"/><properties><property name="Float" value="0.5"/><property name="Int" value="1"/><property name="String" value="TextTests"/><property name="List" value="[&quot;1&quot;]"/><property name="Symbol" value="asymbol"/></properties></testsuite></testsuites>
<testsuites tests="9" failures="0" errors="0"><testsuite name="Math/Multiplication" tests="2" failures="0" errors="0" time="0.0" timestamp="0" hostname="localhost" id="0"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/Multiplication" time="0.0"/><testcase name="pass (info lost) (Test 2)" id="_testcase_id_" classname="Math/Multiplication" time="0.0"/><properties><property name="File" value="runtests.jl"/><property name="ID" value="1"/></properties></testsuite><testsuite name="Math/addition/negative addition" tests="2" failures="0" errors="0" time="0.0" timestamp="0" hostname="localhost" id="1"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"/><testcase name="pass (info lost) (Test 2)" id="_testcase_id_" classname="Math/addition/negative addition" time="0.0"/><properties><property name="File" value="runtests.jl"/><property name="AdditionalNest" value="true"/><property name="ID" value="2"/></properties></testsuite><testsuite name="Math/addition" tests="2" failures="0" errors="0" time="0.0" timestamp="0" hostname="localhost" id="2"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math/addition" time="0.0"/><testcase name="pass (info lost) (Test 2)" id="_testcase_id_" classname="Math/addition" time="0.0"/><properties><property name="File" value="runtests.jl"/><property name="ID" value="2"/></properties></testsuite><testsuite name="Math" tests="2" failures="0" errors="0" time="0.0" timestamp="0" hostname="localhost" id="3"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Math" time="0.0"/><testcase name="pass (info lost) (Test 2)" id="_testcase_id_" classname="Math" time="0.0"/><properties><property name="File" value="runtests.jl"/></properties></testsuite><testsuite name="Types" tests="1" failures="0" errors="0" time="0.0" timestamp="0" hostname="localhost" id="4"><testcase name="pass (info lost) (Test 1)" id="_testcase_id_" classname="Types" time="0.0"/><properties><property name="Float" value="0.5"/><property name="Int" value="1"/><property name="String" value="TextTests"/><property name="List" value="[&quot;1&quot;]"/><property name="Symbol" value="asymbol"/></properties></testsuite></testsuites>
5 changes: 4 additions & 1 deletion test/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ remove_timing_info(str) = replace(str, r"\stime=\\\"[0-9.-]*\\\"" => " time=\"0.
# Zero timestamp output - we want "timestamp" there to check its being recorded
remove_timestamp_info(str) = replace(str, r"\stimestamp=\\\"[0-9-T:.]*\\\"" => " timestamp=\"0\"")

const clean_output = strip_filepaths ∘ remove_stacktraces ∘ remove_test_output ∘ remove_timing_info ∘ remove_timestamp_info
# Default hostname output - we want "hostname" there to check its being recorded
default_hostname_info(str) = replace(str, r"\shostname=\\\"[\S]*\\\"" => " hostname=\"localhost\"")

const clean_output = strip_filepaths ∘ remove_stacktraces ∘ remove_test_output ∘ remove_timing_info ∘ remove_timestamp_info ∘ default_hostname_info

"""
`copy_test_package` copied from [`Pkg.jl/test/utils.jl`](https://github.com/JuliaLang/Pkg.jl/blob/v1.4.2/test/utils.jl#L209).
Expand Down