Skip to content

Commit cf418ba

Browse files
authored
Merge pull request #11 from kenichiice/capture-stdout
<system-out>, <system-err>をサポートする
2 parents ffe0fcd + 0cc6774 commit cf418ba

File tree

8 files changed

+312
-26
lines changed

8 files changed

+312
-26
lines changed

README.ja.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ require "test/unit/runner/junitxml"
2222

2323
class MyTest < Test::Unit::TestCase
2424
def test_1
25+
print("hello")
2526
assert_equal(1, 2)
2627
end
2728
end
@@ -32,20 +33,28 @@ $ ruby test.rb --runner=junitxml --junitxml-output-file=result.xml
3233
$ cat result.xml
3334
<?xml version="1.0" encoding="UTF-8" ?>
3435
<testsuites>
35-
<testsuite name="MyTest" tests="1" errors="0" failures="1" skipped="0" time="0.0027089">
36-
<testcase classname="MyTest" name="test_1(MyTest)" time="0.0026767" assertions="1">
36+
<testsuite name="MyTest" tests="1" errors="0" failures="1" skipped="0" time="0.0047083">
37+
<testcase classname="MyTest" name="test_1(MyTest)" time="0.0046712" assertions="1">
3738
<failure message="&lt;1&gt; expected but was
3839
&lt;2&gt;.">
3940
Failure:
40-
test_1(MyTest) [test.rb:6]:
41+
test_1(MyTest) [test.rb:7]:
4142
&lt;1&gt; expected but was
4243
&lt;2&gt;.
4344
</failure>
45+
<system-out>hello</system-out>
4446
</testcase>
4547
</testsuite>
4648
</testsuites>
4749
```
4850

51+
## オプション
52+
53+
* --junitxml-output-file=FILE_NAME
54+
* XMLを、標準出力ではなく指定したファイルへ出力します。
55+
* --junitxml-disable-output-capture
56+
* 標準出力と標準エラー出力のキャプチャを行わないようになります。
57+
4958
## ライセンス
5059

5160
[MIT License](https://opensource.org/licenses/MIT)

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ require "test/unit/runner/junitxml"
2222

2323
class MyTest < Test::Unit::TestCase
2424
def test_1
25+
print("hello")
2526
assert_equal(1, 2)
2627
end
2728
end
@@ -32,20 +33,28 @@ $ ruby test.rb --runner=junitxml --junitxml-output-file=result.xml
3233
$ cat result.xml
3334
<?xml version="1.0" encoding="UTF-8" ?>
3435
<testsuites>
35-
<testsuite name="MyTest" tests="1" errors="0" failures="1" skipped="0" time="0.0027089">
36-
<testcase classname="MyTest" name="test_1(MyTest)" time="0.0026767" assertions="1">
36+
<testsuite name="MyTest" tests="1" errors="0" failures="1" skipped="0" time="0.0047083">
37+
<testcase classname="MyTest" name="test_1(MyTest)" time="0.0046712" assertions="1">
3738
<failure message="&lt;1&gt; expected but was
3839
&lt;2&gt;.">
3940
Failure:
40-
test_1(MyTest) [test.rb:6]:
41+
test_1(MyTest) [test.rb:7]:
4142
&lt;1&gt; expected but was
4243
&lt;2&gt;.
4344
</failure>
45+
<system-out>hello</system-out>
4446
</testcase>
4547
</testsuite>
4648
</testsuites>
4749
```
4850

51+
## Options
52+
53+
* --junitxml-output-file=FILE_NAME
54+
* Output XML to the specified file instead of the standard output.
55+
* --junitxml-disable-output-capture
56+
* Disable capture of standard output and standard error.
57+
4958
## License
5059

5160
[MIT License](https://opensource.org/licenses/MIT)

lib/test/unit/runner/junitxml.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ module Unit
1212
"Outputs to FILE_NAME") do |name|
1313
auto_runner.runner_options[:junitxml_output_file] = name
1414
end
15+
opts.on("--junitxml-disable-output-capture",
16+
"Disable output capture") do |b|
17+
auto_runner.runner_options[:junitxml_disable_output_capture] = b
18+
end
1519
end
1620
end
1721
end

lib/test/unit/ui/junitxml/testrunner.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'erb'
2+
require 'stringio'
23
require 'test/unit/ui/testrunner'
34
require 'test/unit/ui/testrunnermediator'
45

@@ -48,12 +49,22 @@ def test_suite_finished(suite)
4849
end
4950

5051
def test_started(test)
51-
@junit_test_suites.last << JUnitTestCase.new(test.class.name,
52-
test.description)
52+
test_case = JUnitTestCase.new(test.class.name, test.description)
53+
@junit_test_suites.last << test_case
54+
unless @options[:junitxml_disable_output_capture]
55+
@stdout_org = $stdout
56+
@stderr_org = $stderr
57+
$stdout = test_case.stdout
58+
$stderr = test_case.stderr
59+
end
5360
end
5461

