* refix handling of partial setup failures

* shuffle / consolidate related tests
* re-gen setup.py

--HG--
branch : 1.0.x
This commit is contained in:
holger krekel 2009-07-08 16:41:30 +02:00
parent 183af95526
commit 88a0714dfa
10 changed files with 40 additions and 49 deletions

View File

@ -6,7 +6,8 @@ Changes between 1.0.0b7 and 1.0.0b8
talk/tutorial doc page talk/tutorial doc page
* fixed teardown problem related to partially failing funcarg setups * fixed teardown problem related to partially failing funcarg setups
(thanks MrTopf for reporting) (thanks MrTopf for reporting), "pytest_runtest_teardown" is now
always invoked even if the "pytest_runtest_setup" failed.
* tweaked doctest output for docstrings in py modules, * tweaked doctest output for docstrings in py modules,
thanks Radomir. thanks Radomir.

View File

@ -1,8 +1,6 @@
MANIFEST
py/__init__.py
setup.py
CHANGELOG CHANGELOG
LICENSE LICENSE
MANIFEST
README.txt README.txt
_findpy.py _findpy.py
doc/announce/release-0.9.0.txt doc/announce/release-0.9.0.txt
@ -31,6 +29,7 @@ doc/test/extend.txt
doc/test/features.txt doc/test/features.txt
doc/test/funcargs.txt doc/test/funcargs.txt
doc/test/quickstart.txt doc/test/quickstart.txt
doc/test/talks.txt
doc/test/test.txt doc/test/test.txt
doc/test/xunit_setup.txt doc/test/xunit_setup.txt
doc/xml.txt doc/xml.txt
@ -58,6 +57,7 @@ example/pytest/failure_demo.py
example/pytest/test_failures.py example/pytest/test_failures.py
example/pytest/test_setup_flow_example.py example/pytest/test_setup_flow_example.py
py/LICENSE py/LICENSE
py/__init__.py
py/_com.py py/_com.py
py/bin/_findpy.py py/bin/_findpy.py
py/bin/_genscripts.py py/bin/_genscripts.py
@ -333,6 +333,7 @@ py/test/plugin/pytest_tmpdir.py
py/test/plugin/pytest_unittest.py py/test/plugin/pytest_unittest.py
py/test/plugin/pytest_xfail.py py/test/plugin/pytest_xfail.py
py/test/plugin/test_pytest_runner.py py/test/plugin/test_pytest_runner.py
py/test/plugin/test_pytest_runner_xunit.py
py/test/pluginmanager.py py/test/pluginmanager.py
py/test/pycollect.py py/test/pycollect.py
py/test/session.py py/test/session.py
@ -358,7 +359,6 @@ py/test/testing/test_pluginmanager.py
py/test/testing/test_pycollect.py py/test/testing/test_pycollect.py
py/test/testing/test_recording.py py/test/testing/test_recording.py
py/test/testing/test_session.py py/test/testing/test_session.py
py/test/testing/test_setup_functional.py
py/test/testing/test_traceback.py py/test/testing/test_traceback.py
py/test/web/__init__.py py/test/web/__init__.py
py/test/web/exception.py py/test/web/exception.py
@ -382,3 +382,4 @@ py/xmlobj/testing/test_html.py
py/xmlobj/testing/test_xml.py py/xmlobj/testing/test_xml.py
py/xmlobj/visit.py py/xmlobj/visit.py
py/xmlobj/xml.py py/xmlobj/xml.py
setup.py

View File

