remove yield tests and compat properties

This commit is contained in:
Ronny Pfannschmidt 2018-08-28 10:26:18 +02:00
parent 1d86247b2c
commit 7eb28f9eb7
18 changed files with 29 additions and 691 deletions

View File

@ -0,0 +1 @@
Remove support for yield tests - they are fundamentally broken since collection and test execution were separated.

View File

@ -0,0 +1 @@
Remove the deprecated compat properties for node.Class/Function/Module - use pytest... now.

View File

@ -389,7 +389,6 @@ else:
COLLECT_FAKEMODULE_ATTRIBUTES = ( COLLECT_FAKEMODULE_ATTRIBUTES = (
"Collector", "Collector",
"Module", "Module",
"Generator",
"Function", "Function",
"Instance", "Instance",
"Session", "Session",

View File

@ -22,28 +22,13 @@ MAIN_STR_ARGS = RemovedInPytest4Warning(
"pass a list of arguments instead." "pass a list of arguments instead."
) )
YIELD_TESTS = RemovedInPytest4Warning( YIELD_TESTS = "yield tests were removed in pytest 4.0 - {name} will be ignored"
"yield tests are deprecated, and scheduled to be removed in pytest 4.0"
)
CACHED_SETUP = RemovedInPytest4Warning( CACHED_SETUP = RemovedInPytest4Warning(
"cached_setup is deprecated and will be removed in a future release. " "cached_setup is deprecated and will be removed in a future release. "
"Use standard fixture functions instead." "Use standard fixture functions instead."
) )
COMPAT_PROPERTY = UnformattedWarning(
RemovedInPytest4Warning,
"usage of {owner}.{name} is deprecated, please use pytest.{name} instead",
)
CUSTOM_CLASS = UnformattedWarning(
RemovedInPytest4Warning,
'use of special named "{name}" objects in collectors of type "{type_name}" to '
"customize the created nodes is deprecated. "
"Use pytest_pycollect_makeitem(...) to create custom "
"collection nodes instead.",
)
FUNCARG_PREFIX = UnformattedWarning( FUNCARG_PREFIX = UnformattedWarning(
RemovedInPytest4Warning, RemovedInPytest4Warning,
'{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated ' '{name}: declaring fixtures using "pytest_funcarg__" prefix is deprecated '

View File

@ -1303,17 +1303,11 @@ class FixtureManager(object):
if holderobj in self._holderobjseen: if holderobj in self._holderobjseen:
return return
from _pytest.nodes import _CompatProperty
self._holderobjseen.add(holderobj) self._holderobjseen.add(holderobj)
autousenames = [] autousenames = []
for name in dir(holderobj): for name in dir(holderobj):
# The attribute can be an arbitrary descriptor, so the attribute # The attribute can be an arbitrary descriptor, so the attribute
# access below can raise. safe_getatt() ignores such exceptions. # access below can raise. safe_getatt() ignores such exceptions.
maybe_property = safe_getattr(type(holderobj), name, None)
if isinstance(maybe_property, _CompatProperty):
# deprecated
continue
obj = safe_getattr(holderobj, name, None) obj = safe_getattr(holderobj, name, None)
marker = getfixturemarker(obj) marker = getfixturemarker(obj)
# fixture functions have a pytest_funcarg__ prefix (pre-2.3 style) # fixture functions have a pytest_funcarg__ prefix (pre-2.3 style)

View File

@ -5,7 +5,6 @@ from __future__ import print_function
import os import os
import warnings import warnings
import attr
import py import py
import six import six
@ -56,22 +55,6 @@ def ischildnode(baseid, nodeid):
return node_parts[: len(base_parts)] == base_parts return node_parts[: len(base_parts)] == base_parts
@attr.s
class _CompatProperty(object):
name = attr.ib()
def __get__(self, obj, owner):
if obj is None:
return self
from _pytest.deprecated import COMPAT_PROPERTY
warnings.warn(
COMPAT_PROPERTY.format(name=self.name, owner=owner.__name__), stacklevel=2
)
return getattr(__import__("pytest"), self.name)
class Node(object): class Node(object):
""" base class for Collector and Item the test collection tree. """ base class for Collector and Item the test collection tree.
Collector subclasses have children, Items are terminal nodes.""" Collector subclasses have children, Items are terminal nodes."""
@ -119,24 +102,6 @@ class Node(object):
""" fspath sensitive hook proxy used to call pytest hooks""" """ fspath sensitive hook proxy used to call pytest hooks"""
return self.session.gethookproxy(self.fspath) return self.session.gethookproxy(self.fspath)
Module = _CompatProperty("Module")
Class = _CompatProperty("Class")
Instance = _CompatProperty("Instance")
Function = _CompatProperty("Function")
File = _CompatProperty("File")
Item = _CompatProperty("Item")
def _getcustomclass(self, name):
maybe_compatprop = getattr(type(self), name)
if isinstance(maybe_compatprop, _CompatProperty):
return getattr(__import__("pytest"), name)
else:
from _pytest.deprecated import CUSTOM_CLASS
cls = getattr(self, name)
self.warn(CUSTOM_CLASS.format(name=name, type_name=type(self).__name__))
return cls
def __repr__(self): def __repr__(self):
return "<%s %s>" % (self.__class__.__name__, getattr(self, "name", None)) return "<%s %s>" % (self.__class__.__name__, getattr(self, "name", None))

View File

@ -30,13 +30,6 @@ def pytest_runtest_makereport(item, call):
@hookimpl(trylast=True) @hookimpl(trylast=True)
def pytest_runtest_setup(item): def pytest_runtest_setup(item):
if is_potential_nosetest(item): if is_potential_nosetest(item):
if isinstance(item.parent, python.Generator):
gen = item.parent
if not hasattr(gen, "_nosegensetup"):
call_optional(gen.obj, "setup")
if isinstance(gen.parent, python.Instance):
call_optional(gen.parent.obj, "setup")
gen._nosegensetup = True
if not call_optional(item.obj, "setup"): if not call_optional(item.obj, "setup"):
# call module level setup if there is no object level one # call module level setup if there is no object level one
call_optional(item.parent.obj, "setup") call_optional(item.parent.obj, "setup")
@ -53,11 +46,6 @@ def teardown_nose(item):
# del item.parent._nosegensetup # del item.parent._nosegensetup
def pytest_make_collect_report(collector):
if isinstance(collector, python.Generator):
call_optional(collector.obj, "setup")
def is_potential_nosetest(item): def is_potential_nosetest(item):
# extra check needed since we do not do nose style setup/teardown # extra check needed since we do not do nose style setup/teardown
# on direct unittest style classes # on direct unittest style classes

View File

@ -38,6 +38,7 @@ from _pytest.compat import safe_str
from _pytest.compat import STRING_TYPES from _pytest.compat import STRING_TYPES
from _pytest.config import hookimpl from _pytest.config import hookimpl
from _pytest.main import FSHookProxy from _pytest.main import FSHookProxy
from _pytest.mark import MARK_GEN
from _pytest.mark.structures import get_unpacked_marks from _pytest.mark.structures import get_unpacked_marks
from _pytest.mark.structures import normalize_mark_list from _pytest.mark.structures import normalize_mark_list
from _pytest.mark.structures import transfer_markers from _pytest.mark.structures import transfer_markers
@ -199,7 +200,6 @@ def pytest_pycollect_makeitem(collector, name, obj):
# nothing was collected elsewhere, let's do it here # nothing was collected elsewhere, let's do it here
if safe_isclass(obj): if safe_isclass(obj):
if collector.istestclass(obj, name): if collector.istestclass(obj, name):
Class = collector._getcustomclass("Class")
outcome.force_result(Class(name, parent=collector)) outcome.force_result(Class(name, parent=collector))
elif collector.istestfunction(obj, name): elif collector.istestfunction(obj, name):
# mock seems to store unbound methods (issue473), normalize it # mock seems to store unbound methods (issue473), normalize it
@ -219,7 +219,10 @@ def pytest_pycollect_makeitem(collector, name, obj):
) )
elif getattr(obj, "__test__", True): elif getattr(obj, "__test__", True):
if is_generator(obj): if is_generator(obj):
res = Generator(name, parent=collector) res = Function(name, parent=collector)
reason = deprecated.YIELD_TESTS.format(name=name)
res.add_marker(MARK_GEN.xfail(run=False, reason=reason))
res.warn(PytestWarning(reason))
else: else:
res = list(collector._genfunctions(name, obj)) res = list(collector._genfunctions(name, obj))
outcome.force_result(res) outcome.force_result(res)
@ -408,7 +411,6 @@ class PyCollector(PyobjMixin, nodes.Collector):
else: else:
self.ihook.pytest_generate_tests(metafunc=metafunc) self.ihook.pytest_generate_tests(metafunc=metafunc)
Function = self._getcustomclass("Function")
if not metafunc._calls: if not metafunc._calls:
yield Function(name, parent=self, fixtureinfo=fixtureinfo) yield Function(name, parent=self, fixtureinfo=fixtureinfo)
else: else:
@ -648,7 +650,7 @@ class Class(PyCollector):
) )
) )
return [] return []
return [self._getcustomclass("Instance")(name="()", parent=self)] return [Instance(name="()", parent=self)]
def setup(self): def setup(self):
setup_class = _get_xunit_func(self.obj, "setup_class") setup_class = _get_xunit_func(self.obj, "setup_class")
@ -739,51 +741,6 @@ class FunctionMixin(PyobjMixin):
return self._repr_failure_py(excinfo, style=style) return self._repr_failure_py(excinfo, style=style)
class Generator(FunctionMixin, PyCollector):
def collect(self):
# test generators are seen as collectors but they also
# invoke setup/teardown on popular request
# (induced by the common "test_*" naming shared with normal tests)
from _pytest import deprecated
self.warn(deprecated.YIELD_TESTS)
self.session._setupstate.prepare(self)
# see FunctionMixin.setup and test_setupstate_is_preserved_134
self._preservedparent = self.parent.obj
values = []
seen = {}
_Function = self._getcustomclass("Function")
for i, x in enumerate(self.obj()):
name, call, args = self.getcallargs(x)
if not callable(call):
raise TypeError("%r yielded non callable test %r" % (self.obj, call))
if name is None:
name = "[%d]" % i
else:
name = "['%s']" % name
if name in seen:
raise ValueError(
"%r generated tests with non-unique name %r" % (self, name)
)
seen[name] = True
values.append(_Function(name, self, args=args, callobj=call))
return values
def getcallargs(self, obj):
if not isinstance(obj, (tuple, list)):
obj = (obj,)
# explicit naming
if isinstance(obj[0], six.string_types):
name = obj[0]
obj = obj[1:]
else:
name = None
call, args = obj[0], obj[1:]
return name, call, args
def hasinit(obj): def hasinit(obj):
init = getattr(obj, "__init__", None) init = getattr(obj, "__init__", None)
if init: if init:
@ -1326,8 +1283,7 @@ def _showfixtures_main(config, session):
tw.line(" %s: no docstring available" % (loc,), red=True) tw.line(" %s: no docstring available" % (loc,), red=True)
def write_docstring(tw, doc): def write_docstring(tw, doc, indent=" "):
INDENT = " "
doc = doc.rstrip() doc = doc.rstrip()
if "\n" in doc: if "\n" in doc:
firstline, rest = doc.split("\n", 1) firstline, rest = doc.split("\n", 1)
@ -1335,11 +1291,11 @@ def write_docstring(tw, doc):
firstline, rest = doc, "" firstline, rest = doc, ""
if firstline.strip(): if firstline.strip():
tw.line(INDENT + firstline.strip()) tw.line(indent + firstline.strip())
if rest: if rest:
for line in dedent(rest).split("\n"): for line in dedent(rest).split("\n"):
tw.write(INDENT + line + "\n") tw.write(indent + line + "\n")
class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr): class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):

