3 new commits in pytest:
https://bitbucket.org/hpk42/pytest/commits/6fa216bce897/
Changeset: 6fa216bce897
Branch: issue504
User: rouge8
Date: 2014-04-14 23:42:02
Summary: issue504: verbose output displays node IDs for each test
Replace the verbose per-test reporting format of `file:line test_name RESULT`
with the node ID of the test, i.e. `file@line::class::method[param] RESULT`.
This patch does not update the examples in the docs; @hpk42 has a script
to regenerate those.
Affected #: 8 files
diff -r a00590d97593d00163772511aca3149f7ef0bae2 -r
6fa216bce897473c4abc86e18aaf502e65d39130 AUTHORS
--- a/AUTHORS
+++ b/AUTHORS
@@ -41,3 +41,4 @@
Marc Schlaich
Christopher Gilling
Daniel Grana
+Andy Freeland
diff -r a00590d97593d00163772511aca3149f7ef0bae2 -r
6fa216bce897473c4abc86e18aaf502e65d39130 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,10 @@
NEXT (2.6)
-----------------------------------
+- change -v output to include full node IDs of tests. Users can copy
+ a node ID from a test run, including line number, and use it as a
+ positional argument in order to run only a single test.
+
- change XPASS colour to yellow rather then red when tests are run
with -v.
diff -r a00590d97593d00163772511aca3149f7ef0bae2 -r
6fa216bce897473c4abc86e18aaf502e65d39130 _pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -2,6 +2,7 @@
import py
# DON't import pytest here because it causes import cycle troubles
+import re
import sys, os
from _pytest import hookspec # the extension point definitions
from _pytest.core import PluginManager
@@ -180,7 +181,7 @@
a = option.attrs()
arggroup.add_argument(*n, **a)
# bash like autocompletion for dirs (appending '/')
- optparser.add_argument(FILE_OR_DIR, nargs='*'
+ optparser.add_argument(FILE_OR_DIR, nargs='*',
type=node_with_line_number,
).completer=filescompleter
return optparser
@@ -699,7 +700,7 @@
except ConftestImportFailure:
e = sys.exc_info()[1]
if ns.help or ns.version:
- # we don't want to prevent --help/--version to work
+ # we don't want to prevent --help/--version to work
# so just let is pass and print a warning at the end
self.pluginmanager._warnings.append(
"could not load initial conftests (%s)\n" % e.path)
@@ -839,6 +840,12 @@
return {}
+def node_with_line_number(string):
+ split = string.split('[')
+ split[0] = re.sub(r'@\d+', '', split[0])
+ return '['.join(split)
+
+
def setns(obj, dic):
import pytest
for name, value in dic.items():
diff -r a00590d97593d00163772511aca3149f7ef0bae2 -r
6fa216bce897473c4abc86e18aaf502e65d39130 _pytest/terminal.py
--- a/_pytest/terminal.py
+++ b/_pytest/terminal.py
@@ -382,9 +382,11 @@
line = str(fspath)
if lineno is not None:
lineno += 1
- line += ":" + str(lineno)
+ line += "@" + str(lineno)
if domain:
- line += ": " + str(domain)
+ split = str(domain).split('[')
+ split[0] = split[0].replace('.', '::') # don't replace '.' in
params
+ line += "::" + '['.join(split)
else:
line = "[location]"
return line + " "
diff -r a00590d97593d00163772511aca3149f7ef0bae2 -r
6fa216bce897473c4abc86e18aaf502e65d39130 testing/python/fixture.py
--- a/testing/python/fixture.py
+++ b/testing/python/fixture.py
@@ -1620,22 +1620,22 @@
""")
result = testdir.runpytest("-v")
result.stdout.fnmatch_lines("""
- test_mod1.py:1: test_func[s1] PASSED
- test_mod2.py:1: test_func2[s1] PASSED
- test_mod2.py:3: test_func3[s1-m1] PASSED
- test_mod2.py:5: test_func3b[s1-m1] PASSED
- test_mod2.py:3: test_func3[s1-m2] PASSED
- test_mod2.py:5: test_func3b[s1-m2] PASSED
- test_mod1.py:1: test_func[s2] PASSED
- test_mod2.py:1: test_func2[s2] PASSED
- test_mod2.py:3: test_func3[s2-m1] PASSED
- test_mod2.py:5: test_func3b[s2-m1] PASSED
- test_mod2.py:7: test_func4[m1] PASSED
- test_mod2.py:3: test_func3[s2-m2] PASSED
- test_mod2.py:5: test_func3b[s2-m2] PASSED
- test_mod2.py:7: test_func4[m2] PASSED
- test_mod1.py:3: test_func1[m1] PASSED
- test_mod1.py:3: test_func1[m2] PASSED
+ test_mod1.py@1::test_func[s1] PASSED
+ test_mod2.py@1::test_func2[s1] PASSED
+ test_mod2.py@3::test_func3[s1-m1] PASSED
+ test_mod2.py@5::test_func3b[s1-m1] PASSED
+ test_mod2.py@3::test_func3[s1-m2] PASSED
+ test_mod2.py@5::test_func3b[s1-m2] PASSED
+ test_mod1.py@1::test_func[s2] PASSED
+ test_mod2.py@1::test_func2[s2] PASSED
+ test_mod2.py@3::test_func3[s2-m1] PASSED
+ test_mod2.py@5::test_func3b[s2-m1] PASSED
+ test_mod2.py@7::test_func4[m1] PASSED
+ test_mod2.py@3::test_func3[s2-m2] PASSED
+ test_mod2.py@5::test_func3b[s2-m2] PASSED
+ test_mod2.py@7::test_func4[m2] PASSED
+ test_mod1.py@3::test_func1[m1] PASSED
+ test_mod1.py@3::test_func1[m2] PASSED
""")
def test_class_ordering(self, testdir):
@@ -1672,18 +1672,18 @@
""")
result = testdir.runpytest("-vs")
result.stdout.fnmatch_lines("""
- test_class_ordering.py:4: TestClass2.test_1[1-a] PASSED
- test_class_ordering.py:4: TestClass2.test_1[2-a] PASSED
- test_class_ordering.py:6: TestClass2.test_2[1-a] PASSED
- test_class_ordering.py:6: TestClass2.test_2[2-a] PASSED
- test_class_ordering.py:4: TestClass2.test_1[1-b] PASSED
- test_class_ordering.py:4: TestClass2.test_1[2-b] PASSED
- test_class_ordering.py:6: TestClass2.test_2[1-b] PASSED
- test_class_ordering.py:6: TestClass2.test_2[2-b] PASSED
- test_class_ordering.py:9: TestClass.test_3[1-a] PASSED
- test_class_ordering.py:9: TestClass.test_3[2-a] PASSED
- test_class_ordering.py:9: TestClass.test_3[1-b] PASSED
- test_class_ordering.py:9: TestClass.test_3[2-b] PASSED
+ test_class_ordering.py@4::TestClass2::test_1[1-a] PASSED
+ test_class_ordering.py@4::TestClass2::test_1[2-a] PASSED
+ test_class_ordering.py@6::TestClass2::test_2[1-a] PASSED
+ test_class_ordering.py@6::TestClass2::test_2[2-a] PASSED
+ test_class_ordering.py@4::TestClass2::test_1[1-b] PASSED
+ test_class_ordering.py@4::TestClass2::test_1[2-b] PASSED
+ test_class_ordering.py@6::TestClass2::test_2[1-b] PASSED
+ test_class_ordering.py@6::TestClass2::test_2[2-b] PASSED
+ test_class_ordering.py@9::TestClass::test_3[1-a] PASSED
+ test_class_ordering.py@9::TestClass::test_3[2-a] PASSED
+ test_class_ordering.py@9::TestClass::test_3[1-b] PASSED
+ test_class_ordering.py@9::TestClass::test_3[2-b] PASSED
""")
def test_parametrize_separated_order_higher_scope_first(self, testdir):
@@ -2094,7 +2094,7 @@
def fix1(request):
def f():
raise KeyError
- request.addfinalizer(f)
+ request.addfinalizer(f)
return object()
l = []
@@ -2113,7 +2113,7 @@
*KeyError*
*3 pass*2 error*
""")
-
+
def test_setupfunc_missing_funcarg(self, testdir):
diff -r a00590d97593d00163772511aca3149f7ef0bae2 -r
6fa216bce897473c4abc86e18aaf502e65d39130 testing/test_parseopt.py
--- a/testing/test_parseopt.py
+++ b/testing/test_parseopt.py
@@ -145,6 +145,10 @@
assert args.R == True
assert args.S == False
+ def test_parse_removes_line_number_from_positional_arguments(self, parser):
+ args = parser.parse(['path@2::func', 'path2@5::func2[param with @]'])
+ assert getattr(args, parseopt.FILE_OR_DIR) == ['path::func',
'path2::func2[param with @]']
+
def test_parse_defaultgetter(self):
def defaultget(option):
if not hasattr(option, 'type'):
diff -r a00590d97593d00163772511aca3149f7ef0bae2 -r
6fa216bce897473c4abc86e18aaf502e65d39130 testing/test_terminal.py
--- a/testing/test_terminal.py
+++ b/testing/test_terminal.py
@@ -51,9 +51,9 @@
result = testdir.runpytest(*option.args)
if option.verbose:
result.stdout.fnmatch_lines([
- "*test_pass_skip_fail.py:2: *test_ok*PASS*",
- "*test_pass_skip_fail.py:4: *test_skip*SKIP*",
- "*test_pass_skip_fail.py:6: *test_func*FAIL*",
+ "*test_pass_skip_fail.py@2::test_ok PASS*",
+ "*test_pass_skip_fail.py@4::test_skip SKIP*",
+ "*test_pass_skip_fail.py@6::test_func FAIL*",
])
else:
result.stdout.fnmatch_lines([
@@ -126,7 +126,7 @@
])
result = testdir.runpytest("-v", p2)
result.stdout.fnmatch_lines([
- "*test_p2.py <- *test_p1.py:2: TestMore.test_p1*",
+ "*test_p2.py <- *test_p1.py@2::TestMore::test_p1*",
])
def test_itemreport_directclasses_not_shown_as_subclasses(self, testdir):
@@ -450,17 +450,17 @@
""")
result = testdir.runpytest(p1, '-v')
result.stdout.fnmatch_lines([
- "*test_verbose_reporting.py:2: test_fail*FAIL*",
- "*test_verbose_reporting.py:4: test_pass*PASS*",
- "*test_verbose_reporting.py:7: TestClass.test_skip*SKIP*",
- "*test_verbose_reporting.py:10: test_gen*FAIL*",
+ "*test_verbose_reporting.py@2::test_fail *FAIL*",
+ "*test_verbose_reporting.py@4::test_pass *PASS*",
+ "*test_verbose_reporting.py@7::TestClass::test_skip *SKIP*",
+ "*test_verbose_reporting.py@10::test_gen*0* *FAIL*",
])
assert result.ret == 1
pytestconfig.pluginmanager.skipifmissing("xdist")
result = testdir.runpytest(p1, '-v', '-n 1')
result.stdout.fnmatch_lines([
- "*FAIL*test_verbose_reporting.py:2: test_fail*",
+ "*FAIL*test_verbose_reporting.py@2::test_fail*",
])
assert result.ret == 1
diff -r a00590d97593d00163772511aca3149f7ef0bae2 -r
6fa216bce897473c4abc86e18aaf502e65d39130 testing/test_unittest.py
--- a/testing/test_unittest.py
+++ b/testing/test_unittest.py
@@ -29,8 +29,8 @@
""")
result = testdir.runpytest("-v")
result.stdout.fnmatch_lines("""
- *MyTestCaseWithRunTest.runTest*
- *MyTestCaseWithoutRunTest.test_something*
+ *MyTestCaseWithRunTest::runTest*
+ *MyTestCaseWithoutRunTest::test_something*
*2 passed*
""")
https://bitbucket.org/hpk42/pytest/commits/229f3213f7a6/
Changeset: 229f3213f7a6
User: flub
Date: 2014-04-15 17:43:38
Summary: Merge pull request #158, fixes issue 504
Affected #: 8 files
diff -r 9572842277fa4cf0e9cac75684b4fb02c3927f4d -r
229f3213f7a629f547e6b89a20263a41611807a1 AUTHORS
--- a/AUTHORS
+++ b/AUTHORS
@@ -41,3 +41,4 @@
Marc Schlaich
Christopher Gilling
Daniel Grana
+Andy Freeland
diff -r 9572842277fa4cf0e9cac75684b4fb02c3927f4d -r
229f3213f7a629f547e6b89a20263a41611807a1 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,10 @@
NEXT (2.6)
-----------------------------------
+- change -v output to include full node IDs of tests. Users can copy
+ a node ID from a test run, including line number, and use it as a
+ positional argument in order to run only a single test.
+
- fix issue 475: fail early and comprehensible if calling
pytest.raises with wrong exception type.
diff -r 9572842277fa4cf0e9cac75684b4fb02c3927f4d -r
229f3213f7a629f547e6b89a20263a41611807a1 _pytest/config.py
--- a/_pytest/config.py
+++ b/_pytest/config.py
@@ -2,6 +2,7 @@
import py
# DON't import pytest here because it causes import cycle troubles
+import re
import sys, os
from _pytest import hookspec # the extension point definitions
from _pytest.core import PluginManager
@@ -180,7 +181,7 @@
a = option.attrs()
arggroup.add_argument(*n, **a)
# bash like autocompletion for dirs (appending '/')
- optparser.add_argument(FILE_OR_DIR, nargs='*'
+ optparser.add_argument(FILE_OR_DIR, nargs='*',
type=node_with_line_number,
).completer=filescompleter
return optparser
@@ -699,7 +700,7 @@
except ConftestImportFailure:
e = sys.exc_info()[1]
if ns.help or ns.version:
- # we don't want to prevent --help/--version to work
+ # we don't want to prevent --help/--version to work
# so just let is pass and print a warning at the end
self.pluginmanager._warnings.append(
"could not load initial conftests (%s)\n" % e.path)
@@ -839,6 +840,12 @@
return {}
+def node_with_line_number(string):
+ split = string.split('[')
+ split[0] = re.sub(r'@\d+', '', split[0])
+ return '['.join(split)
+
+
def setns(obj, dic):
import pytest
for name, value in dic.items():
diff -r 9572842277fa4cf0e9cac75684b4fb02c3927f4d -r
229f3213f7a629f547e6b89a20263a41611807a1 _pytest/terminal.py
--- a/_pytest/terminal.py
+++ b/_pytest/terminal.py
@@ -382,9 +382,11 @@
line = str(fspath)
if lineno is not None:
lineno += 1
- line += ":" + str(lineno)
+ line += "@" + str(lineno)
if domain:
- line += ": " + str(domain)
+ split = str(domain).split('[')
+ split[0] = split[0].replace('.', '::') # don't replace '.' in
params
+ line += "::" + '['.join(split)
else:
line = "[location]"
return line + " "
diff -r 9572842277fa4cf0e9cac75684b4fb02c3927f4d -r
229f3213f7a629f547e6b89a20263a41611807a1 testing/python/fixture.py
--- a/testing/python/fixture.py
+++ b/testing/python/fixture.py
@@ -1620,22 +1620,22 @@
""")
result = testdir.runpytest("-v")
result.stdout.fnmatch_lines("""
- test_mod1.py:1: test_func[s1] PASSED
- test_mod2.py:1: test_func2[s1] PASSED
- test_mod2.py:3: test_func3[s1-m1] PASSED
- test_mod2.py:5: test_func3b[s1-m1] PASSED
- test_mod2.py:3: test_func3[s1-m2] PASSED
- test_mod2.py:5: test_func3b[s1-m2] PASSED
- test_mod1.py:1: test_func[s2] PASSED
- test_mod2.py:1: test_func2[s2] PASSED
- test_mod2.py:3: test_func3[s2-m1] PASSED
- test_mod2.py:5: test_func3b[s2-m1] PASSED
- test_mod2.py:7: test_func4[m1] PASSED
- test_mod2.py:3: test_func3[s2-m2] PASSED
- test_mod2.py:5: test_func3b[s2-m2] PASSED
- test_mod2.py:7: test_func4[m2] PASSED
- test_mod1.py:3: test_func1[m1] PASSED
- test_mod1.py:3: test_func1[m2] PASSED
+ test_mod1.py@1::test_func[s1] PASSED
+ test_mod2.py@1::test_func2[s1] PASSED
+ test_mod2.py@3::test_func3[s1-m1] PASSED
+ test_mod2.py@5::test_func3b[s1-m1] PASSED
+ test_mod2.py@3::test_func3[s1-m2] PASSED
+ test_mod2.py@5::test_func3b[s1-m2] PASSED
+ test_mod1.py@1::test_func[s2] PASSED
+ test_mod2.py@1::test_func2[s2] PASSED
+ test_mod2.py@3::test_func3[s2-m1] PASSED
+ test_mod2.py@5::test_func3b[s2-m1] PASSED
+ test_mod2.py@7::test_func4[m1] PASSED
+ test_mod2.py@3::test_func3[s2-m2] PASSED
+ test_mod2.py@5::test_func3b[s2-m2] PASSED
+ test_mod2.py@7::test_func4[m2] PASSED
+ test_mod1.py@3::test_func1[m1] PASSED
+ test_mod1.py@3::test_func1[m2] PASSED
""")
def test_class_ordering(self, testdir):
@@ -1672,18 +1672,18 @@
""")
result = testdir.runpytest("-vs")
result.stdout.fnmatch_lines("""
- test_class_ordering.py:4: TestClass2.test_1[1-a] PASSED
- test_class_ordering.py:4: TestClass2.test_1[2-a] PASSED
- test_class_ordering.py:6: TestClass2.test_2[1-a] PASSED
- test_class_ordering.py:6: TestClass2.test_2[2-a] PASSED
- test_class_ordering.py:4: TestClass2.test_1[1-b] PASSED
- test_class_ordering.py:4: TestClass2.test_1[2-b] PASSED
- test_class_ordering.py:6: TestClass2.test_2[1-b] PASSED
- test_class_ordering.py:6: TestClass2.test_2[2-b] PASSED
- test_class_ordering.py:9: TestClass.test_3[1-a] PASSED
- test_class_ordering.py:9: TestClass.test_3[2-a] PASSED
- test_class_ordering.py:9: TestClass.test_3[1-b] PASSED
- test_class_ordering.py:9: TestClass.test_3[2-b] PASSED
+ test_class_ordering.py@4::TestClass2::test_1[1-a] PASSED
+ test_class_ordering.py@4::TestClass2::test_1[2-a] PASSED
+ test_class_ordering.py@6::TestClass2::test_2[1-a] PASSED
+ test_class_ordering.py@6::TestClass2::test_2[2-a] PASSED
+ test_class_ordering.py@4::TestClass2::test_1[1-b] PASSED
+ test_class_ordering.py@4::TestClass2::test_1[2-b] PASSED
+ test_class_ordering.py@6::TestClass2::test_2[1-b] PASSED
+ test_class_ordering.py@6::TestClass2::test_2[2-b] PASSED
+ test_class_ordering.py@9::TestClass::test_3[1-a] PASSED
+ test_class_ordering.py@9::TestClass::test_3[2-a] PASSED
+ test_class_ordering.py@9::TestClass::test_3[1-b] PASSED
+ test_class_ordering.py@9::TestClass::test_3[2-b] PASSED
""")
def test_parametrize_separated_order_higher_scope_first(self, testdir):
@@ -2094,7 +2094,7 @@
def fix1(request):
def f():
raise KeyError
- request.addfinalizer(f)
+ request.addfinalizer(f)
return object()
l = []
@@ -2113,7 +2113,7 @@
*KeyError*
*3 pass*2 error*
""")
-
+
def test_setupfunc_missing_funcarg(self, testdir):
diff -r 9572842277fa4cf0e9cac75684b4fb02c3927f4d -r
229f3213f7a629f547e6b89a20263a41611807a1 testing/test_parseopt.py
--- a/testing/test_parseopt.py
+++ b/testing/test_parseopt.py
@@ -145,6 +145,10 @@
assert args.R == True
assert args.S == False
+ def test_parse_removes_line_number_from_positional_arguments(self, parser):
+ args = parser.parse(['path@2::func', 'path2@5::func2[param with @]'])
+ assert getattr(args, parseopt.FILE_OR_DIR) == ['path::func',
'path2::func2[param with @]']
+
def test_parse_defaultgetter(self):
def defaultget(option):
if not hasattr(option, 'type'):
diff -r 9572842277fa4cf0e9cac75684b4fb02c3927f4d -r
229f3213f7a629f547e6b89a20263a41611807a1 testing/test_terminal.py
--- a/testing/test_terminal.py
+++ b/testing/test_terminal.py
@@ -51,9 +51,9 @@
result = testdir.runpytest(*option.args)
if option.verbose:
result.stdout.fnmatch_lines([
- "*test_pass_skip_fail.py:2: *test_ok*PASS*",
- "*test_pass_skip_fail.py:4: *test_skip*SKIP*",
- "*test_pass_skip_fail.py:6: *test_func*FAIL*",
+ "*test_pass_skip_fail.py@2::test_ok PASS*",
+ "*test_pass_skip_fail.py@4::test_skip SKIP*",
+ "*test_pass_skip_fail.py@6::test_func FAIL*",
])
else:
result.stdout.fnmatch_lines([
@@ -126,7 +126,7 @@
])
result = testdir.runpytest("-v", p2)
result.stdout.fnmatch_lines([
- "*test_p2.py <- *test_p1.py:2: TestMore.test_p1*",
+ "*test_p2.py <- *test_p1.py@2::TestMore::test_p1*",
])
def test_itemreport_directclasses_not_shown_as_subclasses(self, testdir):
@@ -450,17 +450,17 @@
""")
result = testdir.runpytest(p1, '-v')
result.stdout.fnmatch_lines([
- "*test_verbose_reporting.py:2: test_fail*FAIL*",
- "*test_verbose_reporting.py:4: test_pass*PASS*",
- "*test_verbose_reporting.py:7: TestClass.test_skip*SKIP*",
- "*test_verbose_reporting.py:10: test_gen*FAIL*",
+ "*test_verbose_reporting.py@2::test_fail *FAIL*",
+ "*test_verbose_reporting.py@4::test_pass *PASS*",
+ "*test_verbose_reporting.py@7::TestClass::test_skip *SKIP*",
+ "*test_verbose_reporting.py@10::test_gen*0* *FAIL*",
])
assert result.ret == 1
pytestconfig.pluginmanager.skipifmissing("xdist")
result = testdir.runpytest(p1, '-v', '-n 1')
result.stdout.fnmatch_lines([
- "*FAIL*test_verbose_reporting.py:2: test_fail*",
+ "*FAIL*test_verbose_reporting.py@2::test_fail*",
])
assert result.ret == 1
diff -r 9572842277fa4cf0e9cac75684b4fb02c3927f4d -r
229f3213f7a629f547e6b89a20263a41611807a1 testing/test_unittest.py
--- a/testing/test_unittest.py
+++ b/testing/test_unittest.py
@@ -29,8 +29,8 @@
""")
result = testdir.runpytest("-v")
result.stdout.fnmatch_lines("""
- *MyTestCaseWithRunTest.runTest*
- *MyTestCaseWithoutRunTest.test_something*
+ *MyTestCaseWithRunTest::runTest*
+ *MyTestCaseWithoutRunTest::test_something*
*2 passed*
""")
https://bitbucket.org/hpk42/pytest/commits/ffe92a9b0441/
Changeset: ffe92a9b0441
Branch: issue504
User: flub
Date: 2014-04-15 17:46:34
Summary: Closing bugfix branch
Affected #: 0 files
Repository URL: https://bitbucket.org/hpk42/pytest/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
_______________________________________________
pytest-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pytest-commit