[py-svn] r56737 - in py/branch/event/py/test2: . rsession testing
hpk at codespeak.net
hpk at codespeak.net
Wed Jul 23 15:04:05 CEST 2008
Author: hpk
Date: Wed Jul 23 15:04:03 2008
New Revision: 56737
Modified:
py/branch/event/py/test2/rsession/slave.py
py/branch/event/py/test2/runner.py
py/branch/event/py/test2/session.py
py/branch/event/py/test2/testing/test_runner.py
py/branch/event/py/test2/testing/test_session.py
Log:
refactoring the runner to not use the
config "kitchen sink" object but require
explicit objects for its operations.
also involves a refactoring of runner
tests making them independent from the
collection process, more unit-testish.
Modified: py/branch/event/py/test2/rsession/slave.py
==============================================================================
--- py/branch/event/py/test2/rsession/slave.py (original)
+++ py/branch/event/py/test2/rsession/slave.py Wed Jul 23 15:04:03 2008
@@ -14,7 +14,7 @@
break
item = config._getcollector(itemspec)
runner = item._getrunner()
- testrep = runner(item)
+ testrep = runner(item, item._config._setupstate, item._config._getcapture)
send(testrep.dumps())
def setup():
Modified: py/branch/event/py/test2/runner.py
==============================================================================
--- py/branch/event/py/test2/runner.py (original)
+++ py/branch/event/py/test2/runner.py Wed Jul 23 15:04:03 2008
@@ -5,7 +5,7 @@
import py, os, sys
from py.__.test2 import repevent
-from py.__.test2.outcome import Skipped
+from py.__.test2.outcome import Skipped, Exit
from py.__.test.outcome import Skipped as Skipped2
import py.__.test2.custompdb
from py.__.test2 import present
@@ -16,23 +16,24 @@
self.excinfo = excinfo
self.outerr = outerr
-def basic_runner(item):
+def basic_runner(item, setupstate, getcapture, pdbfunc=None):
""" returns a test report after having run the given test item. """
- config = item._config
- capture = config._getcapture(path=item.fspath)
+ capture = getcapture()
excinfo = None
try:
try:
outcome = "setupfailed"
- config._setupstate.prepare(item)
- outcome = "failed"
- item.execute()
- outcome = "setupfailed"
- config._setupstate.teardown_exact(item)
+ setupstate.prepare(item)
+ try:
+ item.execute()
+ finally:
+ outcome = "setupfailed"
+ setupstate.teardown_exact(item)
+ outcome = "failed"
outcome = "passed"
finally:
outerr = capture.reset()
- except KeyboardInterrupt:
+ except (Exit, KeyboardInterrupt):
raise
except:
excinfo = py.code.ExceptionInfo()
@@ -52,38 +53,42 @@
title="failure during setup/teardown")
rep = repevent.ItemTestReport(trail, outcome, repr_run, repr_path)
- if config.option.usepdb and rep.failed:
+ if pdbfunc and rep.failed:
# xxx print rep.repr_run() ?
- py.__.test2.custompdb.post_mortem(excinfo._excinfo[2])
+ pdbfunc(excinfo._excinfo[2])
return rep
-def fork_runner(item):
+def fork_runner(item, setupstate, getcapture):
def runforked():
- testrep = basic_runner(item)
+ testrep = basic_runner(item, setupstate, getcapture)
return testrep.dumps()
ff = py.io.ForkedFunc(runforked)
result = ff.waitfinish()
+ print vars(result)
if result.retval is not None:
- testrep = repevent.ItemTestReport.fromdumps(result.retval)
+ return repevent.ItemTestReport.fromdumps(result.retval)
#testrep.stdout = result.out
#testrep.stderr = result.err
else:
- # xxx look into reusing present/tbpresent-writer
- tw = py.io.TerminalWriter()
- tw.sep("_", "CRASHED with signal=%d: %s" %
- (result.signal, present.getmodpath(item)))
- code = py.code.Code(item.obj)
- path, firstlineno = code.path, code.firstlineno
- src = py.code.Source(item.obj)
- tw.line()
- tw.line(str(src.indent()))
- tw.line("[%s:%d]" %(path, firstlineno))
- repr_run = tw.stringio.getvalue()
- repr_path = item.repr_path()
- trail = item._get_collector_trail()
- testrep = repevent.ItemTestReport(trail, "failed", repr_run, repr_path)
- #testrep.stdout = result.out
- #testrep.stderr = result.err
+ return report_crash(item, result)
+
+def report_crash(item, result):
+ # xxx look into reusing present/tbpresent-writer
+ tw = py.io.TerminalWriter()
+ tw.sep("_", "CRASHED with signal=%d: %s" %
+ (result.signal, present.getmodpath(item)))
+ code = py.code.Code(item.obj)
+ path, firstlineno = code.path, code.firstlineno
+ src = py.code.Source(item.obj)
+ tw.line()
+ tw.line(str(src.indent()))
+ tw.line("[%s:%d]" %(path, firstlineno))
+ repr_run = tw.stringio.getvalue()
+ repr_path = item.repr_path()
+ trail = item._get_collector_trail()
+ testrep = repevent.ItemTestReport(trail, "failed", repr_run, repr_path)
+ #testrep.stdout = result.out
+ #testrep.stderr = result.err
return testrep
Modified: py/branch/event/py/test2/session.py
==============================================================================
--- py/branch/event/py/test2/session.py (original)
+++ py/branch/event/py/test2/session.py Wed Jul 23 15:04:03 2008
@@ -85,5 +85,5 @@
def runtest(self, item):
runner = item._getrunner()
- return runner(item)
+ return runner(item, item._config._setupstate, item._config._getcapture)
Modified: py/branch/event/py/test2/testing/test_runner.py
==============================================================================
--- py/branch/event/py/test2/testing/test_runner.py (original)
+++ py/branch/event/py/test2/testing/test_runner.py Wed Jul 23 15:04:03 2008
@@ -1,213 +1,236 @@
import py
-from py.__.test2.runner import basic_runner, fork_runner
+from py.__.test2 import runner
+from py.__.test2.outcome import Exit
+from py.__.test2 import present
def setup_module(mod):
mod.tmpdir = py.test.ensuretemp(mod.__name__)
-class TestRunner:
- def getrunner(self):
- return basic_runner
-
- def setup_method(self, method):
- self.tmpdir = tmpdir.join("%s_%s" %
- (self.__class__.__name__, method.__name__))
-
- def getmodulecol(self, func, funcname="testfunc"):
- funcname = getattr(func, '__name__', funcname)
- self.tmpdir.ensure("__init__.py")
- path = self.tmpdir.ensure(funcname + ".py")
- path.write(py.code.Source(func))
- self.config = py.test2.config._reparse([path.dirpath()])
- modulecol = self.config._getcollector(path)
- return modulecol
-
- def makeitem(self, source, funcname="testfunc"):
- modulecol = self.getmodulecol(source)
- item = modulecol.join(funcname)
- assert item is not None, (item, funcname)
- return item
-
- def getitems(self, source):
- modulecol = self.getmodulecol(source)
- return [modulecol.join(x) for x in modulecol.listdir()]
+class MockItem:
+ def __init__(self, func):
+ self.func = func
+
+ def _get_collector_trail(self):
+ return "MockItem.trail"
+
+ def repr_path(self):
+ return "MockItem.repr_path"
+
+ def repr_run(self, runnerinfo):
+ excinfo = runnerinfo.excinfo
+ if not excinfo:
+ return ("(%s)MockItem.repr_run" %(runnerinfo.outerr,))
+ else:
+ assert isinstance(excinfo, py.code.ExceptionInfo)
+ return ("(%s)MockItem.repr_run: %s" %(
+ runnerinfo.outerr, excinfo.exconly()))
+
+ def execute(self):
+ self.func()
+
+class MockCapture:
+ def reset(self):
+ return "out", "err"
+
+class MockSetupState:
+ def prepare(self, item):
+ return
+ def teardown_exact(self, item):
+ pass
+ def teardown_all(self):
+ pass
- def runtestfunc(self, func, funcname="testfunc"):
- item = self.makeitem(func, funcname=funcname)
+class RunnerTests:
+ def run(self, func, setupstate=None, getcapture=None):
runner = self.getrunner()
- return runner(item)
+ item = MockItem(func)
+ if not setupstate: setupstate = MockSetupState()
+ if not getcapture: getcapture = MockCapture
+ testrep = runner(item, setupstate, getcapture)
+ return testrep
def test_run_pass(self):
- testrep = self.runtestfunc("""
- def testfunc():
- pass
- """)
- assert testrep.passed
+ def test_func():
+ pass
+ testrep = self.run(test_func)
+ assert testrep.passed
def test_run_fail(self):
- testrep = self.runtestfunc("""
- def testfunc():
- assert 0
- """)
+ def testfunc():
+ assert 0
+ testrep = self.run(testfunc)
assert not testrep.passed
assert testrep.failed
def test_run_skip(self):
- testrep = self.runtestfunc("""
- import py
- def testfunc():
- py.test2.skip("hello")
- """)
+ def testfunc():
+ py.test2.skip("hello")
+ testrep = self.run(testfunc)
assert testrep.skipped
assert not testrep.passed
assert not testrep.failed
assert not testrep.setupfailed
def test_systemexit_does_not_bail_out(self):
- testrep = self.runtestfunc("""
- import sys
- def testfunc():
- raise SystemExit(42)
- """)
+ def testfunc():
+ raise SystemExit(42)
+ try:
+ testrep = self.run(testfunc)
+ except SystemExit:
+ py.test.fail("runner did not catch SystemExit")
assert testrep.failed
assert not testrep.setupfailed
assert testrep.repr_run.find("SystemExit") != -1
- def test_run_capture_stdout(self):
- testrep = self.runtestfunc("""
- def testfunc():
- print "samfing"
- """)
- assert testrep.passed
- assert testrep.repr_run.find("stderr") == -1
- assert testrep.repr_run.find("samfing\n") != -1
-
- def test_run_capture_stderr(self):
- testrep = self.runtestfunc("""
- import sys
- def testfunc():
- print >>sys.stderr, "samfong"
- """)
- print testrep.repr_run
- assert testrep.repr_run.find("stdout") == -1
- assert testrep.repr_run.find("stderr") != -1
- assert testrep.repr_run.find("samfong\n") != -1
-
- def test_print_with_assertion_failed(self):
- testrep = self.runtestfunc("""
- import sys
- def testfunc():
- print "samfing elz"
- print >>sys.stderr, "sure"
- assert 0
- """)
- assert not testrep.passed
- assert testrep.failed
- assert testrep.repr_run.find("stdout") != -1
- assert testrep.repr_run.find("stderr") != -1
- assert testrep.repr_run.find("samfing elz") != -1
- assert testrep.repr_run.find("sure") != -1
-
- def test_print_with_explicit_fail(self):
- testrep = self.runtestfunc("""
- import py, sys
- def testfunc():
- print "samfing elz"
- print >>sys.stderr, "sure"
- py.test.fail()
- """)
- assert not testrep.passed
- assert testrep.failed
- assert testrep.repr_run.find("stdout") != -1
- assert testrep.repr_run.find("stderr") != -1
- assert testrep.repr_run.find("samfing elz\n") != -1
- assert testrep.repr_run.find("sure\n") != -1
-
- def test_setupfailure(self):
- testrep = self.runtestfunc("""
- def setup_module(mod):
- raise ValueError(10)
- def testfunc():
- pass
- """)
+ def test_exit_does_bail_out(self):
+ def testfunc():
+ raise Exit()
+ py.test.raises(Exit, "self.run(testfunc)")
+
+ def test_runner_handles_skip_in_prepare(self):
+ l = []
+ class MySetupState:
+ def prepare(self, item):
+ py.test2.skip("skip")
+ def testfunc(): pass
+ def pythonreprrun(item, runnerinfo, title=None): return ""
+ py.magic.patch(present, "python_repr_run", pythonreprrun)
+ try:
+ testrep = self.run(testfunc, setupstate=MySetupState())
+ finally:
+ py.magic.revert(present, "python_repr_run")
+ assert testrep.skipped
+ assert not testrep.failed
assert not testrep.passed
- assert testrep.setupfailed
- assert testrep.failed
- s = testrep.repr_run
- print s
- exp = "failure during setup/teardown"
- assert s.find(exp) != -1
- i = s.find("def ")
- assert s[i+4:].startswith("setup_module")
-
- def test_setup_skip(self):
- testrep = self.runtestfunc("""
- import py
- def setup_module(mod):
- py.test.skip("setupmoduleskip")
- def testfunc():
- pass
- """)
- assert testrep.skipped
+ def test_runnner_handles_setupfailure_in_prepare(self):
+ l = []
+ class MySetupState:
+ def prepare(self, item):
+ raise ValueError(2)
+ def testfunc():
+ pass
+ def pythonreprrun(item, runnerinfo, title=None):
+ assert runnerinfo.excinfo.errisinstance(ValueError)
+ return "pythonreprrun"
+ py.magic.patch(present, "python_repr_run", pythonreprrun)
+ try:
+ testrep = self.run(testfunc, setupstate=MySetupState())
+ finally:
+ py.magic.revert(present, "python_repr_run")
+ assert testrep.setupfailed
+ assert testrep.failed
assert not testrep.passed
- assert not testrep.setupfailed
- assert not testrep.failed
+ assert testrep.repr_run == "pythonreprrun"
- def test_setupfailure_always_python_traceback(self):
- item = self.makeitem("""
- def setup_module(mod):
- raise ValueError(10)
- def testfunc():
- pass
- """)
- runner = self.getrunner()
- item.repr_run = lambda *args: "cusWRONG TRACEBACK!"
- testrep = runner(item)
- assert not testrep.passed
- assert testrep.setupfailed
- assert testrep.failed
- # repr_run of setupfailures should always
- # display python Tracebacks starting from the
- # failing setup function
- s = testrep.repr_run
- print s
- i = s.find("def ")
- assert s[i+4:].startswith("setup_module")
-
- def test_setupfailure_on_eager_teardown(self):
- testrep = self.runtestfunc("""
- def testfunc():
+ def test_runner_handles_capture(self):
+ l = []
+ class MyCapture:
+ def __init__(self):
+ l.append("init")
+ def reset(self):
+ l.append("reset")
+ return ":".join(l), ""
+ def testfunc():
+ l.append("run")
+ testrep = self.run(testfunc, getcapture=MyCapture)
+ assert testrep.passed
+ assert testrep.repr_run.find("init:run:reset") != -1
+
+ def testfuncfail():
+ l.append("run")
+ assert 0
+ l[:] = []
+ testrep = self.run(testfuncfail, getcapture=MyCapture)
+ assert testrep.repr_run.find("init:run:reset") != -1
+ assert testrep.failed
+
+class TestBasicRunner(RunnerTests):
+ def getrunner(self):
+ return runner.basic_runner
+
+ def test_runner_handles_setupstate(self):
+ l = []
+ class MySetupState:
+ def prepare(self, item):
+ l.append("prepare")
+ def teardown_exact(self, item):
+ l.append("teardown_exact")
+ def testfunc():
+ l.append("run")
+ testrep = self.run(testfunc, setupstate=MySetupState())
+ assert l == ["prepare", "run", "teardown_exact"]
+ assert testrep.passed
+
+ def testfuncfail():
+ l.append("run")
+ assert 0
+ l[:] = []
+ testrep = self.run(testfuncfail, setupstate=MySetupState())
+ assert l == ["prepare", "run", "teardown_exact"]
+ assert testrep.failed
+
+
+ def test_runnner_handles_setupfailure_in_eager_teardown(self):
+ l = []
+ class MySetupState:
+ def prepare(self, item):
pass
- def teardown_function(func):
- raise ValueError(11)
- """)
+ def teardown_exact(self, item):
+ raise ValueError(17)
+ def testfunc():
+ l.append(0)
+ pass
+ def pythonreprrun(item, runnerinfo, title=None):
+ l.append(runnerinfo)
+ py.magic.patch(present, "python_repr_run", pythonreprrun)
+ try:
+ testrep = self.run(testfunc, setupstate=MySetupState())
+ finally:
+ py.magic.revert(present, "python_repr_run")
assert testrep.setupfailed
+ assert testrep.failed
assert not testrep.passed
- assert testrep.failed
- s = testrep.repr_run
- print s
- i = s.find("def ")
- assert s[i+4:].startswith("teardown_function")
+ assert len(l) == 2 # means that testfunc didnt run
+ assert l[0] == 0
+ assert l[1].excinfo.errisinstance(ValueError)
+
+ def test_runner_handles_pdb(self):
+ py.test.skip("check for proper pdb interaction")
-class TestForkRunner(TestRunner):
+class TestForkRunner(RunnerTests):
def setup_class(cls):
if not hasattr(py.std.os, 'fork'):
py.test.skip("need os.fork()")
+
def getrunner(self):
- return fork_runner
+ return runner.fork_runner
+
+ def test_exit_does_bail_out(self):
+ py.test.skip("XXX needs work")
+ def testfunc():
+ raise Exit()
+ py.test.raises(Exit, "self.run(testfunc)")
def test_suicide(self):
- testrep = self.runtestfunc("""
+ def testfunc():
import os
- def testfunc():
- os.kill(os.getpid(), 15)
- #
- """)
- assert not testrep.passed
- assert testrep.failed
- assert testrep.repr_run.find("CRASHED") != -1
- assert testrep.repr_run.find("signal=15") != -1
- print testrep.repr_run
+ os.kill(os.getpid(), 15)
+ crashes = []
+ def myreport(item, result):
+ crashes.append((item, result))
+ py.magic.patch(runner, "report_crash", myreport)
+ try:
+ testrep = self.run(testfunc)
+ finally:
+ py.magic.revert(runner, "report_crash")
+ assert len(crashes) == 1
+ assert crashes[0][1].signal == 15
# assert 0
+def test_crash_report():
+ py.test.skip("check that crash reporting works")
+
+def test_present_tb_and_python_repr_run():
+ py.test.skip("check that present_tb and python_repr_run work")
Modified: py/branch/event/py/test2/testing/test_session.py
==============================================================================
--- py/branch/event/py/test2/testing/test_session.py (original)
+++ py/branch/event/py/test2/testing/test_session.py Wed Jul 23 15:04:03 2008
@@ -206,6 +206,7 @@
assert len(failedcollections) == 2
def test_pdb_run(self):
+ py.test.skip("fix this test after the runner refactoring")
tfile = suptest.makeuniquepyfile("""
def test_usepdb():
assert 0
More information about the pytest-commit
mailing list