1
# subunit: extensions to python unittest to get test results from subprocesses.
2
# Copyright (C) 2009 Robert Collins <robertc@robertcollins.net>
4
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
5
# license at the users choice. A copy of both licenses are available in the
6
# project source as Apache-2.0 and BSD. You may not use this file except in
7
# compliance with one of these two licences.
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
11
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
# license you chose for the specific language governing permissions and
13
# limitations under that license.
17
from optparse import OptionParser
20
from subunit import DiscardStream, ProtocolTestCase
23
def make_options(description):
24
parser = OptionParser(description=description)
26
"--no-passthrough", action="store_true",
27
help="Hide all non subunit input.", default=False,
28
dest="no_passthrough")
31
help="Send the output to this path rather than stdout.")
33
"-f", "--forward", action="store_true", default=False,
34
help="Forward subunit stream on stdout.")
38
def run_tests_from_stream(input_stream, result, passthrough_stream=None,
40
"""Run tests from a subunit input stream through 'result'.
42
:param input_stream: A stream containing subunit input.
43
:param result: A TestResult that will receive the test events.
44
:param passthrough_stream: All non-subunit input received will be
45
sent to this stream. If not provided, uses the ``TestProtocolServer``
46
default, which is ``sys.stdout``.
47
:param forward_stream: All subunit input received will be forwarded
48
to this stream. If not provided, uses the ``TestProtocolServer``
49
default, which is to not forward any input.
51
test = ProtocolTestCase(
52
input_stream, passthrough=passthrough_stream,
53
forward=forward_stream)
59
def filter_by_result(result_factory, output_path, passthrough, forward,
60
input_stream=sys.stdin):
61
"""Filter an input stream using a test result.
63
:param result_factory: A callable that when passed an output stream
64
returns a TestResult. It is expected that this result will output
66
:param output_path: A path send output to. If None, output will be go
68
:param passthrough: If True, all non-subunit input will be sent to
69
``sys.stdout``. If False, that input will be discarded.
70
:param forward: If True, all subunit input will be forwarded directly to
71
``sys.stdout`` as well as to the ``TestResult``.
72
:param input_stream: The source of subunit input. Defaults to
74
:return: A test result with the resultts of the run.
77
passthrough_stream = sys.stdout
79
passthrough_stream = DiscardStream()
82
forward_stream = sys.stdout
84
forward_stream = DiscardStream()
86
if output_path is None:
87
output_to = sys.stdout
89
output_to = file(output_path, 'wb')
92
result = result_factory(output_to)
93
run_tests_from_stream(
94
input_stream, result, passthrough_stream, forward_stream)
101
def run_filter_script(result_factory, description, post_run_hook=None):
102
"""Main function for simple subunit filter scripts.
104
Many subunit filter scripts take a stream of subunit input and use a
105
TestResult to handle the events generated by that stream. This function
106
wraps a lot of the boiler-plate around that by making a script with
107
options for handling passthrough information and stream forwarding, and
108
that will exit with a successful return code (i.e. 0) if the input stream
109
represents a successful test run.
111
:param result_factory: A callable that takes an output stream and returns
112
a test result that outputs to that stream.
113
:param description: A description of the filter script.
115
parser = make_options(description)
116
(options, args) = parser.parse_args()
117
result = filter_by_result(
118
result_factory, options.output_to, not options.no_passthrough,
121
post_run_hook(result)
122
if result.wasSuccessful():