Compare commits

..

16 Commits

Author SHA1 Message Date
Bruno Oliveira
e59c609b59 Merge pull request #153 from reginaldl/master
Fix CHANGELOG for issue #124
2017-06-09 18:52:11 -03:00
reginaldl
de257e6b83 Fix CHANGELOG for issue #124 2017-06-09 10:51:12 -07:00
Ronny Pfannschmidt
51b5a5ace4 Merge pull request #140 from xoviat/patch-1
travis: use tox-travis
2017-05-17 10:34:15 +02:00
Ronny Pfannschmidt
d86ce20d28 Merge pull request #144 from EdgeCaseLabs/master
Correcting broken URI in documentation.
2017-05-16 15:21:40 +02:00
Wes Thomas
58750f5765 Correcting broken URI in documentation. 2017-05-11 15:29:39 -05:00
xoviat
0789605d30 fixup py36 tests 2017-05-08 09:12:47 -05:00
xoviat
2b57d85550 travis: use tox-travis 2017-05-08 09:11:32 -05:00
Omer Katz
0ce4f32315 Run tests on Python 3.6 on windows. 2017-05-08 09:11:32 -05:00
Omer Katz
de7a45ef40 Test with Python 3.6 as well. 2017-05-08 09:11:32 -05:00
Ronny Pfannschmidt
e83aae6351 Merge pull request #125 from reginaldl/master
Mark test as complete at teardown.
2017-05-05 22:43:53 +02:00
Ronny Pfannschmidt
a23f572b21 Merge pull request #138 from nicoddemus/anaconda-ver
Add a badge for the anaconda package
2017-05-05 07:11:52 +02:00
Bruno Oliveira
36c0e68c23 Add a badge for the anaconda package
Also bring Travis and AppVeyor badges near each other
2017-04-24 17:04:59 -03:00
reginaldl
c79a98c624 Add note about #124 to CHANGELOG. 2017-03-07 10:15:52 -08:00
reginaldl
602694b817 Fix missing blank line. 2017-02-23 15:14:24 -08:00
reginaldl
99f667380f - Reinforce test_crashing_item to match test name instead of test
file.
- Add `test_crashing_item_teardown` to validate crash behavior at
  teardown.
2017-02-23 15:01:48 -08:00
reginaldl
82b992a5fd Mark test as complete at teardown. 2017-02-23 11:31:37 -08:00
8 changed files with 107 additions and 57 deletions

View File

@@ -1,30 +1,19 @@
sudo: false sudo: false
language: python language: python
python: python:
- '2.6'
- '2.7'
- '3.4'
- '3.5' - '3.5'
install: pip install -U tox setuptools_scm - '3.6'
env: install: pip install tox-travis setuptools_scm
matrix: matrix:
include:
# note: please use "tox --listenvs" to populate the build matrix # note: please use "tox --listenvs" to populate the build matrix
- TOXENV=py26-pytest27 - python: "3.5"
- TOXENV=py26-pytest28 env: TOXENV=flakes
- TOXENV=py26-pytest29 - python: "3.5"
- TOXENV=py26-pytest30 env: TOXENV=readme
- TOXENV=py27-pytest27
- TOXENV=py27-pytest28
- TOXENV=py27-pytest29
- TOXENV=py27-pytest30
- TOXENV=py34-pytest27
- TOXENV=py34-pytest28
- TOXENV=py34-pytest29
- TOXENV=py34-pytest30
- TOXENV=py35-pytest27
- TOXENV=py35-pytest28
- TOXENV=py35-pytest29
- TOXENV=py27-pytest28-pexpect
- TOXENV=py35-pytest28-pexpect
- TOXENV=flakes
- TOXENV=readme
script: tox script: tox
notifications: notifications:

View File

@@ -1,3 +1,10 @@
1.17.0
------
- fix #124: xdist would mark test as complete after 'call' step. As a result,
xdist could identify the wrong test as failing when test crashes at teardown.
To address this issue, xdist now marks test as complete at teardown.
1.16.0 1.16.0
------ ------

View File

