move session.py and collect.py to a unified pytest_session.py plugin.
--HG-- branch : trunk
This commit is contained in:
parent
d1aff902d5
commit
51bb0f53c5
|
@ -2,14 +2,25 @@
|
||||||
extensible functional and unit testing with Python.
|
extensible functional and unit testing with Python.
|
||||||
(c) Holger Krekel and others, 2004-2010
|
(c) Holger Krekel and others, 2004-2010
|
||||||
"""
|
"""
|
||||||
__version__ = "1.4.0a1"
|
__version__ = "2.0.0dev0"
|
||||||
|
|
||||||
#__all__ = ['collect']
|
|
||||||
|
|
||||||
import pytest.collect
|
|
||||||
import pytest.config
|
import pytest.config
|
||||||
from pytest import collect
|
from pytest import collect
|
||||||
|
|
||||||
|
class cmdline: # compatibility py.test.cmdline.main == pytest.cmdline.main
|
||||||
|
@staticmethod
|
||||||
|
def main(args=None):
|
||||||
|
import sys
|
||||||
|
if args is None:
|
||||||
|
args = sys.argv[1:]
|
||||||
|
config = pytest.config.Config()
|
||||||
|
config.parse(args)
|
||||||
|
try:
|
||||||
|
exitstatus = config.hook.pytest_cmdline_main(config=config)
|
||||||
|
except config.Error:
|
||||||
|
e = sys.exc_info()[1]
|
||||||
|
sys.stderr.write("ERROR: %s\n" %(e.args[0],))
|
||||||
|
exitstatus = EXIT_INTERNALERROR
|
||||||
|
return exitstatus
|
||||||
|
|
||||||
def __main__():
|
def __main__():
|
||||||
from pytest.session import main
|
raise SystemExit(cmdline.main())
|
||||||
raise SystemExit(main())
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
__all__ = []
|
||||||
|
import py, pytest
|
||||||
|
|
||||||
|
def main(args=None):
|
||||||
|
import sys
|
||||||
|
if args is None:
|
||||||
|
args = sys.argv[1:]
|
||||||
|
config = py.test.config
|
||||||
|
config.parse(args)
|
||||||
|
try:
|
||||||
|
exitstatus = config.hook.pytest_cmdline_main(config=config)
|
||||||
|
except config.Error:
|
||||||
|
e = sys.exc_info()[1]
|
||||||
|
sys.stderr.write("ERROR: %s\n" %(e.args[0],))
|
||||||
|
exitstatus = 3
|
||||||
|
py.test.config = config.__class__()
|
||||||
|
return exitstatus
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
""" default hooks and general py.test options. """
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import py
|
|
||||||
|
|
||||||
def pytest_cmdline_main(config):
|
|
||||||
from pytest.session import Session
|
|
||||||
return Session(config).main()
|
|
||||||
|
|
||||||
def pytest_perform_collection(session):
|
|
||||||
collection = session.collection
|
|
||||||
assert not hasattr(collection, 'items')
|
|
||||||
hook = session.config.hook
|
|
||||||
collection.items = items = collection.perform_collect()
|
|
||||||
hook.pytest_collection_modifyitems(config=session.config, items=items)
|
|
||||||
hook.pytest_log_finishcollection(collection=collection)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def pytest_runtest_mainloop(session):
|
|
||||||
if session.config.option.collectonly:
|
|
||||||
return True
|
|
||||||
for item in session.collection.items:
|
|
||||||
item.config.hook.pytest_runtest_protocol(item=item)
|
|
||||||
if session.shouldstop:
|
|
||||||
raise session.Interrupted(session.shouldstop)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def pytest_ignore_collect(path, config):
|
|
||||||
p = path.dirpath()
|
|
||||||
ignore_paths = config.getconftest_pathlist("collect_ignore", path=p)
|
|
||||||
ignore_paths = ignore_paths or []
|
|
||||||
excludeopt = config.getvalue("ignore")
|
|
||||||
if excludeopt:
|
|
||||||
ignore_paths.extend([py.path.local(x) for x in excludeopt])
|
|
||||||
return path in ignore_paths
|
|
||||||
|
|
||||||
def pytest_collect_directory(path, parent):
|
|
||||||
if not parent.recfilter(path): # by default special ".cvs", ...
|
|
||||||
# check if cmdline specified this dir or a subdir directly
|
|
||||||
for arg in parent.collection._argfspaths:
|
|
||||||
if path == arg or arg.relto(path):
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
return parent.Directory(path, parent=parent)
|
|
||||||
|
|
||||||
def pytest_report_iteminfo(item):
|
|
||||||
return item.reportinfo()
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
|
||||||
group = parser.getgroup("general", "running and selection options")
|
|
||||||
group._addoption('-x', '--exitfirst', action="store_true", default=False,
|
|
||||||
dest="exitfirst",
|
|
||||||
help="exit instantly on first error or failed test."),
|
|
||||||
group._addoption('--maxfail', metavar="num",
|
|
||||||
action="store", type="int", dest="maxfail", default=0,
|
|
||||||
help="exit after first num failures or errors.")
|
|
||||||
|
|
||||||
group = parser.getgroup("collect", "collection")
|
|
||||||
group.addoption('--collectonly',
|
|
||||||
action="store_true", dest="collectonly",
|
|
||||||
help="only collect tests, don't execute them."),
|
|
||||||
group.addoption("--ignore", action="append", metavar="path",
|
|
||||||
help="ignore path during collection (multi-allowed).")
|
|
||||||
group.addoption('--confcutdir', dest="confcutdir", default=None,
|
|
||||||
metavar="dir",
|
|
||||||
help="only load conftest.py's relative to specified dir.")
|
|
||||||
|
|
||||||
group = parser.getgroup("debugconfig",
|
|
||||||
"test process debugging and configuration")
|
|
||||||
group.addoption('--basetemp', dest="basetemp", default=None, metavar="dir",
|
|
||||||
help="base temporary directory for this test run.")
|
|
||||||
|
|
||||||
def pytest_configure(config):
|
|
||||||
# compat
|
|
||||||
if config.getvalue("exitfirst"):
|
|
||||||
config.option.maxfail = 1
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import inspect
|
||||||
import time
|
import time
|
||||||
from fnmatch import fnmatch
|
from fnmatch import fnmatch
|
||||||
from pytest.config import Config as pytestConfig
|
from pytest.config import Config as pytestConfig
|
||||||
|
from pytest.plugin.pytest_session import Collection
|
||||||
from py.builtin import print_
|
from py.builtin import print_
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
|
@ -149,7 +150,6 @@ class TmpTestdir:
|
||||||
return p
|
return p
|
||||||
|
|
||||||
def getnode(self, config, arg):
|
def getnode(self, config, arg):
|
||||||
from pytest.session import Collection
|
|
||||||
collection = Collection(config)
|
collection = Collection(config)
|
||||||
return collection.getbyid(collection._normalizearg(arg))[0]
|
return collection.getbyid(collection._normalizearg(arg))[0]
|
||||||
|
|
||||||
|
@ -161,7 +161,6 @@ class TmpTestdir:
|
||||||
|
|
||||||
def inline_genitems(self, *args):
|
def inline_genitems(self, *args):
|
||||||
#config = self.parseconfig(*args)
|
#config = self.parseconfig(*args)
|
||||||
from pytest.session import Collection
|
|
||||||
config = self.parseconfigure(*args)
|
config = self.parseconfigure(*args)
|
||||||
rec = self.getreportrecorder(config)
|
rec = self.getreportrecorder(config)
|
||||||
items = Collection(config).perform_collect()
|
items = Collection(config).perform_collect()
|
||||||
|
|
|
@ -660,7 +660,7 @@ class FuncargRequest:
|
||||||
raise self.LookupError(msg)
|
raise self.LookupError(msg)
|
||||||
|
|
||||||
def showfuncargs(config):
|
def showfuncargs(config):
|
||||||
from pytest.session import Collection
|
from pytest.plugin.pytest_session import Collection
|
||||||
collection = Collection(config)
|
collection = Collection(config)
|
||||||
firstid = collection._normalizearg(config.args[0])
|
firstid = collection._normalizearg(config.args[0])
|
||||||
colitem = collection.getbyid(firstid)[0]
|
colitem = collection.getbyid(firstid)[0]
|
||||||
|
|
|
@ -6,25 +6,81 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import py
|
import py
|
||||||
|
import pytest
|
||||||
import os, sys
|
import os, sys
|
||||||
import pytest.config
|
|
||||||
|
|
||||||
#
|
def pytest_addoption(parser):
|
||||||
# main entry point
|
group = parser.getgroup("general", "running and selection options")
|
||||||
#
|
group._addoption('-x', '--exitfirst', action="store_true", default=False,
|
||||||
|
dest="exitfirst",
|
||||||
|
help="exit instantly on first error or failed test."),
|
||||||
|
group._addoption('--maxfail', metavar="num",
|
||||||
|
action="store", type="int", dest="maxfail", default=0,
|
||||||
|
help="exit after first num failures or errors.")
|
||||||
|
|
||||||
|
group = parser.getgroup("collect", "collection")
|
||||||
|
group.addoption('--collectonly',
|
||||||
|
action="store_true", dest="collectonly",
|
||||||
|
help="only collect tests, don't execute them."),
|
||||||
|
group.addoption("--ignore", action="append", metavar="path",
|
||||||
|
help="ignore path during collection (multi-allowed).")
|
||||||
|
group.addoption('--confcutdir', dest="confcutdir", default=None,
|
||||||
|
metavar="dir",
|
||||||
|
help="only load conftest.py's relative to specified dir.")
|
||||||
|
|
||||||
|
group = parser.getgroup("debugconfig",
|
||||||
|
"test process debugging and configuration")
|
||||||
|
group.addoption('--basetemp', dest="basetemp", default=None, metavar="dir",
|
||||||
|
help="base temporary directory for this test run.")
|
||||||
|
|
||||||
|
def pytest_configure(config):
|
||||||
|
# compat
|
||||||
|
if config.getvalue("exitfirst"):
|
||||||
|
config.option.maxfail = 1
|
||||||
|
|
||||||
|
def pytest_cmdline_main(config):
|
||||||
|
return Session(config).main()
|
||||||
|
|
||||||
|
def pytest_perform_collection(session):
|
||||||
|
collection = session.collection
|
||||||
|
assert not hasattr(collection, 'items')
|
||||||
|
hook = session.config.hook
|
||||||
|
collection.items = items = collection.perform_collect()
|
||||||
|
hook.pytest_collection_modifyitems(config=session.config, items=items)
|
||||||
|
hook.pytest_log_finishcollection(collection=collection)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def pytest_runtest_mainloop(session):
|
||||||
|
if session.config.option.collectonly:
|
||||||
|
return True
|
||||||
|
for item in session.collection.items:
|
||||||
|
item.config.hook.pytest_runtest_protocol(item=item)
|
||||||
|
if session.shouldstop:
|
||||||
|
raise session.Interrupted(session.shouldstop)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def pytest_ignore_collect(path, config):
|
||||||
|
p = path.dirpath()
|
||||||
|
ignore_paths = config.getconftest_pathlist("collect_ignore", path=p)
|
||||||
|
ignore_paths = ignore_paths or []
|
||||||
|
excludeopt = config.getvalue("ignore")
|
||||||
|
if excludeopt:
|
||||||
|
ignore_paths.extend([py.path.local(x) for x in excludeopt])
|
||||||
|
return path in ignore_paths
|
||||||
|
|
||||||
|
def pytest_collect_directory(path, parent):
|
||||||
|
if not parent.recfilter(path): # by default special ".cvs", ...
|
||||||
|
# check if cmdline specified this dir or a subdir directly
|
||||||
|
for arg in parent.collection._argfspaths:
|
||||||
|
if path == arg or arg.relto(path):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
return parent.Directory(path, parent=parent)
|
||||||
|
|
||||||
|
def pytest_report_iteminfo(item):
|
||||||
|
return item.reportinfo()
|
||||||
|
|
||||||
def main(args=None):
|
|
||||||
if args is None:
|
|
||||||
args = sys.argv[1:]
|
|
||||||
config = pytest.config.Config()
|
|
||||||
config.parse(args)
|
|
||||||
try:
|
|
||||||
exitstatus = config.hook.pytest_cmdline_main(config=config)
|
|
||||||
except config.Error:
|
|
||||||
e = sys.exc_info()[1]
|
|
||||||
sys.stderr.write("ERROR: %s\n" %(e.args[0],))
|
|
||||||
exitstatus = EXIT_INTERNALERROR
|
|
||||||
return exitstatus
|
|
||||||
|
|
||||||
# exitcodes for the command line
|
# exitcodes for the command line
|
||||||
EXIT_OK = 0
|
EXIT_OK = 0
|
|
@ -3,11 +3,9 @@ managing loading and interacting with pytest plugins.
|
||||||
"""
|
"""
|
||||||
import py
|
import py
|
||||||
import sys
|
import sys
|
||||||
import inspect
|
|
||||||
from pytest.plugin import hookspec
|
|
||||||
|
|
||||||
default_plugins = (
|
default_plugins = (
|
||||||
"default terminal python runner pdb capture mark skipping tmpdir monkeypatch "
|
"session terminal python runner pdb capture mark skipping tmpdir monkeypatch "
|
||||||
"recwarn pastebin unittest helpconfig nose assertion genscript "
|
"recwarn pastebin unittest helpconfig nose assertion genscript "
|
||||||
"junitxml doctest keyword").split()
|
"junitxml doctest keyword").split()
|
||||||
|
|
||||||
|
@ -17,6 +15,7 @@ def check_old_use(mod, modname):
|
||||||
|
|
||||||
class PluginManager(object):
|
class PluginManager(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
from pytest.plugin import hookspec
|
||||||
self.registry = Registry()
|
self.registry = Registry()
|
||||||
self._name2plugin = {}
|
self._name2plugin = {}
|
||||||
self._hints = []
|
self._hints = []
|
||||||
|
@ -275,6 +274,7 @@ class MultiCall:
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def varnames(func):
|
def varnames(func):
|
||||||
|
import inspect
|
||||||
if not inspect.isfunction(func) and not inspect.ismethod(func):
|
if not inspect.isfunction(func) and not inspect.ismethod(func):
|
||||||
func = getattr(func, '__call__', func)
|
func = getattr(func, '__call__', func)
|
||||||
ismethod = inspect.ismethod(func)
|
ismethod = inspect.ismethod(func)
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -26,7 +26,7 @@ def main():
|
||||||
name='pytest',
|
name='pytest',
|
||||||
description='py.test: simple testing with Python',
|
description='py.test: simple testing with Python',
|
||||||
long_description = long_description,
|
long_description = long_description,
|
||||||
version= '1.4.0a1',
|
version= '2.0.0.dev0',
|
||||||
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'],
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
import py
|
|
||||||
from pytest.plugin.pytest_default import pytest_report_iteminfo
|
|
||||||
|
|
||||||
def test_plugin_specify(testdir):
|
|
||||||
testdir.chdir()
|
|
||||||
config = py.test.raises(ImportError, """
|
|
||||||
testdir.parseconfig("-p", "nqweotexistent")
|
|
||||||
""")
|
|
||||||
#py.test.raises(ImportError,
|
|
||||||
# "config.pluginmanager.do_configure(config)"
|
|
||||||
#)
|
|
||||||
|
|
||||||
def test_plugin_already_exists(testdir):
|
|
||||||
config = testdir.parseconfig("-p", "default")
|
|
||||||
assert config.option.plugins == ['default']
|
|
||||||
config.pluginmanager.do_configure(config)
|
|
||||||
|
|
||||||
def test_exclude(testdir):
|
|
||||||
hellodir = testdir.mkdir("hello")
|
|
||||||
hellodir.join("test_hello.py").write("x y syntaxerror")
|
|
||||||
hello2dir = testdir.mkdir("hello2")
|
|
||||||
hello2dir.join("test_hello2.py").write("x y syntaxerror")
|
|
||||||
testdir.makepyfile(test_ok="def test_pass(): pass")
|
|
||||||
result = testdir.runpytest("--ignore=hello", "--ignore=hello2")
|
|
||||||
assert result.ret == 0
|
|
||||||
result.stdout.fnmatch_lines(["*1 passed*"])
|
|
||||||
|
|
||||||
def test_pytest_report_iteminfo():
|
|
||||||
class FakeItem(object):
|
|
||||||
|
|
||||||
def reportinfo(self):
|
|
||||||
return "-reportinfo-"
|
|
||||||
|
|
||||||
res = pytest_report_iteminfo(FakeItem())
|
|
||||||
assert res == "-reportinfo-"
|
|
||||||
|
|
||||||
|
|
||||||
def test_conftest_confcutdir(testdir):
|
|
||||||
testdir.makeconftest("assert 0")
|
|
||||||
x = testdir.mkdir("x")
|
|
||||||
x.join("conftest.py").write(py.code.Source("""
|
|
||||||
def pytest_addoption(parser):
|
|
||||||
parser.addoption("--xyz", action="store_true")
|
|
||||||
"""))
|
|
||||||
result = testdir.runpytest("-h", "--confcutdir=%s" % x, x)
|
|
||||||
result.stdout.fnmatch_lines(["*--xyz*"])
|
|
|
@ -3,9 +3,9 @@ import os
|
||||||
from pytest.plugin.pytest_resultlog import generic_path, ResultLog, \
|
from pytest.plugin.pytest_resultlog import generic_path, ResultLog, \
|
||||||
pytest_configure, pytest_unconfigure
|
pytest_configure, pytest_unconfigure
|
||||||
from pytest.collect import Node, Item, FSCollector
|
from pytest.collect import Node, Item, FSCollector
|
||||||
from pytest.session import Collection
|
|
||||||
|
|
||||||
def test_generic_path(testdir):
|
def test_generic_path(testdir):
|
||||||
|
from pytest.plugin.pytest_session import Collection
|
||||||
config = testdir.parseconfig()
|
config = testdir.parseconfig()
|
||||||
collection = Collection(config)
|
collection = Collection(config)
|
||||||
p1 = Node('a', config=config, collection=collection)
|
p1 = Node('a', config=config, collection=collection)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import py
|
import py
|
||||||
|
from pytest.plugin.pytest_session import pytest_report_iteminfo
|
||||||
|
|
||||||
class SessionTests:
|
class SessionTests:
|
||||||
def test_basic_testitem_events(self, testdir):
|
def test_basic_testitem_events(self, testdir):
|
||||||
|
@ -198,3 +199,36 @@ class TestNewSession(SessionTests):
|
||||||
colfail = [x for x in finished if x.failed]
|
colfail = [x for x in finished if x.failed]
|
||||||
assert len(colfail) == 1
|
assert len(colfail) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_plugin_specify(testdir):
|
||||||
|
testdir.chdir()
|
||||||
|
config = py.test.raises(ImportError, """
|
||||||
|
testdir.parseconfig("-p", "nqweotexistent")
|
||||||
|
""")
|
||||||
|
#py.test.raises(ImportError,
|
||||||
|
# "config.pluginmanager.do_configure(config)"
|
||||||
|
#)
|
||||||
|
|
||||||
|
def test_plugin_already_exists(testdir):
|
||||||
|
config = testdir.parseconfig("-p", "default")
|
||||||
|
assert config.option.plugins == ['default']
|
||||||
|
config.pluginmanager.do_configure(config)
|
||||||
|
|
||||||
|
def test_exclude(testdir):
|
||||||
|
hellodir = testdir.mkdir("hello")
|
||||||
|
hellodir.join("test_hello.py").write("x y syntaxerror")
|
||||||
|
hello2dir = testdir.mkdir("hello2")
|
||||||
|
hello2dir.join("test_hello2.py").write("x y syntaxerror")
|
||||||
|
testdir.makepyfile(test_ok="def test_pass(): pass")
|
||||||
|
result = testdir.runpytest("--ignore=hello", "--ignore=hello2")
|
||||||
|
assert result.ret == 0
|
||||||
|
result.stdout.fnmatch_lines(["*1 passed*"])
|
||||||
|
|
||||||
|
def test_pytest_report_iteminfo():
|
||||||
|
class FakeItem(object):
|
||||||
|
|
||||||
|
def reportinfo(self):
|
||||||
|
return "-reportinfo-"
|
||||||
|
|
||||||
|
res = pytest_report_iteminfo(FakeItem())
|
||||||
|
assert res == "-reportinfo-"
|
|
@ -1,6 +1,6 @@
|
||||||
import py
|
import py
|
||||||
|
|
||||||
from pytest.session import Collection, gettopdir
|
from pytest.plugin.pytest_session import Collection, gettopdir
|
||||||
|
|
||||||
class TestCollection:
|
class TestCollection:
|
||||||
def test_parsearg(self, testdir):
|
def test_parsearg(self, testdir):
|
||||||
|
|
|
@ -176,3 +176,13 @@ def test_setinitial_conftest_subdirs(testdir, name):
|
||||||
else:
|
else:
|
||||||
assert subconftest not in conftest._conftestpath2mod
|
assert subconftest not in conftest._conftestpath2mod
|
||||||
assert len(conftest._conftestpath2mod) == 0
|
assert len(conftest._conftestpath2mod) == 0
|
||||||
|
|
||||||
|
def test_conftest_confcutdir(testdir):
|
||||||
|
testdir.makeconftest("assert 0")
|
||||||
|
x = testdir.mkdir("x")
|
||||||
|
x.join("conftest.py").write(py.code.Source("""
|
||||||
|
def pytest_addoption(parser):
|
||||||
|
parser.addoption("--xyz", action="store_true")
|
||||||
|
"""))
|
||||||
|
result = testdir.runpytest("-h", "--confcutdir=%s" % x, x)
|
||||||
|
result.stdout.fnmatch_lines(["*--xyz*"])
|
||||||
|
|
Loading…
Reference in New Issue