@ -19,7 +19,7 @@ For questions please check out http://pylib.org/contact.html
""" """
from initpkg import initpkg from initpkg import initpkg
version = "1.0.0b7" version = "1.0.0b8"
initpkg(__name__, initpkg(__name__,
description = "py.test and pylib: advanced testing tool and networking lib", description = "py.test and pylib: advanced testing tool and networking lib",

View File

@ -362,6 +362,7 @@ def test_deindent():
class TestApigenLinkRole: class TestApigenLinkRole:
disabled = True disabled = True
# these tests are moved here from the former py/doc/conftest.py # these tests are moved here from the former py/doc/conftest.py
def test_resolve_linkrole(self): def test_resolve_linkrole(self):
from py.__.doc.conftest import get_apigen_relpath from py.__.doc.conftest import get_apigen_relpath

View File

@ -1,9 +1,5 @@
""" """
collect and run test items. collect and run test items and creating reports.
* executing test items
* running collectors
* and generating report events about it
""" """
import py import py
@ -53,7 +49,7 @@ def runtestprotocol(item, log=True):
reports = [rep] reports = [rep]
if rep.passed: if rep.passed:
reports.append(call_and_report(item, "call", log)) reports.append(call_and_report(item, "call", log))
reports.append(call_and_report(item, "teardown", log)) reports.append(call_and_report(item, "teardown", log))
return reports return reports
def pytest_runtest_setup(item): def pytest_runtest_setup(item):
@ -225,11 +221,14 @@ class SetupState(object):
colitem = self.stack.pop() colitem = self.stack.pop()
self._teardown_with_finalization(colitem) self._teardown_with_finalization(colitem)
def _teardown_with_finalization(self, colitem): def _callfinalizers(self, colitem):
finalizers = self._finalizers.pop(colitem, None) finalizers = self._finalizers.pop(colitem, None)
while finalizers: while finalizers:
fin = finalizers.pop() fin = finalizers.pop()
fin() fin()
def _teardown_with_finalization(self, colitem):
self._callfinalizers(colitem)
if colitem: if colitem:
colitem.teardown() colitem.teardown()
for colitem in self._finalizers: for colitem in self._finalizers:
@ -242,17 +241,19 @@ class SetupState(object):
assert not self._finalizers assert not self._finalizers
def teardown_exact(self, item): def teardown_exact(self, item):
assert self.stack and self.stack[-1] == item if item == self.stack[-1]:
self._pop_and_teardown() self._pop_and_teardown()
else:
self._callfinalizers(item)
def prepare(self, colitem): def prepare(self, colitem):
""" setup objects along the collector chain to the test-method """ setup objects along the collector chain to the test-method
Teardown any unneccessary previously setup objects.""" and teardown previously setup objects."""
needed_collectors = colitem.listchain() needed_collectors = colitem.listchain()
while self.stack: while self.stack:
if self.stack == needed_collectors[:len(self.stack)]: if self.stack == needed_collectors[:len(self.stack)]:
break break
self._pop_and_teardown() self._pop_and_teardown()
for col in needed_collectors[len(self.stack):]: for col in needed_collectors[len(self.stack):]:
self.stack.append(col)
col.setup() col.setup()
self.stack.append(col)

View File

@ -86,7 +86,8 @@ class BaseFunctionalTests:
#assert rep.skipped.reason == "hello" #assert rep.skipped.reason == "hello"
#assert rep.skipped.location.lineno == 3 #assert rep.skipped.location.lineno == 3
#assert rep.skipped.location.lineno == 3 #assert rep.skipped.location.lineno == 3
assert len(reports) == 1 assert len(reports) == 2
assert reports[1].passed # teardown
def test_failure_in_setup_function(self, testdir): def test_failure_in_setup_function(self, testdir):
reports = testdir.runitem(""" reports = testdir.runitem("""
@ -101,7 +102,7 @@ class BaseFunctionalTests:
assert not rep.passed assert not rep.passed
assert rep.failed assert rep.failed
assert rep.when == "setup" assert rep.when == "setup"
assert len(reports) == 1 assert len(reports) == 2
def test_failure_in_teardown_function(self, testdir): def test_failure_in_teardown_function(self, testdir):
reports = testdir.runitem(""" reports = testdir.runitem("""
@ -156,7 +157,7 @@ class BaseFunctionalTests:
def test_func(): def test_func():
pass pass
""") """)
assert len(reports) == 1 assert len(reports) == 2
rep = reports[0] rep = reports[0]
print rep print rep
assert not rep.skipped assert not rep.skipped

View File

@ -55,6 +55,7 @@ def test_class_setup(testdir):
""") """)
reprec.assertoutcome(passed=1+2+1) reprec.assertoutcome(passed=1+2+1)
def test_method_setup(testdir): def test_method_setup(testdir):
reprec = testdir.inline_runsource(""" reprec = testdir.inline_runsource("""
class TestSetupMethod: class TestSetupMethod:

View File

@ -221,30 +221,6 @@ class TestPytestPluginInteractions:
assert not pluginmanager.listattr("hello") assert not pluginmanager.listattr("hello")
assert pluginmanager.listattr("x") == [42] assert pluginmanager.listattr("x") == [42]
@py.test.mark.xfail # setup call methods
def test_call_setup_participants(self, testdir):
testdir.makepyfile(
conftest="""
import py
def pytest_method(self, x):
return x+1
pytest_plugin = "pytest_someplugin",
"""
)
testdir.makepyfile(pytest_someplugin="""
def pytest_method(self, x):
return x+1
""")
modcol = testdir.getmodulecol("""
def pytest_method(x):
return x+0
""")
l = []
call = modcol.config.pluginmanager.setupcall(modcol, "pytest_method", 1)
assert len(call.methods) == 3
results = call.execute()
assert results == [1,2,2]
def test_collectattr(): def test_collectattr():
class A: class A:
def pytest_hello(self): def pytest_hello(self):

View File

@ -39,6 +39,7 @@ class TestModule:
modcol = testdir.getmodulecol("pytest_plugins='xasdlkj',") modcol = testdir.getmodulecol("pytest_plugins='xasdlkj',")
py.test.raises(ImportError, "modcol.obj") py.test.raises(ImportError, "modcol.obj")
class TestDisabled:
def test_disabled_module(self, testdir): def test_disabled_module(self, testdir):
modcol = testdir.getmodulecol(""" modcol = testdir.getmodulecol("""
disabled = True disabled = True
@ -51,7 +52,6 @@ class TestModule:
assert len(l) == 1 assert len(l) == 1
py.test.raises(Skipped, "modcol.setup()") py.test.raises(Skipped, "modcol.setup()")
class TestClass:
def test_disabled_class(self, testdir): def test_disabled_class(self, testdir):
modcol = testdir.getmodulecol(""" modcol = testdir.getmodulecol("""
class TestClass: class TestClass:
@ -67,6 +67,15 @@ class TestClass:
assert len(l) == 1 assert len(l) == 1
py.test.raises(Skipped, "modcol.setup()") py.test.raises(Skipped, "modcol.setup()")
def test_disabled_class_functional(self, testdir):
reprec = testdir.inline_runsource("""
class TestSimpleClassSetup:
disabled = True
def test_classlevel(self): pass
def test_classlevel2(self): pass
""")
reprec.assertoutcome(skipped=2)
class TestGenerator: class TestGenerator:
def test_generative_functions(self, testdir): def test_generative_functions(self, testdir):
modcol = testdir.getmodulecol(""" modcol = testdir.getmodulecol("""

View File

@ -1,6 +1,6 @@
""" """
autogenerated by gensetup.py py lib / py.test setup.py file, autogenerated by gensetup.py
""" """
import os, sys import os, sys
@ -30,7 +30,7 @@ def main():
name='py', name='py',
description='py.test and pylib: advanced testing tool and networking lib', description='py.test and pylib: advanced testing tool and networking lib',
long_description = long_description, long_description = long_description,
version='1.0.0b7', version='1.0.0b8',
url='http://pylib.org', url='http://pylib.org',
license='MIT license', license='MIT license',
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
@ -144,4 +144,4 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
main() main()