@@ -1,10 +1,14 @@
.. image:: http://img.shields.io/pypi/v/pytest-xdist.svg
:target: https://pypi.python.org/pypi/pytest-xdist
.. image:: https://anaconda.org/conda-forge/pytest-xdist/badges/version.svg
:target: https://anaconda.org/conda-forge/pytest-xdist
.. image:: https://travis-ci.org/pytest-dev/pytest-xdist.svg?branch=master .. image:: https://travis-ci.org/pytest-dev/pytest-xdist.svg?branch=master
:target: https://travis-ci.org/pytest-dev/pytest-xdist :target: https://travis-ci.org/pytest-dev/pytest-xdist
.. image:: http://img.shields.io/pypi/v/pytest-xdist.svg
:target: https://pypi.python.org/pypi/pytest-xdist
.. image:: https://ci.appveyor.com/api/projects/status/56eq1a1avd4sdd7e/branch/master?svg=true .. image:: https://ci.appveyor.com/api/projects/status/56eq1a1avd4sdd7e/branch/master?svg=true
:target: https://ci.appveyor.com/project/pytestbot/pytest-xdist :target: https://ci.appveyor.com/project/pytestbot/pytest-xdist

View File

@@ -16,6 +16,11 @@ environment:
- TOXENV: "py35-pytest27" - TOXENV: "py35-pytest27"
- TOXENV: "py35-pytest28" - TOXENV: "py35-pytest28"
- TOXENV: "py35-pytest29" - TOXENV: "py35-pytest29"
- TOXENV: "py35-pytest30"
- TOXENV: "py36-pytest27"
- TOXENV: "py36-pytest28"
- TOXENV: "py36-pytest29"
- TOXENV: "py36-pytest30"
- TOXENV: "py27-pytest28-pexpect" - TOXENV: "py27-pytest28-pexpect"
- TOXENV: "py35-pytest28-pexpect" - TOXENV: "py35-pytest28-pexpect"
- TOXENV: "flakes" - TOXENV: "flakes"

View File