View File

@ -28,7 +28,6 @@ from _pytest.outcomes import skip
from _pytest.outcomes import xfail from _pytest.outcomes import xfail
from _pytest.python import Class from _pytest.python import Class
from _pytest.python import Function from _pytest.python import Function
from _pytest.python import Generator
from _pytest.python import Instance from _pytest.python import Instance
from _pytest.python import Module from _pytest.python import Module
from _pytest.python import Package from _pytest.python import Package
@ -57,7 +56,6 @@ __all__ = [
"fixture", "fixture",
"freeze_includes", "freeze_includes",
"Function", "Function",
"Generator",
"hookimpl", "hookimpl",
"hookspec", "hookspec",
"importorskip", "importorskip",

View File

@ -10,47 +10,6 @@ from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
pytestmark = pytest.mark.pytester_example_path("deprecated") pytestmark = pytest.mark.pytester_example_path("deprecated")
def test_yield_tests_deprecation(testdir):
testdir.makepyfile(
"""
def func1(arg, arg2):
assert arg == arg2
def test_gen():
yield "m1", func1, 15, 3*5
yield "m2", func1, 42, 6*7
def test_gen2():
for k in range(10):
yield func1, 1, 1
"""
)
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(
[
"*test_yield_tests_deprecation.py:3:*yield tests are deprecated*",
"*test_yield_tests_deprecation.py:6:*yield tests are deprecated*",
"*2 passed*",
]
)
assert result.stdout.str().count("yield tests are deprecated") == 2
def test_compat_properties_deprecation(testdir):
testdir.makepyfile(
"""
def test_foo(request):
print(request.node.Module)
"""
)
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(
[
"*test_compat_properties_deprecation.py:2:*usage of Function.Module is deprecated, "
"please use pytest.Module instead*",
"*1 passed, 1 warnings in*",
]
)
def test_cached_setup_deprecation(testdir): def test_cached_setup_deprecation(testdir):
testdir.makepyfile( testdir.makepyfile(
""" """
@ -72,36 +31,6 @@ def test_cached_setup_deprecation(testdir):
) )
def test_custom_class_deprecation(testdir):
testdir.makeconftest(
"""
import pytest
class MyModule(pytest.Module):
class Class(pytest.Class):
pass
def pytest_pycollect_makemodule(path, parent):
return MyModule(path, parent)
"""
)
testdir.makepyfile(
"""
class Test:
def test_foo(self):
pass
"""
)
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(
[
'*test_custom_class_deprecation.py:1:*"Class" objects in collectors of type "MyModule*',
"*1 passed, 1 warnings in*",
]
)
def test_funcarg_prefix_deprecation(testdir): def test_funcarg_prefix_deprecation(testdir):
testdir.makepyfile( testdir.makepyfile(
""" """

View File

@ -7,7 +7,6 @@ import _pytest._code
import pytest import pytest
from _pytest.main import EXIT_NOTESTSCOLLECTED from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.nodes import Collector from _pytest.nodes import Collector
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
class TestModule(object): class TestModule(object):
@ -244,217 +243,6 @@ class TestClass(object):
@pytest.mark.filterwarnings( @pytest.mark.filterwarnings(
"ignore:usage of Generator.Function is deprecated, please use pytest.Function instead" "ignore:usage of Generator.Function is deprecated, please use pytest.Function instead"
) )
class TestGenerator(object):
def test_generative_functions(self, testdir):
modcol = testdir.getmodulecol(
"""
def func1(arg, arg2):
assert arg == arg2
def test_gen():
yield func1, 17, 3*5
yield func1, 42, 6*7
"""
)
colitems = modcol.collect()
assert len(colitems) == 1
gencol = colitems[0]
assert isinstance(gencol, pytest.Generator)
gencolitems = gencol.collect()
assert len(gencolitems) == 2
assert isinstance(gencolitems[0], pytest.Function)
assert isinstance(gencolitems[1], pytest.Function)
assert gencolitems[0].name == "[0]"
assert gencolitems[0].obj.__name__ == "func1"
def test_generative_methods(self, testdir):
modcol = testdir.getmodulecol(
"""
def func1(arg, arg2):
assert arg == arg2
class TestGenMethods(object):
def test_gen(self):
yield func1, 17, 3*5
yield func1, 42, 6*7
"""
)
gencol = modcol.collect()[0].collect()[0].collect()[0]
assert isinstance(gencol, pytest.Generator)
gencolitems = gencol.collect()
assert len(gencolitems) == 2
assert isinstance(gencolitems[0], pytest.Function)
assert isinstance(gencolitems[1], pytest.Function)
assert gencolitems[0].name == "[0]"
assert gencolitems[0].obj.__name__ == "func1"
def test_generative_functions_with_explicit_names(self, testdir):
modcol = testdir.getmodulecol(
"""
def func1(arg, arg2):
assert arg == arg2
def test_gen():
yield "seventeen", func1, 17, 3*5
yield "fortytwo", func1, 42, 6*7
"""
)
colitems = modcol.collect()
assert len(colitems) == 1
gencol = colitems[0]
assert isinstance(gencol, pytest.Generator)
gencolitems = gencol.collect()
assert len(gencolitems) == 2
assert isinstance(gencolitems[0], pytest.Function)
assert isinstance(gencolitems[1], pytest.Function)
assert gencolitems[0].name == "['seventeen']"
assert gencolitems[0].obj.__name__ == "func1"
assert gencolitems[1].name == "['fortytwo']"
assert gencolitems[1].obj.__name__ == "func1"
def test_generative_functions_unique_explicit_names(self, testdir):
# generative
modcol = testdir.getmodulecol(
"""
def func(): pass
def test_gen():
yield "name", func
yield "name", func
"""
)
colitems = modcol.collect()
assert len(colitems) == 1
gencol = colitems[0]
assert isinstance(gencol, pytest.Generator)
pytest.raises(ValueError, gencol.collect)
def test_generative_methods_with_explicit_names(self, testdir):
modcol = testdir.getmodulecol(
"""
def func1(arg, arg2):
assert arg == arg2
class TestGenMethods(object):
def test_gen(self):
yield "m1", func1, 17, 3*5
yield "m2", func1, 42, 6*7
"""
)
gencol = modcol.collect()[0].collect()[0].collect()[0]
assert isinstance(gencol, pytest.Generator)
gencolitems = gencol.collect()
assert len(gencolitems) == 2
assert isinstance(gencolitems[0], pytest.Function)
assert isinstance(gencolitems[1], pytest.Function)
assert gencolitems[0].name == "['m1']"
assert gencolitems[0].obj.__name__ == "func1"
assert gencolitems[1].name == "['m2']"
assert gencolitems[1].obj.__name__ == "func1"
def test_order_of_execution_generator_same_codeline(self, testdir, tmpdir):
o = testdir.makepyfile(
"""
from __future__ import print_function
def test_generative_order_of_execution():
import py, pytest
test_list = []
expected_list = list(range(6))
def list_append(item):
test_list.append(item)
def assert_order_of_execution():
print('expected order', expected_list)
print('but got ', test_list)
assert test_list == expected_list
for i in expected_list:
yield list_append, i
yield assert_order_of_execution
"""
)
reprec = testdir.inline_run(o, SHOW_PYTEST_WARNINGS_ARG)
passed, skipped, failed = reprec.countoutcomes()
assert passed == 7
assert not skipped and not failed
def test_order_of_execution_generator_different_codeline(self, testdir):
o = testdir.makepyfile(
"""
from __future__ import print_function
def test_generative_tests_different_codeline():
import py, pytest
test_list = []
expected_list = list(range(3))
def list_append_2():
test_list.append(2)
def list_append_1():
test_list.append(1)
def list_append_0():
test_list.append(0)
def assert_order_of_execution():
print('expected order', expected_list)
print('but got ', test_list)
assert test_list == expected_list
yield list_append_0
yield list_append_1
yield list_append_2
yield assert_order_of_execution
"""
)
reprec = testdir.inline_run(o, SHOW_PYTEST_WARNINGS_ARG)
passed, skipped, failed = reprec.countoutcomes()
assert passed == 4
assert not skipped and not failed
def test_setupstate_is_preserved_134(self, testdir):
# yield-based tests are messy wrt to setupstate because
# during collection they already invoke setup functions
# and then again when they are run. For now, we want to make sure
# that the old 1.3.4 behaviour is preserved such that all
# yielded functions all share the same "self" instance that
# has been used during collection.
o = testdir.makepyfile(
"""
setuplist = []
class TestClass(object):
def setup_method(self, func):
#print "setup_method", self, func
setuplist.append(self)
self.init = 42
def teardown_method(self, func):
self.init = None
def test_func1(self):
pass
def test_func2(self):
yield self.func2
yield self.func2
def func2(self):
assert self.init
def test_setuplist():
# once for test_func2 during collection
# once for test_func1 during test run
# once for test_func2 during test run
#print setuplist
assert len(setuplist) == 3, len(setuplist)
assert setuplist[0] == setuplist[2], setuplist
assert setuplist[1] != setuplist[2], setuplist
"""
)
reprec = testdir.inline_run(o, "-v", SHOW_PYTEST_WARNINGS_ARG)
passed, skipped, failed = reprec.countoutcomes()
assert passed == 4
assert not skipped and not failed
class TestFunction(object): class TestFunction(object):
@pytest.fixture @pytest.fixture
def ignore_parametrized_marks_args(self): def ignore_parametrized_marks_args(self):
@ -1271,39 +1059,6 @@ class TestReportInfo(object):
@pytest.mark.filterwarnings( @pytest.mark.filterwarnings(
"ignore:usage of Generator.Function is deprecated, please use pytest.Function instead" "ignore:usage of Generator.Function is deprecated, please use pytest.Function instead"
) )
def test_generator_reportinfo(self, testdir):
modcol = testdir.getmodulecol(
"""
# lineno 0
def test_gen():
def check(x):
assert x
yield check, 3
"""
)
gencol = testdir.collect_by_name(modcol, "test_gen")
fspath, lineno, modpath = gencol.reportinfo()
assert fspath == modcol.fspath
assert lineno == 1
assert modpath == "test_gen"
genitem = gencol.collect()[0]
fspath, lineno, modpath = genitem.reportinfo()
assert fspath == modcol.fspath
assert lineno == 2
assert modpath == "test_gen[0]"
"""
def test_func():
pass
def test_genfunc():
def check(x):
pass
yield check, 3
class TestClass(object):
def test_method(self):
pass
"""
def test_reportinfo_with_nasty_getattr(self, testdir): def test_reportinfo_with_nasty_getattr(self, testdir):
# https://github.com/pytest-dev/pytest/issues/1204 # https://github.com/pytest-dev/pytest/issues/1204
modcol = testdir.getmodulecol( modcol = testdir.getmodulecol(
@ -1373,54 +1128,6 @@ def test_customized_python_discovery_functions(testdir):
result.stdout.fnmatch_lines(["*1 passed*"]) result.stdout.fnmatch_lines(["*1 passed*"])
def test_collector_attributes(testdir):
testdir.makeconftest(
"""
import pytest
def pytest_pycollect_makeitem(collector):
assert collector.Function == pytest.Function
assert collector.Class == pytest.Class
assert collector.Instance == pytest.Instance
assert collector.Module == pytest.Module
"""
)
testdir.makepyfile(
"""
def test_hello():
pass
"""
)
result = testdir.runpytest(SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(["*1 passed*"])
def test_customize_through_attributes(testdir):
testdir.makeconftest(
"""
import pytest
class MyFunction(pytest.Function):
pass
class MyInstance(pytest.Instance):
Function = MyFunction
class MyClass(pytest.Class):
Instance = MyInstance
def pytest_pycollect_makeitem(collector, name, obj):
if name.startswith("MyTestClass"):
return MyClass(name, parent=collector)
"""
)
testdir.makepyfile(
"""
class MyTestClass(object):
def test_hello(self):
pass
"""
)
result = testdir.runpytest("--collect-only", SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(["*MyClass*", "*MyFunction*test_hello*"])
def test_unorderable_types(testdir): def test_unorderable_types(testdir):
testdir.makepyfile( testdir.makepyfile(
""" """

View File

@ -1850,24 +1850,6 @@ class TestAutouseManagement(object):
reprec = testdir.inline_run("-s") reprec = testdir.inline_run("-s")
reprec.assertoutcome(passed=1) reprec.assertoutcome(passed=1)
def test_autouse_honored_for_yield(self, testdir):
testdir.makepyfile(
"""
import pytest
@pytest.fixture(autouse=True)
def tst():
global x
x = 3
def test_gen():
def f(hello):
assert x == abs(hello)
yield f, 3
yield f, -3
"""
)
reprec = testdir.inline_run(SHOW_PYTEST_WARNINGS_ARG)
reprec.assertoutcome(passed=2)
def test_funcarg_and_setup(self, testdir): def test_funcarg_and_setup(self, testdir):
testdir.makepyfile( testdir.makepyfile(
""" """

View File

@ -21,20 +21,6 @@ class TestCollector(object):
assert not issubclass(Collector, Item) assert not issubclass(Collector, Item)
assert not issubclass(Item, Collector) assert not issubclass(Item, Collector)
def test_compat_attributes(self, testdir, recwarn):
modcol = testdir.getmodulecol(
"""
def test_pass(): pass
def test_fail(): assert 0
"""
)
recwarn.clear()
assert modcol.Module == pytest.Module
assert modcol.Class == pytest.Class
assert modcol.Item == pytest.Item
assert modcol.File == pytest.File
assert modcol.Function == pytest.Function
def test_check_equality(self, testdir): def test_check_equality(self, testdir):
modcol = testdir.getmodulecol( modcol = testdir.getmodulecol(
""" """

View File

@ -3,7 +3,6 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import pytest import pytest
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
def setup_module(mod): def setup_module(mod):
@ -162,73 +161,6 @@ def test_nose_setup_partial(testdir):
result.stdout.fnmatch_lines(["*2 passed*"]) result.stdout.fnmatch_lines(["*2 passed*"])
def test_nose_test_generator_fixtures(testdir):
p = testdir.makepyfile(
"""
# taken from nose-0.11.1 unit_tests/test_generator_fixtures.py
from nose.tools import eq_
called = []
def outer_setup():
called.append('outer_setup')
def outer_teardown():
called.append('outer_teardown')
def inner_setup():
called.append('inner_setup')
def inner_teardown():
called.append('inner_teardown')
def test_gen():
called[:] = []
for i in range(0, 5):
yield check, i
def check(i):
expect = ['outer_setup']
for x in range(0, i):
expect.append('inner_setup')
expect.append('inner_teardown')
expect.append('inner_setup')
eq_(called, expect)
test_gen.setup = outer_setup
test_gen.teardown = outer_teardown
check.setup = inner_setup
check.teardown = inner_teardown
class TestClass(object):
def setup(self):
print("setup called in %s" % self)
self.called = ['setup']
def teardown(self):
print("teardown called in %s" % self)
eq_(self.called, ['setup'])
self.called.append('teardown')
def test(self):
print("test called in %s" % self)
for i in range(0, 5):
yield self.check, i
def check(self, i):
print("check called in %s" % self)
expect = ['setup']
#for x in range(0, i):
# expect.append('setup')
# expect.append('teardown')
#expect.append('setup')
eq_(self.called, expect)
"""
)
result = testdir.runpytest(p, "-p", "nose", SHOW_PYTEST_WARNINGS_ARG)
result.stdout.fnmatch_lines(["*10 passed*"])
def test_module_level_setup(testdir): def test_module_level_setup(testdir):
testdir.makepyfile( testdir.makepyfile(
""" """

View File

@ -8,7 +8,6 @@ import sys
import _pytest._code import _pytest._code
import pytest import pytest
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
try: try:
breakpoint breakpoint
@ -809,27 +808,6 @@ class TestTraceOption:
assert "reading from stdin while output" not in rest assert "reading from stdin while output" not in rest
TestPDB.flush(child) TestPDB.flush(child)
def test_trace_against_yield_test(self, testdir):
p1 = testdir.makepyfile(
"""
def is_equal(a, b):
assert a == b
def test_1():
yield is_equal, 1, 1
"""
)
child = testdir.spawn_pytest(
"{} --trace {}".format(SHOW_PYTEST_WARNINGS_ARG, str(p1))
)
child.expect("is_equal")
child.expect("Pdb")
child.sendeof()
rest = child.read().decode("utf8")
assert "1 passed" in rest
assert "reading from stdin while output" not in rest
TestPDB.flush(child)
def test_trace_after_runpytest(testdir): def test_trace_after_runpytest(testdir):
"""Test that debugging's pytest_configure is re-entrant.""" """Test that debugging's pytest_configure is re-entrant."""

View File

@ -7,7 +7,6 @@ from __future__ import division
from __future__ import print_function from __future__ import print_function
import pytest import pytest
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
def test_module_and_function_setup(testdir): def test_module_and_function_setup(testdir):
@ -170,64 +169,6 @@ def test_method_setup_failure_no_teardown(testdir):
reprec.assertoutcome(failed=1, passed=1) reprec.assertoutcome(failed=1, passed=1)
def test_method_generator_setup(testdir):
reprec = testdir.inline_runsource(
"""
class TestSetupTeardownOnInstance(object):
def setup_class(cls):
cls.classsetup = True
def setup_method(self, method):
self.methsetup = method
def test_generate(self):
assert self.classsetup
assert self.methsetup == self.test_generate
yield self.generated, 5
yield self.generated, 2
def generated(self, value):
assert self.classsetup
assert self.methsetup == self.test_generate
assert value == 5
""",
SHOW_PYTEST_WARNINGS_ARG,
)
reprec.assertoutcome(passed=1, failed=1)
def test_func_generator_setup(testdir):
reprec = testdir.inline_runsource(
"""
import sys
def setup_module(mod):
print("setup_module")
mod.x = []
def setup_function(fun):
print("setup_function")
x.append(1)
def teardown_function(fun):
print("teardown_function")
x.pop()
def test_one():
assert x == [1]
def check():
print("check")
sys.stderr.write("e\\n")
assert x == [1]
yield check
assert x == [1]
""",
SHOW_PYTEST_WARNINGS_ARG,
)
rep = reprec.matchreport("test_one", names="pytest_runtest_logreport")
assert rep.passed
def test_method_setup_uses_fresh_instances(testdir): def test_method_setup_uses_fresh_instances(testdir):
reprec = testdir.inline_runsource( reprec = testdir.inline_runsource(
""" """

View File

@ -4,7 +4,6 @@ from __future__ import print_function
import pytest import pytest
from _pytest.main import EXIT_NOTESTSCOLLECTED from _pytest.main import EXIT_NOTESTSCOLLECTED
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
class SessionTests(object): class SessionTests(object):
@ -73,19 +72,6 @@ class SessionTests(object):
print(out) print(out)
pytest.fail("incorrect raises() output") pytest.fail("incorrect raises() output")
def test_generator_yields_None(self, testdir):
reprec = testdir.inline_runsource(
"""
def test_1():
yield None
""",
SHOW_PYTEST_WARNINGS_ARG,
)
failures = reprec.getfailedcollections()
out = failures[0].longrepr.reprcrash.message
i = out.find("TypeError")
assert i != -1
def test_syntax_error_module(self, testdir): def test_syntax_error_module(self, testdir):
reprec = testdir.inline_runsource("this is really not python") reprec = testdir.inline_runsource("this is really not python")
values = reprec.getfailedcollections() values = reprec.getfailedcollections()

View File

@ -20,7 +20,6 @@ from _pytest.terminal import build_summary_stats_line
from _pytest.terminal import getreportopt from _pytest.terminal import getreportopt
from _pytest.terminal import repr_pythonversion from _pytest.terminal import repr_pythonversion
from _pytest.terminal import TerminalReporter from _pytest.terminal import TerminalReporter
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
DistInfo = collections.namedtuple("DistInfo", ["project_name", "version"]) DistInfo = collections.namedtuple("DistInfo", ["project_name", "version"])
@ -585,8 +584,9 @@ class TestTerminalFunctional(object):
] ]
) )
def test_verbose_reporting(self, testdir, pytestconfig): @pytest.fixture
p1 = testdir.makepyfile( def verbose_testfile(self, testdir):
return testdir.makepyfile(
""" """
import pytest import pytest
def test_fail(): def test_fail():
@ -602,22 +602,32 @@ class TestTerminalFunctional(object):
yield check, 0 yield check, 0
""" """
) )
result = testdir.runpytest(p1, "-v", SHOW_PYTEST_WARNINGS_ARG)
def test_verbose_reporting(self, verbose_testfile, testdir, pytestconfig):
result = testdir.runpytest(
verbose_testfile, "-v", "-Walways::pytest.PytestWarning"
)
result.stdout.fnmatch_lines( result.stdout.fnmatch_lines(
[ [
"*test_verbose_reporting.py::test_fail *FAIL*", "*test_verbose_reporting.py::test_fail *FAIL*",
"*test_verbose_reporting.py::test_pass *PASS*", "*test_verbose_reporting.py::test_pass *PASS*",
"*test_verbose_reporting.py::TestClass::test_skip *SKIP*", "*test_verbose_reporting.py::TestClass::test_skip *SKIP*",
"*test_verbose_reporting.py::test_gen*0* *FAIL*", "*test_verbose_reporting.py::test_gen *xfail*",
] ]
) )
assert result.ret == 1 assert result.ret == 1
def test_verbose_reporting_xdist(self, verbose_testfile, testdir, pytestconfig):
if not pytestconfig.pluginmanager.get_plugin("xdist"): if not pytestconfig.pluginmanager.get_plugin("xdist"):
pytest.skip("xdist plugin not installed") pytest.skip("xdist plugin not installed")
result = testdir.runpytest(p1, "-v", "-n 1", SHOW_PYTEST_WARNINGS_ARG) result = testdir.runpytest(
result.stdout.fnmatch_lines(["*FAIL*test_verbose_reporting.py::test_fail*"]) verbose_testfile, "-v", "-n 1", "-Walways::pytest.PytestWarning"
)
result.stdout.fnmatch_lines(
["*FAIL*test_verbose_reporting_xdist.py::test_fail*"]
)
assert result.ret == 1 assert result.ret == 1
def test_quiet_reporting(self, testdir): def test_quiet_reporting(self, testdir):