5562
def test_finished(test)
5663
@junit_test_suites.last.test_cases.last.time = test.elapsed_time
64+
unless @options[:junitxml_disable_output_capture]
65+
$stdout = @stdout_org
66+
$stderr = @stderr_org
67+
end
5768
end
5869

5970
def result_pass_assertion(result)
@@ -116,15 +127,16 @@ def errors
116127
class JUnitTestCase
117128
attr_reader :class_name, :name
118129
attr_reader :failure, :error, :omission, :pending
130+
attr_reader :stdout, :stderr
119131
attr_accessor :assertion_count, :time
120132

121133
def initialize(class_name, name)
122134
@class_name = class_name
123135
@name = name
136+
@stdout = StringIO.new
137+
@stderr = StringIO.new
124138
@assertion_count = 0
125139
@time = 0
126-
@omission = nil
127-
@pending = nil
128140
end
129141

130142
def <<(fault)

lib/test/unit/ui/junitxml/xml.erb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@
1616
<skipped message="<%=h test_case.omission.message %>"/>
1717
% elsif test_case.pending
1818
<skipped message="<%=h test_case.pending.message %>"/>
19+
% end
20+
% if test_case.stdout.size > 0
21+
<system-out><%=h test_case.stdout.string %></system-out>
22+
% end
23+
% if test_case.stderr.size > 0
24+
<system-err><%=h test_case.stderr.string %></system-err>
1925
% end
2026
</testcase>
2127
% end

test/check.rb

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,16 @@ def check_testsuite(testsuite, name, tests, errors, failures, skipped)
1111
assert_compare(0, "<", Float(testsuite.attribute("time").value))
1212
end
1313

14-
def check_testcase_success(testcase, class_name, assertions)
15-
assert_equal(class_name, testcase.attribute("classname").value)
16-
assert_equal(assertions.to_s, testcase.attribute("assertions").value)
17-
assert_compare(0, "<", Float(testcase.attribute("time").value))
14+
def check_testcase_success(testcase, class_name, assertions, out = nil, err = nil)
15+
check_test_case(testcase, class_name, assertions, out, err)
1816

1917
assert_equal(0, testcase.get_elements("failure").size)
2018
assert_equal(0, testcase.get_elements("error").size)
2119
assert_equal(0, testcase.get_elements("skipped").size)
2220
end
2321

24-
def check_testcase_failure(testcase, class_name, assertions, message = nil)
25-
assert_equal(class_name, testcase.attribute("classname").value)
26-
assert_equal(assertions.to_s, testcase.attribute("assertions").value)
27-
assert_compare(0, "<", Float(testcase.attribute("time").value))
22+
def check_testcase_failure(testcase, class_name, assertions, message = nil, out = nil, err = nil)
23+
check_test_case(testcase, class_name, assertions, out, err)
2824

2925
failures = testcase.get_elements("failure")
3026
assert_equal(1, failures.size)
@@ -38,10 +34,8 @@ def check_testcase_failure(testcase, class_name, assertions, message = nil)
3834
assert_equal(0, testcase.get_elements("skipped").size)
3935
end
4036

41-
def check_testcase_error(testcase, class_name, assertions, message = nil)
42-
assert_equal(class_name, testcase.attribute("classname").value)
43-
assert_equal(assertions.to_s, testcase.attribute("assertions").value)
44-
assert_compare(0, "<", Float(testcase.attribute("time").value))
37+
def check_testcase_error(testcase, class_name, assertions, message = nil, out = nil, err = nil)
38+
check_test_case(testcase, class_name, assertions, out, err)
4539

4640
errors = testcase.get_elements("error")
4741
assert_equal(1, errors.size)
@@ -56,10 +50,8 @@ def check_testcase_error(testcase, class_name, assertions, message = nil)
5650
assert_equal(0, testcase.get_elements("skipped").size)
5751
end
5852

59-
def check_testcase_skipped(testcase, class_name, assertions, message = nil)
60-
assert_equal(class_name, testcase.attribute("classname").value)
61-
assert_equal(assertions.to_s, testcase.attribute("assertions").value)
62-
assert_compare(0, "<", Float(testcase.attribute("time").value))
53+
def check_testcase_skipped(testcase, class_name, assertions, message = nil, out = nil, err = nil)
54+
check_test_case(testcase, class_name, assertions, out, err)
6355