@@ -10,7 +10,9 @@ class TestDistribution:
""") """)
result = testdir.runpytest(p1, "-n1") result = testdir.runpytest(p1, "-n1")
assert result.ret == 0 assert result.ret == 0
result.stdout.fnmatch_lines(["*1 passed*", ]) result.stdout.fnmatch_lines([
"*1 passed*",
])
def test_n1_fail(self, testdir): def test_n1_fail(self, testdir):
p1 = testdir.makepyfile(""" p1 = testdir.makepyfile("""
@@ -19,7 +21,9 @@ class TestDistribution:
""") """)
result = testdir.runpytest(p1, "-n1") result = testdir.runpytest(p1, "-n1")
assert result.ret == 1 assert result.ret == 1
result.stdout.fnmatch_lines(["*1 failed*", ]) result.stdout.fnmatch_lines([
"*1 failed*",
])
def test_n1_import_error(self, testdir): def test_n1_import_error(self, testdir):
p1 = testdir.makepyfile(""" p1 = testdir.makepyfile("""
@@ -30,7 +34,7 @@ class TestDistribution:
result = testdir.runpytest(p1, "-n1") result = testdir.runpytest(p1, "-n1")
assert result.ret == 1 assert result.ret == 1
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"E ImportError: *__import_of_missing_module*", "E *Error: No module named *__import_of_missing_module*",
]) ])
def test_n2_import_error(self, testdir): def test_n2_import_error(self, testdir):
@@ -53,7 +57,9 @@ class TestDistribution:
""") """)
result = testdir.runpytest(p1, "-n1") result = testdir.runpytest(p1, "-n1")
assert result.ret == 0 assert result.ret == 0
result.stdout.fnmatch_lines(["*1 skipped*", ]) result.stdout.fnmatch_lines([
"*1 skipped*",
])
def test_manytests_to_one_import_error(self, testdir): def test_manytests_to_one_import_error(self, testdir):
p1 = testdir.makepyfile(""" p1 = testdir.makepyfile("""
@@ -64,11 +70,12 @@ class TestDistribution:
result = testdir.runpytest(p1, '--tx=popen', '--tx=popen') result = testdir.runpytest(p1, '--tx=popen', '--tx=popen')
assert result.ret in (1, 2) assert result.ret in (1, 2)
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines([
"E ImportError: *__import_of_missing_module*", "E *Error: No module named *__import_of_missing_module*",
]) ])
def test_manytests_to_one_popen(self, testdir): def test_manytests_to_one_popen(self, testdir):
p1 = testdir.makepyfile(""" p1 = testdir.makepyfile(
"""
import py import py
def test_fail0(): def test_fail0():
assert 0 assert 0
@@ -108,10 +115,13 @@ class TestDistribution:
""" % str(testdir.tmpdir)) """ % str(testdir.tmpdir))
result = testdir.runpytest_subprocess(p1, "-n1") result = testdir.runpytest_subprocess(p1, "-n1")
assert result.ret == 0 assert result.ret == 0
result.stdout.fnmatch_lines(["*1 passed*", ]) result.stdout.fnmatch_lines([
"*1 passed*",
])
def test_dist_ini_specified(self, testdir): def test_dist_ini_specified(self, testdir):
p1 = testdir.makepyfile(""" p1 = testdir.makepyfile(
"""
import py import py
def test_fail0(): def test_fail0():
assert 0 assert 0
@@ -207,14 +217,14 @@ class TestDistribution:
""") """)
p1 = testdir.makepyfile("def test_func(): pass") p1 = testdir.makepyfile("def test_func(): pass")
result = testdir.runpytest("-v", p1, '-d', '--tx=popen') result = testdir.runpytest("-v", p1, '-d', '--tx=popen')
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines(
"*0*Python*", "*calculated result is 49*", "*1 passed*" ["*0*Python*", "*calculated result is 49*", "*1 passed*"])
])
assert result.ret == 0 assert result.ret == 0
def test_keyboardinterrupt_hooks_issue79(self, testdir): def test_keyboardinterrupt_hooks_issue79(self, testdir):
testdir.makepyfile(__init__="", testdir.makepyfile(
test_one=""" __init__="",
test_one="""
def test_hello(): def test_hello():
raise KeyboardInterrupt() raise KeyboardInterrupt()
""") """)
@@ -273,8 +283,9 @@ class TestDistEach:
py.test.skip("%s not found" % name) py.test.skip("%s not found" % name)
interpreters.append(interp) interpreters.append(interp)
testdir.makepyfile(__init__="", testdir.makepyfile(
test_one=""" __init__="",
test_one="""
import sys import sys
def test_hello(): def test_hello():
print("%s...%s" % sys.version_info[:2]) print("%s...%s" % sys.version_info[:2])
@@ -335,9 +346,8 @@ def test_teardownfails_one_function(testdir):
assert 0 assert 0
""") """)
result = testdir.runpytest(p, '-n1', '--tx=popen') result = testdir.runpytest(p, '-n1', '--tx=popen')
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines(
"*def teardown_function(function):*", "*1 passed*1 error*" ["*def teardown_function(function):*", "*1 passed*1 error*"])
])
@py.test.mark.xfail @py.test.mark.xfail
@@ -350,7 +360,9 @@ def test_terminate_on_hangingnode(testdir):
""") """)
result = testdir.runpytest(p, '--dist=each', '--tx=popen//id=my') result = testdir.runpytest(p, '--dist=each', '--tx=popen//id=my')
assert result.duration < 2.0 assert result.duration < 2.0
result.stdout.fnmatch_lines(["*killed*my*", ]) result.stdout.fnmatch_lines([
"*killed*my*",
])
@pytest.mark.xfail(reason="works if run outside test suite", run=False) @pytest.mark.xfail(reason="works if run outside test suite", run=False)
@@ -377,7 +389,10 @@ def test_session_hooks(testdir):
assert hasattr(sys, 'pytestsessionhooks') assert hasattr(sys, 'pytestsessionhooks')
""") """)
result = testdir.runpytest(p, "--dist=each", "--tx=popen") result = testdir.runpytest(p, "--dist=each", "--tx=popen")
result.stdout.fnmatch_lines(["*ValueError*", "*1 passed*", ]) result.stdout.fnmatch_lines([
"*ValueError*",
"*1 passed*",
])
assert not result.ret assert not result.ret
d = result.parseoutcomes() d = result.parseoutcomes()
assert d['passed'] == 1 assert d['passed'] == 1
@@ -422,7 +437,10 @@ def test_funcarg_teardown_failure(testdir):
pass pass
""") """)
result = testdir.runpytest_subprocess("--debug", p) # , "-n1") result = testdir.runpytest_subprocess("--debug", p) # , "-n1")
result.stdout.fnmatch_lines(["*ValueError*42*", "*1 passed*1 error*", ]) result.stdout.fnmatch_lines([
"*ValueError*42*",
"*1 passed*1 error*",
])
assert result.ret assert result.ret
@@ -436,9 +454,31 @@ def test_crashing_item(testdir):
pass pass
""") """)
result = testdir.runpytest("-n2", p) result = testdir.runpytest("-n2", p)
result.stdout.fnmatch_lines([ result.stdout.fnmatch_lines(
"*crashed*test_crash*", "*1 failed*1 passed*" ["*crashed*::test_crash*", "*1 failed*1 passed*"])
])
def test_crashing_item_teardown(testdir):
p = testdir.makepyfile("""
import py
import pytest
import os
import time
@pytest.fixture
def crash_fixture(request):
def kill_me():
py.process.kill(os.getpid())
request.addfinalizer(kill_me)
def test_a(crash_fixture):
pass
def test_b():
pass
""")
result = testdir.runpytest("-n1", p)
result.stdout.fnmatch_lines(["*crashed*::test_a*", "*1 failed*2 passed*"])
def test_skipping(testdir): def test_skipping(testdir):
@@ -453,7 +493,8 @@ def test_skipping(testdir):
def test_issue34_pluginloading_in_subprocess(testdir): def test_issue34_pluginloading_in_subprocess(testdir):
testdir.tmpdir.join("plugin123.py").write(py.code.Source(""" testdir.tmpdir.join("plugin123.py").write(
py.code.Source("""
def pytest_namespace(): def pytest_namespace():
return {'sample_variable': 'testing'} return {'sample_variable': 'testing'}
""")) """))
@@ -464,7 +505,9 @@ def test_issue34_pluginloading_in_subprocess(testdir):
""") """)
result = testdir.runpytest_subprocess("-n1", "-p", "plugin123") result = testdir.runpytest_subprocess("-n1", "-p", "plugin123")
assert result.ret == 0 assert result.ret == 0
result.stdout.fnmatch_lines(["*1 passed*", ]) result.stdout.fnmatch_lines([
"*1 passed*",
])
def test_fixture_scope_caching_issue503(testdir): def test_fixture_scope_caching_issue503(testdir):
@@ -486,7 +529,9 @@ def test_fixture_scope_caching_issue503(testdir):
""") """)
result = testdir.runpytest(p1, '-v', '-n1') result = testdir.runpytest(p1, '-v', '-n1')
assert result.ret == 0 assert result.ret == 0
result.stdout.fnmatch_lines(["*2 passed*", ]) result.stdout.fnmatch_lines([
"*2 passed*",
])
def test_issue_594_random_parametrize(testdir): def test_issue_594_random_parametrize(testdir):

