Files
deb-subunit/filters/subunit-filter
2009-09-30 22:04:18 +10:00

110 lines
4.1 KiB
Python
Executable File

#!/usr/bin/env python
# subunit: extensions to python unittest to get test results from subprocesses.
# Copyright (C) 2008 Robert Collins <robertc@robertcollins.net>
# (C) 2009 Martin Pool
#
# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
# license at the users choice. A copy of both licenses are available in the
# project source as Apache-2.0 and BSD. You may not use this file except in
# compliance with one of these two licences.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# license you chose for the specific language governing permissions and
# limitations under that license.
#
"""Filter a subunit stream to include/exclude tests.
The default is to strip successful tests.
Tests can be filtered by Python regular expressions with --with and --without,
which match both the test name and the error text (if any). The result
contains tests which match any of the --with expressions and none of the
--without expressions. For case-insensitive matching prepend '(?i)'.
Remember to quote shell metacharacters.
"""
from optparse import OptionParser
import sys
import unittest
import re
from subunit import (
DiscardStream,
ProtocolTestCase,
TestProtocolClient,
TestResultFilter,
)
parser = OptionParser(description=__doc__)
parser.add_option("--error", action="store_false",
help="include errors", default=False, dest="error")
parser.add_option("-e", "--no-error", action="store_true",
help="exclude errors", dest="error")
parser.add_option("--failure", action="store_false",
help="include failures", default=False, dest="failure")
parser.add_option("-f", "--no-failure", action="store_true",
help="include failures", dest="failure")
parser.add_option("--no-passthrough", action="store_true",
help="Hide all non subunit input.", default=False, dest="no_passthrough")
parser.add_option("-s", "--success", action="store_false",
help="include successes", dest="success")
parser.add_option("--no-skip", action="store_true",
help="exclude skips", dest="skip")
parser.add_option("--no-success", action="store_true",
help="exclude successes", default=True, dest="success")
parser.add_option("-m", "--with", type=str,
help="regexp to include (case-sensitive by default)",
action="append", dest="with_regexps")
parser.add_option("--without", type=str,
help="regexp to exclude (case-sensitive by default)",
action="append", dest="without_regexps")
(options, args) = parser.parse_args()
def _compile_re_from_list(l):
return re.compile("|".join(l), re.MULTILINE)
def _make_regexp_filter(with_regexps, without_regexps):
"""Make a callback that checks tests against regexps.
with_regexps and without_regexps are each either a list of regexp strings,
or None.
"""
with_re = with_regexps and _compile_re_from_list(with_regexps)
without_re = without_regexps and _compile_re_from_list(without_regexps)
def check_regexps(test, err):
"""Check if this test and error match the regexp filters."""
test_str = str(test)
err_str = err and str(err) # may be None
if with_re:
if not (with_re.search(test_str)
or with_re.search(err_str)):
return False
if without_re:
if (without_re.search(test_str) or without_re.search(err_str)):
return False
return True
return check_regexps
regexp_filter = _make_regexp_filter(options.with_regexps,
options.without_regexps)
result = TestProtocolClient(sys.stdout)
result = TestResultFilter(result, filter_error=options.error,
filter_failure=options.failure, filter_success=options.success,
filter_skip=options.skip,
filter_predicate=regexp_filter)
if options.no_passthrough:
passthrough_stream = DiscardStream()
else:
passthrough_stream = None
test = ProtocolTestCase(sys.stdin, passthrough=passthrough_stream)
test.run(result)
sys.exit(0)