6456
skipped = testcase.get_elements("skipped")
6557
assert_equal(1, skipped.size)
@@ -68,4 +60,26 @@ def check_testcase_skipped(testcase, class_name, assertions, message = nil)
6860
assert_equal(0, testcase.get_elements("failure").size)
6961
assert_equal(0, testcase.get_elements("error").size)
7062
end
63+
64+
def check_test_case(testcase, class_name, assertions, out = nil, err = nil)
65+
assert_equal(class_name, testcase.attribute("classname").value)
66+
assert_equal(assertions.to_s, testcase.attribute("assertions").value)
67+
assert_compare(0, "<", Float(testcase.attribute("time").value))
68+
69+
system_outs = testcase.get_elements("system-out")
70+
if out
71+
assert_equal(1, system_outs.size)
72+
assert_match(out, system_outs.first.text)
73+
else
74+
assert_equal(0, system_outs.size)
75+
end
76+
77+
system_errs = testcase.get_elements("system-err")
78+
if err
79+
assert_equal(1, system_errs.size)
80+
assert_match(err, system_errs.first.text)
81+
else
82+
assert_equal(0, system_errs.size)
83+
end
84+
end
7185
end
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
require "stringio"
2+
require 'rexml/document'
3+
require "test/unit"
4+
require "test/unit/ui/junitxml/testrunner"
5+
require_relative "check"
6+
7+
class TestXmlWithOutput < Test::Unit::TestCase
8+
include Check
9+
10+
setup do
11+
test_case = Class.new(Test::Unit::TestCase) do
12+
include Test::Unit::Util::Output
13+
14+
test "success" do
15+
assert_equal(1, 1)
16+
puts("out 1")
17+
end
18+
19+
def test_failure
20+
assert_equal(1, 1)
21+
warn("warn 1")
22+
assert_equal(1, 2)
23+
end
24+
25+
def test_error
26+
warn("warn 2")
27+
puts("out 2")
28+
assert_equal(1, 1)
29+
assert_equal(1, 1)
30+
assert_equal(1, 1)
31+
raise "hello"
32+
end
33+
34+
def test_omission
35+
puts("out 3")
36+
omit("omission 1")
37+
end
38+
39+
def test_pending
40+
warn("warn 3")
41+
pend("pending 1")
42+
end
43+
44+
def test_with_capture_output
45+
out, err = capture_output do
46+
puts("out 4")
47+
warn("warn 4")
48+
end
49+
assert_equal("out 4\n", out)
50+
assert_equal("warn 4\n", err)
51+
end
52+
end
53+
54+
output = StringIO.new
55+
runner = Test::Unit::UI::JUnitXml::TestRunner.new(
56+
test_case.suite, :output => output)
57+
runner.start
58+
59+
output.rewind
60+
@doc = REXML::Document.new(output)
61+
end
62+
63+
test "testsuites" do
64+
testsuites_array = @doc.get_elements("/testsuites")
65+
assert_equal(1, testsuites_array.size)
66+
end
67+
68+
test "testsuite" do
69+
testsuite_array = @doc.get_elements("/testsuites/testsuite")
70+
assert_equal(1, testsuite_array.size)
71+
check_testsuite(testsuite_array.first, "", 6, 1, 1, 2)
72+
end
73+
74+
test "testcase success" do
75+
testcase_array = @doc.get_elements(
76+
"/testsuites/testsuite/testcase[@name='success']")
77+
assert_equal(1, testcase_array.size)
78+
check_testcase_success(testcase_array.first, "", 1, "out 1")
79+
end
80+
81+
test "testcase failure" do
82+
testcase_array = @doc.get_elements(
83+
"/testsuites/testsuite/testcase[@name='test_failure()']")
84+
assert_equal(1, testcase_array.size)
85+
check_testcase_failure(testcase_array.first, "", 2, /.+/, nil, "warn 1")
86+
end
87+
88+
test "testcase error" do
89+
testcase_array = @doc.get_elements(
90+
"/testsuites/testsuite/testcase[@name='test_error()']")
91+
assert_equal(1, testcase_array.size)
92+
check_testcase_error(testcase_array.first, "", 3, "hello", "out 2", "warn 2")
93+
end
94+
95+
test "testcase omission" do
96+
testcase_array = @doc.get_elements(
97+
"/testsuites/testsuite/testcase[@name='test_omission()']")
98+
assert_equal(1, testcase_array.size)
99+
check_testcase_skipped(testcase_array.first, "", 0, "omission 1", "out 3")
100+
end
101+
102+
test "testcase pending" do
103+
testcase_array = @doc.get_elements(
104+
"/testsuites/testsuite/testcase[@name='test_pending()']")
105+
assert_equal(1, testcase_array.size)
106+
check_testcase_skipped(testcase_array.first, "", 0, "pending 1", nil, "warn 3")
107+
end
108+
109+
test "testcase test_with_capture_output" do
110+
testcase_array = @doc.get_elements(
111+
"/testsuites/testsuite/testcase[@name='test_with_capture_output()']")
112+
assert_equal(1, testcase_array.size)
113+
check_testcase_success(testcase_array.first, "", 2)
114+
end
115+
end

0 commit comments

Comments
 (0)