View File

@@ -1,10 +1,10 @@
[tox] [tox]
# if you change the envlist, please update .travis.yml file as well # if you change the envlist, please update .travis.yml file as well
envlist= envlist=
py{26,27,34,35}-pytest{27,28,29,30} py{26,27,34,35,36}-pytest{27,28,29,30}
py{27,35}-pytest28-pexpect py{27,35}-pytest28-pexpect
flakes flakes
readme readme
[testenv] [testenv]
@@ -20,7 +20,7 @@ deps =
pytest30: pytest~=3.0.5 pytest30: pytest~=3.0.5
pexpect: pexpect pexpect: pexpect
platform= platform=
pexpect: linux|darwin pexpect: linux|darwin
commands= commands=
# always clean to avoid code unmarshal mismatch on old python/pytest # always clean to avoid code unmarshal mismatch on old python/pytest
py.cleanup -aq py.cleanup -aq

View File

@@ -660,7 +660,7 @@ class DSession:
If the node indicates it is finished with a test item, remove If the node indicates it is finished with a test item, remove
the item from the pending list in the scheduler. the item from the pending list in the scheduler.
""" """
if rep.when == "call" or (rep.when == "setup" and not rep.passed): if rep.when == "teardown" or (rep.when == "setup" and not rep.passed):
self.sched.mark_test_complete(node, rep.item_index, rep.duration) self.sched.mark_test_complete(node, rep.item_index, rep.duration)
# self.report_line("testreport %s: %s" %(rep.id, rep.status)) # self.report_line("testreport %s: %s" %(rep.id, rep.status))
rep.node = node rep.node = node

View File

@@ -9,7 +9,7 @@ with the worker instance that executed the hook originally:
You can use this hooks just as you would use normal pytest hooks, but some care You can use this hooks just as you would use normal pytest hooks, but some care
must be taken in plugins in case ``xdist`` is not installed. Please see: must be taken in plugins in case ``xdist`` is not installed. Please see:
http://pytest.org/latest/writing_plugins.html#optionally-using-hooks-from-3rd-party-plugins http://pytest.org/en/latest/writing_plugins.html#optionally-using-hooks-from-3rd-party-plugins
""" """
import pytest import pytest