From commits-noreply at bitbucket.org Fri Nov 2 16:17:47 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 02 Nov 2012 15:17:47 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20121102151747.25694.74322@bitbucket02.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/aadd426bdd8c/ changeset: aadd426bdd8c user: hpk42 date: 2012-11-02 16:04:56 summary: remove unused code affected #: 1 file diff -r a751a14ccfb360f4f72ab138d5a9647e89213a82 -r aadd426bdd8ca896314b29f1802fae58b7684cea _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1286,12 +1286,6 @@ def scopemismatch(currentscope, newscope): return scopes.index(newscope) > scopes.index(currentscope) -def slice_kwargs(names, kwargs): - new_kwargs = {} - for name in names: - new_kwargs[name] = kwargs[name] - return new_kwargs - class FixtureLookupError(LookupError): """ could not return a requested Fixture (missing or invalid). """ def __init__(self, argname, request, msg=None): https://bitbucket.org/hpk42/pytest/changeset/62026bb7a7f3/ changeset: 62026bb7a7f3 user: hpk42 date: 2012-11-02 16:04:57 summary: fix issue215 - refactor test_python.py into multiple files: - python/collect.py cotaining the core collection nodes - python/fixture.py containing funcargs/fixture code - python/metafunc.py generate_tests and metafunc usage - python/raises.py the pytest.raises implementation affected #: 7 files diff -r aadd426bdd8ca896314b29f1802fae58b7684cea -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -4,9 +4,12 @@ - fix issue214 - parse modules that contain special objects like e. g. flask's request object which blows up on getattr access if no request is active. + - fix issue213 - allow to parametrize with values like numpy arrays that do not support an __eq__ operator +- fix issue215 - split test_python.org into multiple files + Changes between 2.3.1 and 2.3.2 ----------------------------------- diff -r aadd426bdd8ca896314b29f1802fae58b7684cea -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c testing/python/collect.py --- /dev/null +++ b/testing/python/collect.py @@ -0,0 +1,721 @@ +import pytest, py, sys +from _pytest import python as funcargs +from _pytest.python import FixtureLookupError + +class TestModule: + def test_failing_import(self, testdir): + modcol = testdir.getmodulecol("import alksdjalskdjalkjals") + pytest.raises(ImportError, modcol.collect) + pytest.raises(ImportError, modcol.collect) + + def test_import_duplicate(self, testdir): + a = testdir.mkdir("a") + b = testdir.mkdir("b") + p = a.ensure("test_whatever.py") + p.pyimport() + del py.std.sys.modules['test_whatever'] + b.ensure("test_whatever.py") + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*import*mismatch*", + "*imported*test_whatever*", + "*%s*" % a.join("test_whatever.py"), + "*not the same*", + "*%s*" % b.join("test_whatever.py"), + "*HINT*", + ]) + + def test_syntax_error_in_module(self, testdir): + modcol = testdir.getmodulecol("this is a syntax error") + pytest.raises(modcol.CollectError, modcol.collect) + pytest.raises(modcol.CollectError, modcol.collect) + + def test_module_considers_pluginmanager_at_import(self, testdir): + modcol = testdir.getmodulecol("pytest_plugins='xasdlkj',") + pytest.raises(ImportError, "modcol.obj") + +class TestClass: + def test_class_with_init_not_collected(self, testdir): + modcol = testdir.getmodulecol(""" + class TestClass1: + def __init__(self): + pass + class TestClass2(object): + def __init__(self): + pass + """) + l = modcol.collect() + assert len(l) == 0 + + def test_class_subclassobject(self, testdir): + testdir.getmodulecol(""" + class test(object): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*collected 0*", + ]) + + def test_setup_teardown_class_as_classmethod(self, testdir): + testdir.makepyfile(test_mod1=""" + class TestClassMethod: + @classmethod + def setup_class(cls): + pass + def test_1(self): + pass + @classmethod + def teardown_class(cls): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*1 passed*", + ]) + + +class TestGenerator: + 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: + 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: + 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(""" + 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(): + py.builtin.print_('expected order', expected_list) + py.builtin.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) + 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(""" + 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(): + py.builtin.print_('expected order', expected_list) + py.builtin.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) + 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: + 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') + passed, skipped, failed = reprec.countoutcomes() + assert passed == 4 + assert not skipped and not failed + + +class TestFunction: + def test_getmodulecollector(self, testdir): + item = testdir.getitem("def test_func(): pass") + modcol = item.getparent(pytest.Module) + assert isinstance(modcol, pytest.Module) + assert hasattr(modcol.obj, 'test_func') + + def test_function_equality(self, testdir, tmpdir): + from _pytest.python import FixtureManager + config = testdir.parseconfigure() + session = testdir.Session(config) + session._fixturemanager = FixtureManager(session) + def func1(): + pass + def func2(): + pass + f1 = pytest.Function(name="name", parent=session, config=config, + args=(1,), callobj=func1) + f2 = pytest.Function(name="name",config=config, + args=(1,), callobj=func2, parent=session) + assert not f1 == f2 + assert f1 != f2 + f3 = pytest.Function(name="name", parent=session, config=config, + args=(1,2), callobj=func2) + assert not f3 == f2 + assert f3 != f2 + + assert not f3 == f1 + assert f3 != f1 + + f1_b = pytest.Function(name="name", parent=session, config=config, + args=(1,), callobj=func1) + assert f1 == f1_b + assert not f1 != f1_b + + def test_issue197_parametrize_emptyset(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.mark.parametrize('arg', []) + def test_function(arg): + pass + """) + reprec = testdir.inline_run() + reprec.assertoutcome(skipped=1) + + def test_issue213_parametrize_value_no_equal(self, testdir): + testdir.makepyfile(""" + import pytest + class A: + def __eq__(self, other): + raise ValueError("not possible") + @pytest.mark.parametrize('arg', [A()]) + def test_function(arg): + assert arg.__class__.__name__ == "A" + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_function_equality_with_callspec(self, testdir, tmpdir): + items = testdir.getitems(""" + import pytest + @pytest.mark.parametrize('arg', [1,2]) + def test_function(arg): + pass + """) + assert items[0] != items[1] + assert not (items[0] == items[1]) + + def test_pyfunc_call(self, testdir): + item = testdir.getitem("def test_func(): raise ValueError") + config = item.config + class MyPlugin1: + def pytest_pyfunc_call(self, pyfuncitem): + raise ValueError + class MyPlugin2: + def pytest_pyfunc_call(self, pyfuncitem): + return True + config.pluginmanager.register(MyPlugin1()) + config.pluginmanager.register(MyPlugin2()) + config.hook.pytest_pyfunc_call(pyfuncitem=item) + +class TestSorting: + def test_check_equality(self, testdir): + modcol = testdir.getmodulecol(""" + def test_pass(): pass + def test_fail(): assert 0 + """) + fn1 = testdir.collect_by_name(modcol, "test_pass") + assert isinstance(fn1, pytest.Function) + fn2 = testdir.collect_by_name(modcol, "test_pass") + assert isinstance(fn2, pytest.Function) + + assert fn1 == fn2 + assert fn1 != modcol + if py.std.sys.version_info < (3, 0): + assert cmp(fn1, fn2) == 0 + assert hash(fn1) == hash(fn2) + + fn3 = testdir.collect_by_name(modcol, "test_fail") + assert isinstance(fn3, pytest.Function) + assert not (fn1 == fn3) + assert fn1 != fn3 + + for fn in fn1,fn2,fn3: + assert fn != 3 + assert fn != modcol + assert fn != [1,2,3] + assert [1,2,3] != fn + assert modcol != fn + + def test_allow_sane_sorting_for_decorators(self, testdir): + modcol = testdir.getmodulecol(""" + def dec(f): + g = lambda: f(2) + g.place_as = f + return g + + + def test_b(y): + pass + test_b = dec(test_b) + + def test_a(y): + pass + test_a = dec(test_a) + """) + colitems = modcol.collect() + assert len(colitems) == 2 + assert [item.name for item in colitems] == ['test_b', 'test_a'] + + +class TestConftestCustomization: + def test_pytest_pycollect_module(self, testdir): + testdir.makeconftest(""" + import pytest + class MyModule(pytest.Module): + pass + def pytest_pycollect_makemodule(path, parent): + if path.basename == "test_xyz.py": + return MyModule(path, parent) + """) + testdir.makepyfile("def test_some(): pass") + testdir.makepyfile(test_xyz="def test_func(): pass") + result = testdir.runpytest("--collectonly") + result.stdout.fnmatch_lines([ + "* 3 + + def test_traceback_error_during_import(self, testdir): + testdir.makepyfile(""" + x = 1 + x = 2 + x = 17 + asd + """) + result = testdir.runpytest() + assert result.ret != 0 + out = result.stdout.str() + assert "x = 1" not in out + assert "x = 2" not in out + result.stdout.fnmatch_lines([ + ">*asd*", + "E*NameError*", + ]) + result = testdir.runpytest("--fulltrace") + out = result.stdout.str() + assert "x = 1" in out + assert "x = 2" in out + result.stdout.fnmatch_lines([ + ">*asd*", + "E*NameError*", + ]) + +class TestReportInfo: + def test_itemreport_reportinfo(self, testdir, linecomp): + testdir.makeconftest(""" + import pytest + class MyFunction(pytest.Function): + def reportinfo(self): + return "ABCDE", 42, "custom" + def pytest_pycollect_makeitem(collector, name, obj): + if name == "test_func": + return MyFunction(name, parent=collector) + """) + item = testdir.getitem("def test_func(): pass") + runner = item.config.pluginmanager.getplugin("runner") + assert item.location == ("ABCDE", 42, "custom") + + def test_func_reportinfo(self, testdir): + item = testdir.getitem("def test_func(): pass") + fspath, lineno, modpath = item.reportinfo() + assert fspath == item.fspath + assert lineno == 0 + assert modpath == "test_func" + + def test_class_reportinfo(self, testdir): + modcol = testdir.getmodulecol(""" + # lineno 0 + class TestClass: + def test_hello(self): pass + """) + classcol = testdir.collect_by_name(modcol, "TestClass") + fspath, lineno, msg = classcol.reportinfo() + assert fspath == modcol.fspath + assert lineno == 1 + assert msg == "TestClass" + + 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: + def test_method(self): + pass + """ + + +def test_customized_python_discovery(testdir): + testdir.makeini(""" + [pytest] + python_files=check_*.py + python_classes=Check + python_functions=check + """) + p = testdir.makepyfile(""" + def check_simple(): + pass + class CheckMyApp: + def check_meth(self): + pass + """) + p2 = p.new(basename=p.basename.replace("test", "check")) + p.move(p2) + result = testdir.runpytest("--collectonly", "-s") + result.stdout.fnmatch_lines([ + "*check_customized*", + "*check_simple*", + "*CheckMyApp*", + "*check_meth*", + ]) + + result = testdir.runpytest() + assert result.ret == 0 + result.stdout.fnmatch_lines([ + "*2 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() + 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: + def test_hello(self): + pass + """) + result = testdir.runpytest("--collectonly") + result.stdout.fnmatch_lines([ + "*MyClass*", + "*MyInstance*", + "*MyFunction*test_hello*", + ]) + + +def test_unorderable_types(testdir): + testdir.makepyfile(""" + class TestJoinEmpty: + pass + + def make_test(): + class Test: + pass + Test.__name__ = "TestFoo" + return Test + TestFoo = make_test() + """) + result = testdir.runpytest() + assert "TypeError" not in result.stdout.str() + assert result.ret == 0 diff -r aadd426bdd8ca896314b29f1802fae58b7684cea -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c testing/python/fixture.py --- /dev/null +++ b/testing/python/fixture.py @@ -0,0 +1,1775 @@ +import pytest, py, sys +from _pytest import python as funcargs +from _pytest.python import FixtureLookupError + +def test_getfuncargnames(): + def f(): pass + assert not funcargs.getfuncargnames(f) + def g(arg): pass + assert funcargs.getfuncargnames(g) == ('arg',) + def h(arg1, arg2="hello"): pass + assert funcargs.getfuncargnames(h) == ('arg1',) + def h(arg1, arg2, arg3="hello"): pass + assert funcargs.getfuncargnames(h) == ('arg1', 'arg2') + class A: + def f(self, arg1, arg2="hello"): + pass + assert funcargs.getfuncargnames(A().f) == ('arg1',) + if sys.version_info < (3,0): + assert funcargs.getfuncargnames(A.f) == ('arg1',) + +class TestFillFixtures: + def test_fillfuncargs_exposed(self): + # used by oejskit, kept for compatibility + assert pytest._fillfuncargs == funcargs.fillfixtures + + def test_funcarg_lookupfails(self, testdir): + testdir.makepyfile(""" + def pytest_funcarg__xyzsomething(request): + return 42 + + def test_func(some): + pass + """) + result = testdir.runpytest() # "--collectonly") + assert result.ret != 0 + result.stdout.fnmatch_lines([ + "*def test_func(some)*", + "*fixture*some*not found*", + "*xyzsomething*", + ]) + + def test_funcarg_basic(self, testdir): + item = testdir.getitem(""" + def pytest_funcarg__some(request): + return request.function.__name__ + def pytest_funcarg__other(request): + return 42 + def test_func(some, other): + pass + """) + funcargs.fillfixtures(item) + del item.funcargs["request"] + assert len(item.funcargs) == 2 + assert item.funcargs['some'] == "test_func" + assert item.funcargs['other'] == 42 + + def test_funcarg_lookup_modulelevel(self, testdir): + testdir.makepyfile(""" + def pytest_funcarg__something(request): + return request.function.__name__ + + class TestClass: + def test_method(self, something): + assert something == "test_method" + def test_func(something): + assert something == "test_func" + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + + def test_funcarg_lookup_classlevel(self, testdir): + p = testdir.makepyfile(""" + class TestClass: + def pytest_funcarg__something(self, request): + return request.instance + def test_method(self, something): + assert something is self + """) + result = testdir.runpytest(p) + result.stdout.fnmatch_lines([ + "*1 passed*" + ]) + + def test_conftest_funcargs_only_available_in_subdir(self, testdir): + sub1 = testdir.mkpydir("sub1") + sub2 = testdir.mkpydir("sub2") + sub1.join("conftest.py").write(py.code.Source(""" + import pytest + def pytest_funcarg__arg1(request): + pytest.raises(Exception, "request.getfuncargvalue('arg2')") + """)) + sub2.join("conftest.py").write(py.code.Source(""" + import pytest + def pytest_funcarg__arg2(request): + pytest.raises(Exception, "request.getfuncargvalue('arg1')") + """)) + + sub1.join("test_in_sub1.py").write("def test_1(arg1): pass") + sub2.join("test_in_sub2.py").write("def test_2(arg2): pass") + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*2 passed*" + ]) + + def test_funcarg_lookup_error(self, testdir): + p = testdir.makepyfile(""" + def test_lookup_error(unknown): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*ERROR*test_lookup_error*", + "*def test_lookup_error(unknown):*", + "*fixture*unknown*not found*", + "*available fixtures*", + "*1 error*", + ]) + assert "INTERNAL" not in result.stdout.str() + +class TestRequestBasic: + def test_request_attributes(self, testdir): + item = testdir.getitem(""" + def pytest_funcarg__something(request): pass + def test_func(something): pass + """) + req = funcargs.FixtureRequest(item) + assert req.function == item.obj + assert req.keywords == item.keywords + assert hasattr(req.module, 'test_func') + assert req.cls is None + assert req.function.__name__ == "test_func" + assert req.config == item.config + assert repr(req).find(req.function.__name__) != -1 + + def test_request_attributes_method(self, testdir): + item, = testdir.getitems(""" + class TestB: + def pytest_funcarg__something(self, request): + return 1 + def test_func(self, something): + pass + """) + req = item._request + assert req.cls.__name__ == "TestB" + assert req.instance.__class__ == req.cls + + def XXXtest_request_contains_funcarg_arg2fixturedefs(self, testdir): + modcol = testdir.getmodulecol(""" + def pytest_funcarg__something(request): + pass + class TestClass: + def test_method(self, something): + pass + """) + item1, = testdir.genitems([modcol]) + assert item1.name == "test_method" + arg2fixturedefs = funcargs.FixtureRequest(item1)._arg2fixturedefs + assert len(arg2fixturedefs) == 1 + assert arg2fixturedefs[0].__name__ == "pytest_funcarg__something" + + def test_getfuncargvalue_recursive(self, testdir): + testdir.makeconftest(""" + def pytest_funcarg__something(request): + return 1 + """) + item = testdir.makepyfile(""" + def pytest_funcarg__something(request): + return request.getfuncargvalue("something") + 1 + def test_func(something): + assert something == 2 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_getfuncargvalue(self, testdir): + item = testdir.getitem(""" + l = [2] + def pytest_funcarg__something(request): return 1 + def pytest_funcarg__other(request): + return l.pop() + def test_func(something): pass + """) + req = item._request + pytest.raises(FixtureLookupError, req.getfuncargvalue, "notexists") + val = req.getfuncargvalue("something") + assert val == 1 + val = req.getfuncargvalue("something") + assert val == 1 + val2 = req.getfuncargvalue("other") + assert val2 == 2 + val2 = req.getfuncargvalue("other") # see about caching + assert val2 == 2 + pytest._fillfuncargs(item) + assert item.funcargs["something"] == 1 + assert len(item.funcargs) == 2 + assert "request" in item.funcargs + #assert item.funcargs == {'something': 1, "other": 2} + + def test_request_addfinalizer(self, testdir): + item = testdir.getitem(""" + teardownlist = [] + def pytest_funcarg__something(request): + request.addfinalizer(lambda: teardownlist.append(1)) + def test_func(something): pass + """) + item.session._setupstate.prepare(item) + pytest._fillfuncargs(item) + # successively check finalization calls + teardownlist = item.getparent(pytest.Module).obj.teardownlist + ss = item.session._setupstate + assert not teardownlist + ss.teardown_exact(item, None) + print(ss.stack) + assert teardownlist == [1] + + def test_request_addfinalizer_partial_setup_failure(self, testdir): + p = testdir.makepyfile(""" + l = [] + def pytest_funcarg__something(request): + request.addfinalizer(lambda: l.append(None)) + def test_func(something, missingarg): + pass + def test_second(): + assert len(l) == 1 + """) + result = testdir.runpytest(p) + result.stdout.fnmatch_lines([ + "*1 error*" # XXX the whole module collection fails + ]) + + def test_request_getmodulepath(self, testdir): + modcol = testdir.getmodulecol("def test_somefunc(): pass") + item, = testdir.genitems([modcol]) + req = funcargs.FixtureRequest(item) + assert req.fspath == modcol.fspath + + def test_request_fixturenames(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture() + def arg1(): + pass + @pytest.fixture() + def farg(arg1): + pass + @pytest.fixture(autouse=True) + def sarg(tmpdir): + pass + def test_function(request, farg): + assert set(request.fixturenames) == \ + set(["tmpdir", "sarg", "arg1", "request", "farg"]) + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_funcargnames_compatattr(self, testdir): + testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + assert metafunc.funcargnames == metafunc.fixturenames + def pytest_funcarg__fn(request): + assert request._pyfuncitem.funcargnames == \ + request._pyfuncitem.fixturenames + return request.funcargnames, request.fixturenames + + def test_hello(fn): + assert fn[0] == fn[1] + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_setupdecorator_and_xunit(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(scope='module', autouse=True) + def setup_module(): + l.append("module") + @pytest.fixture(autouse=True) + def setup_function(): + l.append("function") + + def test_func(): + pass + + class TestClass: + @pytest.fixture(scope="class", autouse=True) + def setup_class(self): + l.append("class") + @pytest.fixture(autouse=True) + def setup_method(self): + l.append("method") + def test_method(self): + pass + def test_all(): + assert l == ["module", "function", "class", + "function", "method", "function"] + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=3) + + def test_fixtures_sub_subdir_normalize_sep(self, testdir): + # this tests that normlization of nodeids takes place + b = testdir.mkdir("tests").mkdir("unit") + b.join("conftest.py").write(py.code.Source(""" + def pytest_funcarg__arg1(): + pass + """)) + p = b.join("test_module.py") + p.write("def test_func(arg1): pass") + result = testdir.runpytest(p, "--fixtures") + assert result.ret == 0 + result.stdout.fnmatch_lines(""" + *fixtures defined*conftest* + *arg1* + """) + + def test_newstyle_with_request(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture() + def arg(request): + pass + def test_1(arg): + pass + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_setupcontext_no_param(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(params=[1,2]) + def arg(request): + return request.param + + @pytest.fixture(autouse=True) + def mysetup(request, arg): + assert not hasattr(request, "param") + def test_1(arg): + assert arg in (1,2) + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + +class TestRequestMarking: + def test_applymarker(self, testdir): + item1,item2 = testdir.getitems(""" + def pytest_funcarg__something(request): + pass + class TestClass: + def test_func1(self, something): + pass + def test_func2(self, something): + pass + """) + req1 = funcargs.FixtureRequest(item1) + assert 'xfail' not in item1.keywords + req1.applymarker(pytest.mark.xfail) + assert 'xfail' in item1.keywords + assert 'skipif' not in item1.keywords + req1.applymarker(pytest.mark.skipif) + assert 'skipif' in item1.keywords + pytest.raises(ValueError, "req1.applymarker(42)") + + def test_accesskeywords(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture() + def keywords(request): + return request.keywords + @pytest.mark.XYZ + def test_function(keywords): + assert keywords["XYZ"] + assert "abc" not in keywords + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_accessmarker_dynamic(self, testdir): + testdir.makeconftest(""" + import pytest + @pytest.fixture() + def keywords(request): + return request.keywords + + @pytest.fixture(scope="class", autouse=True) + def marking(request): + request.applymarker(pytest.mark.XYZ("hello")) + """) + testdir.makepyfile(""" + import pytest + def test_fun1(keywords): + assert keywords["XYZ"] is not None + assert "abc" not in keywords + def test_fun2(keywords): + assert keywords["XYZ"] is not None + assert "abc" not in keywords + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + +class TestRequestCachedSetup: + def test_request_cachedsetup_defaultmodule(self, testdir): + reprec = testdir.inline_runsource(""" + mysetup = ["hello",].pop + + def pytest_funcarg__something(request): + return request.cached_setup(mysetup, scope="module") + + def test_func1(something): + assert something == "hello" + class TestClass: + def test_func1a(self, something): + assert something == "hello" + """) + reprec.assertoutcome(passed=2) + + def test_request_cachedsetup_class(self, testdir): + reprec = testdir.inline_runsource(""" + mysetup = ["hello", "hello2"].pop + + def pytest_funcarg__something(request): + return request.cached_setup(mysetup, scope="class") + def test_func1(something): + assert something == "hello2" + def test_func2(something): + assert something == "hello2" + class TestClass: + def test_func1a(self, something): + assert something == "hello" + def test_func2b(self, something): + assert something == "hello" + """) + reprec.assertoutcome(passed=4) + + def test_request_cachedsetup_extrakey(self, testdir): + item1 = testdir.getitem("def test_func(): pass") + req1 = funcargs.FixtureRequest(item1) + l = ["hello", "world"] + def setup(): + return l.pop() + ret1 = req1.cached_setup(setup, extrakey=1) + ret2 = req1.cached_setup(setup, extrakey=2) + assert ret2 == "hello" + assert ret1 == "world" + ret1b = req1.cached_setup(setup, extrakey=1) + ret2b = req1.cached_setup(setup, extrakey=2) + assert ret1 == ret1b + assert ret2 == ret2b + + def test_request_cachedsetup_cache_deletion(self, testdir): + item1 = testdir.getitem("def test_func(): pass") + req1 = funcargs.FixtureRequest(item1) + l = [] + def setup(): + l.append("setup") + def teardown(val): + l.append("teardown") + ret1 = req1.cached_setup(setup, teardown, scope="function") + assert l == ['setup'] + # artificial call of finalizer + setupstate = req1._pyfuncitem.session._setupstate + setupstate._callfinalizers(item1) + assert l == ["setup", "teardown"] + ret2 = req1.cached_setup(setup, teardown, scope="function") + assert l == ["setup", "teardown", "setup"] + setupstate._callfinalizers(item1) + assert l == ["setup", "teardown", "setup", "teardown"] + + def test_request_cached_setup_two_args(self, testdir): + testdir.makepyfile(""" + def pytest_funcarg__arg1(request): + return request.cached_setup(lambda: 42) + def pytest_funcarg__arg2(request): + return request.cached_setup(lambda: 17) + def test_two_different_setups(arg1, arg2): + assert arg1 != arg2 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*1 passed*" + ]) + + def test_request_cached_setup_getfuncargvalue(self, testdir): + testdir.makepyfile(""" + def pytest_funcarg__arg1(request): + arg1 = request.getfuncargvalue("arg2") + return request.cached_setup(lambda: arg1 + 1) + def pytest_funcarg__arg2(request): + return request.cached_setup(lambda: 10) + def test_two_funcarg(arg1): + assert arg1 == 11 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*1 passed*" + ]) + + def test_request_cached_setup_functional(self, testdir): + testdir.makepyfile(test_0=""" + l = [] + def pytest_funcarg__something(request): + val = request.cached_setup(fsetup, fteardown) + return val + def fsetup(mycache=[1]): + l.append(mycache.pop()) + return l + def fteardown(something): + l.remove(something[0]) + l.append(2) + def test_list_once(something): + assert something == [1] + def test_list_twice(something): + assert something == [1] + """) + testdir.makepyfile(test_1=""" + import test_0 # should have run already + def test_check_test0_has_teardown_correct(): + assert test_0.l == [2] + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*3 passed*" + ]) + + def test_issue117_sessionscopeteardown(self, testdir): + testdir.makepyfile(""" + def pytest_funcarg__app(request): + app = request.cached_setup( + scope='session', + setup=lambda: 0, + teardown=lambda x: 3/x) + return app + def test_func(app): + pass + """) + result = testdir.runpytest() + assert result.ret != 0 + result.stdout.fnmatch_lines([ + "*3/x*", + "*ZeroDivisionError*", + ]) + +class TestOEJSKITSpecials: + def test_funcarg_non_pycollectobj(self, testdir): # rough jstests usage + testdir.makeconftest(""" + import pytest + def pytest_pycollect_makeitem(collector, name, obj): + if name == "MyClass": + return MyCollector(name, parent=collector) + class MyCollector(pytest.Collector): + def reportinfo(self): + return self.fspath, 3, "xyz" + """) + modcol = testdir.getmodulecol(""" + def pytest_funcarg__arg1(request): + return 42 + class MyClass: + pass + """) + # this hook finds funcarg factories + rep = modcol.ihook.pytest_make_collect_report(collector=modcol) + clscol = rep.result[0] + clscol.obj = lambda arg1: None + clscol.funcargs = {} + funcargs.fillfixtures(clscol) + assert clscol.funcargs['arg1'] == 42 + + def test_autouse_fixture(self, testdir): # rough jstests usage + testdir.makeconftest(""" + import pytest + def pytest_pycollect_makeitem(collector, name, obj): + if name == "MyClass": + return MyCollector(name, parent=collector) + class MyCollector(pytest.Collector): + def reportinfo(self): + return self.fspath, 3, "xyz" + """) + modcol = testdir.getmodulecol(""" + import pytest + @pytest.fixture(autouse=True) + def hello(): + pass + def pytest_funcarg__arg1(request): + return 42 + class MyClass: + pass + """) + # this hook finds funcarg factories + rep = modcol.ihook.pytest_make_collect_report(collector=modcol) + clscol = rep.result[0] + clscol.obj = lambda: None + clscol.funcargs = {} + funcargs.fillfixtures(clscol) + assert not clscol.funcargs + +class TestFixtureUsages: + def test_noargfixturedec(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture + def arg1(): + return 1 + + def test_func(arg1): + assert arg1 == 1 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_receives_funcargs(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture() + def arg1(): + return 1 + + @pytest.fixture() + def arg2(arg1): + return arg1 + 1 + + def test_add(arg2): + assert arg2 == 2 + def test_all(arg1, arg2): + assert arg1 == 1 + assert arg2 == 2 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + + def test_receives_funcargs_scope_mismatch(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope="function") + def arg1(): + return 1 + + @pytest.fixture(scope="module") + def arg2(arg1): + return arg1 + 1 + + def test_add(arg2): + assert arg2 == 2 + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*ScopeMismatch*involved factories*", + "* def arg2*", + "* def arg1*", + "*1 error*" + ]) + + def test_funcarg_parametrized_and_used_twice(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(params=[1,2]) + def arg1(request): + l.append(1) + return request.param + + @pytest.fixture() + def arg2(arg1): + return arg1 + 1 + + def test_add(arg1, arg2): + assert arg2 == arg1 + 1 + assert len(l) == arg1 + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*2 passed*" + ]) + + def test_factory_uses_unknown_funcarg_as_dependency_error(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture() + def fail(missing): + return + + @pytest.fixture() + def call_fail(fail): + return + + def test_missing(call_fail): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines(""" + *pytest.fixture()* + *def call_fail(fail)* + *pytest.fixture()* + *def fail* + *fixture*'missing'*not found* + """) + + def test_factory_setup_as_classes_fails(self, testdir): + testdir.makepyfile(""" + import pytest + class arg1: + def __init__(self, request): + self.x = 1 + arg1 = pytest.fixture()(arg1) + + """) + reprec = testdir.inline_run() + l = reprec.getfailedcollections() + assert len(l) == 1 + + def test_request_can_be_overridden(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture() + def request(request): + request.a = 1 + return request + def test_request(request): + assert request.a == 1 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_usefixtures_marker(self, testdir): + testdir.makepyfile(""" + import pytest + + l = [] + + @pytest.fixture(scope="class") + def myfix(request): + request.cls.hello = "world" + l.append(1) + + class TestClass: + def test_one(self): + assert self.hello == "world" + assert len(l) == 1 + def test_two(self): + assert self.hello == "world" + assert len(l) == 1 + pytest.mark.usefixtures("myfix")(TestClass) + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + + def test_usefixtures_ini(self, testdir): + testdir.makeini(""" + [pytest] + usefixtures = myfix + """) + testdir.makeconftest(""" + import pytest + + @pytest.fixture(scope="class") + def myfix(request): + request.cls.hello = "world" + + """) + testdir.makepyfile(""" + class TestClass: + def test_one(self): + assert self.hello == "world" + def test_two(self): + assert self.hello == "world" + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + + def test_usefixtures_seen_in_showmarkers(self, testdir): + result = testdir.runpytest("--markers") + result.stdout.fnmatch_lines(""" + *usefixtures(fixturename1*mark tests*fixtures* + """) + + def test_request_instance_issue203(self, testdir): + testdir.makepyfile(""" + import pytest + + class TestClass: + @pytest.fixture + def setup1(self, request): + assert self == request.instance + self.arg1 = 1 + def test_hello(self, setup1): + assert self.arg1 == 1 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + +class TestFixtureManagerParseFactories: + def pytest_funcarg__testdir(self, request): + testdir = request.getfuncargvalue("testdir") + testdir.makeconftest(""" + def pytest_funcarg__hello(request): + return "conftest" + + def pytest_funcarg__fm(request): + return request._fixturemanager + + def pytest_funcarg__item(request): + return request._pyfuncitem + """) + return testdir + + def test_parsefactories_evil_objects_issue214(self, testdir): + testdir.makepyfile(""" + class A: + def __call__(self): + pass + def __getattr__(self, name): + raise RuntimeError() + a = A() + def test_hello(): + pass + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1, failed=0) + + def test_parsefactories_conftest(self, testdir): + testdir.makepyfile(""" + def test_hello(item, fm): + for name in ("fm", "hello", "item"): + faclist = fm.getfixturedefs(name, item.nodeid) + assert len(faclist) == 1 + fac = faclist[0] + assert fac.func.__name__ == "pytest_funcarg__" + name + """) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(passed=1) + + def test_parsefactories_conftest_and_module_and_class(self, testdir): + testdir.makepyfile(""" + def pytest_funcarg__hello(request): + return "module" + class TestClass: + def pytest_funcarg__hello(self, request): + return "class" + def test_hello(self, item, fm): + faclist = fm.getfixturedefs("hello", item.nodeid) + print (faclist) + assert len(faclist) == 3 + assert faclist[0].func(item._request) == "conftest" + assert faclist[1].func(item._request) == "module" + assert faclist[2].func(item._request) == "class" + """) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(passed=1) + +class TestAutouseDiscovery: + def pytest_funcarg__testdir(self, testdir): + testdir.makeconftest(""" + import pytest + @pytest.fixture(autouse=True) + def perfunction(request, tmpdir): + pass + + @pytest.fixture() + def arg1(tmpdir): + pass + @pytest.fixture(autouse=True) + def perfunction2(arg1): + pass + + def pytest_funcarg__fm(request): + return request._fixturemanager + + def pytest_funcarg__item(request): + return request._pyfuncitem + """) + return testdir + + def test_parsefactories_conftest(self, testdir): + testdir.makepyfile(""" + def test_check_setup(item, fm): + autousenames = fm._getautousenames(item.nodeid) + assert len(autousenames) == 2 + assert "perfunction2" in autousenames + assert "perfunction" in autousenames + """) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(passed=1) + + def test_two_classes_separated_autouse(self, testdir): + testdir.makepyfile(""" + import pytest + class TestA: + l = [] + @pytest.fixture(autouse=True) + def setup1(self): + self.l.append(1) + def test_setup1(self): + assert self.l == [1] + class TestB: + l = [] + @pytest.fixture(autouse=True) + def setup2(self): + self.l.append(1) + def test_setup2(self): + assert self.l == [1] + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + + def test_setup_at_classlevel(self, testdir): + testdir.makepyfile(""" + import pytest + class TestClass: + @pytest.fixture(autouse=True) + def permethod(self, request): + request.instance.funcname = request.function.__name__ + def test_method1(self): + assert self.funcname == "test_method1" + def test_method2(self): + assert self.funcname == "test_method2" + """) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(passed=2) + + @pytest.mark.xfail(reason="'enabled' feature not implemented") + def test_setup_enabled_functionnode(self, testdir): + testdir.makepyfile(""" + import pytest + + def enabled(parentnode, markers): + return "needsdb" in markers + + @pytest.fixture(params=[1,2]) + def db(request): + return request.param + + @pytest.fixture(enabled=enabled, autouse=True) + def createdb(db): + pass + + def test_func1(request): + assert "db" not in request.fixturenames + + @pytest.mark.needsdb + def test_func2(request): + assert "db" in request.fixturenames + """) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(passed=2) + + def test_callables_nocode(self, testdir): + """ + a imported mock.call would break setup/factory discovery + due to it being callable and __code__ not being a code object + """ + testdir.makepyfile(""" + class _call(tuple): + def __call__(self, *k, **kw): + pass + def __getattr__(self, k): + return self + + call = _call() + """) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(failed=0, passed=0) + + def test_autouse_in_conftests(self, testdir): + a = testdir.mkdir("a") + b = testdir.mkdir("a1") + conftest = testdir.makeconftest(""" + import pytest + @pytest.fixture(autouse=True) + def hello(): + xxx + """) + conftest.move(a.join(conftest.basename)) + a.join("test_something.py").write("def test_func(): pass") + b.join("test_otherthing.py").write("def test_func(): pass") + result = testdir.runpytest() + result.stdout.fnmatch_lines(""" + *1 passed*1 error* + """) + + def test_autouse_in_module_and_two_classes(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(autouse=True) + def append1(): + l.append("module") + def test_x(): + assert l == ["module"] + + class TestA: + @pytest.fixture(autouse=True) + def append2(self): + l.append("A") + def test_hello(self): + assert l == ["module", "module", "A"], l + class TestA2: + def test_world(self): + assert l == ["module", "module", "A", "module"], l + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=3) + +class TestAutouseManagement: + def test_funcarg_and_setup(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(scope="module") + def arg(): + l.append(1) + return 0 + @pytest.fixture(scope="class", autouse=True) + def something(arg): + l.append(2) + + def test_hello(arg): + assert len(l) == 2 + assert l == [1,2] + assert arg == 0 + + def test_hello2(arg): + assert len(l) == 2 + assert l == [1,2] + assert arg == 0 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) + + def test_uses_parametrized_resource(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(params=[1,2]) + def arg(request): + return request.param + + @pytest.fixture(autouse=True) + def something(arg): + l.append(arg) + + def test_hello(): + if len(l) == 1: + assert l == [1] + elif len(l) == 2: + assert l == [1, 2] + else: + 0/0 + + """) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(passed=2) + + def test_session_parametrized_function(self, testdir): + testdir.makepyfile(""" + import pytest + + l = [] + + @pytest.fixture(scope="session", params=[1,2]) + def arg(request): + return request.param + + @pytest.fixture(scope="function", autouse=True) + def append(request, arg): + if request.function.__name__ == "test_some": + l.append(arg) + + def test_some(): + pass + + def test_result(arg): + assert len(l) == arg + assert l[:arg] == [1,2][:arg] + """) + reprec = testdir.inline_run("-v", "-s") + reprec.assertoutcome(passed=4) + + def test_class_function_parametrization_finalization(self, testdir): + p = testdir.makeconftest(""" + import pytest + import pprint + + l = [] + + @pytest.fixture(scope="function", params=[1,2]) + def farg(request): + return request.param + + @pytest.fixture(scope="class", params=list("ab")) + def carg(request): + return request.param + + @pytest.fixture(scope="function", autouse=True) + def append(request, farg, carg): + def fin(): + l.append("fin_%s%s" % (carg, farg)) + request.addfinalizer(fin) + """) + testdir.makepyfile(""" + import pytest + + class TestClass: + def test_1(self): + pass + class TestClass2: + def test_2(self): + pass + """) + reprec = testdir.inline_run("-v","-s") + reprec.assertoutcome(passed=8) + config = reprec.getcalls("pytest_unconfigure")[0].config + l = config._conftest.getconftestmodules(p)[0].l + assert l == ["fin_a1", "fin_a2", "fin_b1", "fin_b2"] * 2 + + def test_scope_ordering(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(scope="function", autouse=True) + def fappend2(): + l.append(2) + @pytest.fixture(scope="class", autouse=True) + def classappend3(): + l.append(3) + @pytest.fixture(scope="module", autouse=True) + def mappend(): + l.append(1) + + class TestHallo: + def test_method(self): + assert l == [1,3,2] + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_parametrization_setup_teardown_ordering(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + def pytest_generate_tests(metafunc): + if metafunc.cls is not None: + metafunc.parametrize("item", [1,2], scope="class") + class TestClass: + @pytest.fixture(scope="class", autouse=True) + def addteardown(self, item, request): + l.append("setup-%d" % item) + request.addfinalizer(lambda: l.append("teardown-%d" % item)) + def test_step1(self, item): + l.append("step1-%d" % item) + def test_step2(self, item): + l.append("step2-%d" % item) + + def test_finish(): + assert l == ["setup-1", "step1-1", "step2-1", "teardown-1", + "setup-2", "step1-2", "step2-2", "teardown-2",] + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=5) + + def test_setup_funcarg_order(self, testdir): + testdir.makepyfile(""" + import pytest + + l = [] + @pytest.fixture(autouse=True) + def fix1(): + l.append(1) + @pytest.fixture() + def arg1(): + l.append(2) + def test_hello(arg1): + assert l == [1,2] + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + +class TestFixtureMarker: + def test_parametrize(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(params=["a", "b", "c"]) + def arg(request): + return request.param + l = [] + def test_param(arg): + l.append(arg) + def test_result(): + assert l == list("abc") + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=4) + + def test_scope_session(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(scope="module") + def arg(): + l.append(1) + return 1 + + def test_1(arg): + assert arg == 1 + def test_2(arg): + assert arg == 1 + assert len(l) == 1 + class TestClass: + def test3(self, arg): + assert arg == 1 + assert len(l) == 1 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=3) + + def test_scope_module_uses_session(self, testdir): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(scope="module") + def arg(): + l.append(1) + return 1 + + def test_1(arg): + assert arg == 1 + def test_2(arg): + assert arg == 1 + assert len(l) == 1 + class TestClass: + def test3(self, arg): + assert arg == 1 + assert len(l) == 1 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=3) + + def test_scope_module_and_finalizer(self, testdir): + testdir.makeconftest(""" + import pytest + finalized = [] + created = [] + @pytest.fixture(scope="module") + def arg(request): + created.append(1) + assert request.scope == "module" + request.addfinalizer(lambda: finalized.append(1)) + def pytest_funcarg__created(request): + return len(created) + def pytest_funcarg__finalized(request): + return len(finalized) + """) + testdir.makepyfile( + test_mod1=""" + def test_1(arg, created, finalized): + assert created == 1 + assert finalized == 0 + def test_2(arg, created, finalized): + assert created == 1 + assert finalized == 0""", + test_mod2=""" + def test_3(arg, created, finalized): + assert created == 2 + assert finalized == 1""", + test_mode3=""" + def test_4(arg, created, finalized): + assert created == 3 + assert finalized == 2 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=4) + + @pytest.mark.parametrize("method", [ + 'request.getfuncargvalue("arg")', + 'request.cached_setup(lambda: None, scope="function")', + ], ids=["getfuncargvalue", "cached_setup"]) + def test_scope_mismatch(self, testdir, method): + testdir.makeconftest(""" + import pytest + finalized = [] + created = [] + @pytest.fixture(scope="function") + def arg(request): + pass + """) + testdir.makepyfile( + test_mod1=""" + import pytest + @pytest.fixture(scope="session") + def arg(request): + %s + def test_1(arg): + pass + """ % method) + result = testdir.runpytest() + assert result.ret != 0 + result.stdout.fnmatch_lines([ + "*ScopeMismatch*You tried*function*session*request*", + ]) + + def test_register_only_with_mark(self, testdir): + testdir.makeconftest(""" + import pytest + @pytest.fixture() + def arg(): + return 1 + """) + testdir.makepyfile( + test_mod1=""" + import pytest + @pytest.fixture() + def arg(arg): + return arg + 1 + def test_1(arg): + assert arg == 2 + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_parametrize_and_scope(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope="module", params=["a", "b", "c"]) + def arg(request): + return request.param + l = [] + def test_param(arg): + l.append(arg) + """) + reprec = testdir.inline_run("-v") + reprec.assertoutcome(passed=3) + l = reprec.getcalls("pytest_runtest_call")[0].item.module.l + assert len(l) == 3 + assert "a" in l + assert "b" in l + assert "c" in l + + def test_scope_mismatch(self, testdir): + testdir.makeconftest(""" + import pytest + @pytest.fixture(scope="function") + def arg(request): + pass + """) + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope="session") + def arg(arg): + pass + def test_mismatch(arg): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*ScopeMismatch*", + "*1 error*", + ]) + + def test_parametrize_separated_order(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(scope="module", params=[1, 2]) + def arg(request): + return request.param + + l = [] + def test_1(arg): + l.append(arg) + def test_2(arg): + l.append(arg) + """) + reprec = testdir.inline_run("-v") + reprec.assertoutcome(passed=4) + l = reprec.getcalls("pytest_runtest_call")[0].item.module.l + assert l == [1,1,2,2] + + def test_module_parametrized_ordering(self, testdir): + testdir.makeconftest(""" + import pytest + + @pytest.fixture(scope="session", params="s1 s2".split()) + def sarg(): + pass + @pytest.fixture(scope="module", params="m1 m2".split()) + def marg(): + pass + """) + testdir.makepyfile(test_mod1=""" + def test_func(sarg): + pass + def test_func1(marg): + pass + """, test_mod2=""" + def test_func2(sarg): + pass + def test_func3(sarg, marg): + pass + def test_func3b(sarg, marg): + pass + def test_func4(marg): + pass + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines(""" + test_mod1.py:1: test_func[s1] PASSED + test_mod2.py:1: test_func2[s1] PASSED + test_mod2.py:3: test_func3[s1-m1] PASSED + test_mod2.py:5: test_func3b[s1-m1] PASSED + test_mod2.py:3: test_func3[s1-m2] PASSED + test_mod2.py:5: test_func3b[s1-m2] PASSED + test_mod1.py:1: test_func[s2] PASSED + test_mod2.py:1: test_func2[s2] PASSED + test_mod2.py:3: test_func3[s2-m1] PASSED + test_mod2.py:5: test_func3b[s2-m1] PASSED + test_mod2.py:7: test_func4[m1] PASSED + test_mod2.py:3: test_func3[s2-m2] PASSED + test_mod2.py:5: test_func3b[s2-m2] PASSED + test_mod2.py:7: test_func4[m2] PASSED + test_mod1.py:3: test_func1[m1] PASSED + test_mod1.py:3: test_func1[m2] PASSED + """) + + def test_class_ordering(self, testdir): + p = testdir.makeconftest(""" + import pytest + + l = [] + + @pytest.fixture(scope="function", params=[1,2]) + def farg(request): + return request.param + + @pytest.fixture(scope="class", params=list("ab")) + def carg(request): + return request.param + + @pytest.fixture(scope="function", autouse=True) + def append(request, farg, carg): + def fin(): + l.append("fin_%s%s" % (carg, farg)) + request.addfinalizer(fin) + """) + testdir.makepyfile(""" + import pytest + + class TestClass2: + def test_1(self): + pass + def test_2(self): + pass + class TestClass: + def test_3(self): + pass + """) + result = testdir.runpytest("-vs") + result.stdout.fnmatch_lines(""" + test_class_ordering.py:4: TestClass2.test_1[1-a] PASSED + test_class_ordering.py:4: TestClass2.test_1[2-a] PASSED + test_class_ordering.py:6: TestClass2.test_2[1-a] PASSED + test_class_ordering.py:6: TestClass2.test_2[2-a] PASSED + test_class_ordering.py:4: TestClass2.test_1[1-b] PASSED + test_class_ordering.py:4: TestClass2.test_1[2-b] PASSED + test_class_ordering.py:6: TestClass2.test_2[1-b] PASSED + test_class_ordering.py:6: TestClass2.test_2[2-b] PASSED + test_class_ordering.py:9: TestClass.test_3[1-a] PASSED + test_class_ordering.py:9: TestClass.test_3[2-a] PASSED + test_class_ordering.py:9: TestClass.test_3[1-b] PASSED + test_class_ordering.py:9: TestClass.test_3[2-b] PASSED + """) + + def test_parametrize_separated_order_higher_scope_first(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(scope="function", params=[1, 2]) + def arg(request): + param = request.param + request.addfinalizer(lambda: l.append("fin:%s" % param)) + l.append("create:%s" % param) + return request.param + + @pytest.fixture(scope="module", params=["mod1", "mod2"]) + def modarg(request): + param = request.param + request.addfinalizer(lambda: l.append("fin:%s" % param)) + l.append("create:%s" % param) + return request.param + + l = [] + def test_1(arg): + l.append("test1") + def test_2(modarg): + l.append("test2") + def test_3(arg, modarg): + l.append("test3") + def test_4(modarg, arg): + l.append("test4") + def test_5(): + assert len(l) == 12 * 3 + expected = [ + 'create:1', 'test1', 'fin:1', 'create:2', 'test1', + 'fin:2', 'create:mod1', 'test2', 'create:1', 'test3', + 'fin:1', 'create:2', 'test3', 'fin:2', 'create:1', + 'test4', 'fin:1', 'create:2', 'test4', 'fin:2', + 'fin:mod1', 'create:mod2', 'test2', 'create:1', 'test3', + 'fin:1', 'create:2', 'test3', 'fin:2', 'create:1', + 'test4', 'fin:1', 'create:2', 'test4', 'fin:2', + 'fin:mod2'] + import pprint + pprint.pprint(list(zip(l, expected))) + assert l == expected + """) + reprec = testdir.inline_run("-v") + reprec.assertoutcome(passed=12+1) + + def test_parametrized_fixture_teardown_order(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(params=[1,2], scope="class") + def param1(request): + return request.param + + l = [] + + class TestClass: + @classmethod + @pytest.fixture(scope="class", autouse=True) + def setup1(self, request, param1): + l.append(1) + request.addfinalizer(self.teardown1) + @classmethod + def teardown1(self): + assert l.pop() == 1 + @pytest.fixture(scope="class", autouse=True) + def setup2(self, request, param1): + l.append(2) + request.addfinalizer(self.teardown2) + @classmethod + def teardown2(self): + assert l.pop() == 2 + def test(self): + pass + + def test_finish(): + assert not l + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines(""" + *3 passed* + """) + assert "error" not in result.stdout.str() + + def test_parametrize_separated_lifecycle(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(scope="module", params=[1, 2]) + def arg(request): + request.config.l = l # to access from outer + x = request.param + request.addfinalizer(lambda: l.append("fin%s" % x)) + return request.param + + l = [] + def test_1(arg): + l.append(arg) + def test_2(arg): + l.append(arg) + """) + reprec = testdir.inline_run("-v") + reprec.assertoutcome(passed=4) + l = reprec.getcalls("pytest_configure")[0].config.l + import pprint + pprint.pprint(l) + assert len(l) == 6 + assert l[0] == l[1] == 1 + assert l[2] == "fin1" + assert l[3] == l[4] == 2 + assert l[5] == "fin2" + + + def test_parametrize_function_scoped_finalizers_called(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(scope="function", params=[1, 2]) + def arg(request): + x = request.param + request.addfinalizer(lambda: l.append("fin%s" % x)) + return request.param + + l = [] + def test_1(arg): + l.append(arg) + def test_2(arg): + l.append(arg) + def test_3(): + assert len(l) == 8 + assert l == [1, "fin1", 2, "fin2", 1, "fin1", 2, "fin2"] + """) + reprec = testdir.inline_run("-v") + reprec.assertoutcome(passed=5) + + def test_parametrize_setup_function(self, testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(scope="module", params=[1, 2]) + def arg(request): + return request.param + + @pytest.fixture(scope="module", autouse=True) + def mysetup(request, arg): + request.addfinalizer(lambda: l.append("fin%s" % arg)) + l.append("setup%s" % arg) + + l = [] + def test_1(arg): + l.append(arg) + def test_2(arg): + l.append(arg) + def test_3(): + import pprint + pprint.pprint(l) + if arg == 1: + assert l == ["setup1", 1, 1, ] + elif arg == 2: + assert l == ["setup1", 1, 1, "fin1", + "setup2", 2, 2, ] + + """) + reprec = testdir.inline_run("-v") + reprec.assertoutcome(passed=6) + +class TestRequestScopeAccess: + pytestmark = pytest.mark.parametrize(("scope", "ok", "error"),[ + ["session", "", "fspath class function module"], + ["module", "module fspath", "cls function"], + ["class", "module fspath cls", "function"], + ["function", "module fspath cls function", ""] + ]) + + def test_setup(self, testdir, scope, ok, error): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope=%r, autouse=True) + def myscoped(request): + for x in %r: + assert hasattr(request, x) + for x in %r: + pytest.raises(AttributeError, lambda: + getattr(request, x)) + assert request.session + assert request.config + def test_func(): + pass + """ %(scope, ok.split(), error.split())) + reprec = testdir.inline_run("-l") + reprec.assertoutcome(passed=1) + + def test_funcarg(self, testdir, scope, ok, error): + testdir.makepyfile(""" + import pytest + @pytest.fixture(scope=%r) + def arg(request): + for x in %r: + assert hasattr(request, x) + for x in %r: + pytest.raises(AttributeError, lambda: + getattr(request, x)) + assert request.session + assert request.config + def test_func(arg): + pass + """ %(scope, ok.split(), error.split())) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + +class TestErrors: + def test_subfactory_missing_funcarg(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture() + def gen(qwe123): + return 1 + def test_something(gen): + pass + """) + result = testdir.runpytest() + assert result.ret != 0 + result.stdout.fnmatch_lines([ + "*def gen(qwe123):*", + "*fixture*qwe123*not found*", + "*1 error*", + ]) + + def test_setupfunc_missing_funcarg(self, testdir): + testdir.makepyfile(""" + import pytest + @pytest.fixture(autouse=True) + def gen(qwe123): + return 1 + def test_something(): + pass + """) + result = testdir.runpytest() + assert result.ret != 0 + result.stdout.fnmatch_lines([ + "*def gen(qwe123):*", + "*fixture*qwe123*not found*", + "*1 error*", + ]) + +class TestShowFixtures: + def test_funcarg_compat(self, testdir): + config = testdir.parseconfigure("--funcargs") + assert config.option.showfixtures + + def test_show_fixtures(self, testdir): + result = testdir.runpytest("--fixtures") + result.stdout.fnmatch_lines([ + "*tmpdir*", + "*temporary directory*", + ] + ) + + def test_show_fixtures_verbose(self, testdir): + result = testdir.runpytest("--fixtures", "-v") + result.stdout.fnmatch_lines([ + "*tmpdir*--*tmpdir.py*", + "*temporary directory*", + ] + ) + + def test_show_fixtures_testmodule(self, testdir): + p = testdir.makepyfile(''' + import pytest + @pytest.fixture + def _arg0(): + """ hidden """ + @pytest.fixture + def arg1(): + """ hello world """ + ''') + result = testdir.runpytest("--fixtures", p) + result.stdout.fnmatch_lines(""" + *tmpdir + *fixtures defined from* + *arg1* + *hello world* + """) + assert "arg0" not in result.stdout.str() + + @pytest.mark.parametrize("testmod", [True, False]) + def test_show_fixtures_conftest(self, testdir, testmod): + testdir.makeconftest(''' + import pytest + @pytest.fixture + def arg1(): + """ hello world """ + ''') + if testmod: + testdir.makepyfile(""" + def test_hello(): + pass + """) + result = testdir.runpytest("--fixtures") + result.stdout.fnmatch_lines(""" + *tmpdir* + *fixtures defined from*conftest* + *arg1* + *hello world* + """) + diff -r aadd426bdd8ca896314b29f1802fae58b7684cea -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c testing/python/metafunc.py --- /dev/null +++ b/testing/python/metafunc.py @@ -0,0 +1,575 @@ +import pytest, py, sys +from _pytest import python as funcargs +from _pytest.python import FixtureLookupError + +class TestMetafunc: + def Metafunc(self, func): + # the unit tests of this class check if things work correctly + # on the funcarg level, so we don't need a full blown + # initiliazation + class FixtureInfo: + name2fixturedefs = None + def __init__(self, names): + self.names_closure = names + names = funcargs.getfuncargnames(func) + fixtureinfo = FixtureInfo(names) + return funcargs.Metafunc(func, fixtureinfo, None) + + def test_no_funcargs(self, testdir): + def function(): pass + metafunc = self.Metafunc(function) + assert not metafunc.fixturenames + repr(metafunc._calls) + + def test_function_basic(self): + def func(arg1, arg2="qwe"): pass + metafunc = self.Metafunc(func) + assert len(metafunc.fixturenames) == 1 + assert 'arg1' in metafunc.fixturenames + assert metafunc.function is func + assert metafunc.cls is None + + def test_addcall_no_args(self): + def func(arg1): pass + metafunc = self.Metafunc(func) + metafunc.addcall() + assert len(metafunc._calls) == 1 + call = metafunc._calls[0] + assert call.id == "0" + assert not hasattr(call, 'param') + + def test_addcall_id(self): + def func(arg1): pass + metafunc = self.Metafunc(func) + pytest.raises(ValueError, "metafunc.addcall(id=None)") + + metafunc.addcall(id=1) + pytest.raises(ValueError, "metafunc.addcall(id=1)") + pytest.raises(ValueError, "metafunc.addcall(id='1')") + metafunc.addcall(id=2) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].id == "1" + assert metafunc._calls[1].id == "2" + + def test_addcall_param(self): + def func(arg1): pass + metafunc = self.Metafunc(func) + class obj: pass + metafunc.addcall(param=obj) + metafunc.addcall(param=obj) + metafunc.addcall(param=1) + assert len(metafunc._calls) == 3 + assert metafunc._calls[0].getparam("arg1") == obj + assert metafunc._calls[1].getparam("arg1") == obj + assert metafunc._calls[2].getparam("arg1") == 1 + + def test_addcall_funcargs(self): + def func(x): pass + metafunc = self.Metafunc(func) + class obj: pass + metafunc.addcall(funcargs={"x": 2}) + metafunc.addcall(funcargs={"x": 3}) + pytest.raises(pytest.fail.Exception, "metafunc.addcall({'xyz': 0})") + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == {'x': 2} + assert metafunc._calls[1].funcargs == {'x': 3} + assert not hasattr(metafunc._calls[1], 'param') + + def test_parametrize_error(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.parametrize("x", [1,2]) + pytest.raises(ValueError, lambda: metafunc.parametrize("x", [5,6])) + pytest.raises(ValueError, lambda: metafunc.parametrize("x", [5,6])) + metafunc.parametrize("y", [1,2]) + pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6])) + pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6])) + + def test_parametrize_and_id(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + + metafunc.parametrize("x", [1,2], ids=['basic', 'advanced']) + metafunc.parametrize("y", ["abc", "def"]) + ids = [x.id for x in metafunc._calls] + assert ids == ["basic-abc", "basic-def", "advanced-abc", "advanced-def"] + + def test_parametrize_with_userobjects(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + class A: + pass + metafunc.parametrize("x", [A(), A()]) + metafunc.parametrize("y", list("ab")) + assert metafunc._calls[0].id == "x0-a" + assert metafunc._calls[1].id == "x0-b" + assert metafunc._calls[2].id == "x1-a" + assert metafunc._calls[3].id == "x1-b" + + def test_idmaker_autoname(self): + from _pytest.python import idmaker + result = idmaker(("a", "b"), [("string", 1.0), + ("st-ring", 2.0)]) + assert result == ["string-1.0", "st-ring-2.0"] + + result = idmaker(("a", "b"), [(object(), 1.0), + (object(), object())]) + assert result == ["a0-1.0", "a1-b1"] + + + def test_addcall_and_parametrize(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.addcall({'x': 1}) + metafunc.parametrize('y', [2,3]) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == {'x': 1, 'y': 2} + assert metafunc._calls[1].funcargs == {'x': 1, 'y': 3} + assert metafunc._calls[0].id == "0-2" + assert metafunc._calls[1].id == "0-3" + + def test_parametrize_indirect(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.parametrize('x', [1], indirect=True) + metafunc.parametrize('y', [2,3], indirect=True) + metafunc.parametrize('unnamed', [1], indirect=True) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == {} + assert metafunc._calls[1].funcargs == {} + assert metafunc._calls[0].params == dict(x=1,y=2, unnamed=1) + assert metafunc._calls[1].params == dict(x=1,y=3, unnamed=1) + + def test_addcalls_and_parametrize_indirect(self): + def func(x, y): pass + metafunc = self.Metafunc(func) + metafunc.addcall(param="123") + metafunc.parametrize('x', [1], indirect=True) + metafunc.parametrize('y', [2,3], indirect=True) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == {} + assert metafunc._calls[1].funcargs == {} + assert metafunc._calls[0].params == dict(x=1,y=2) + assert metafunc._calls[1].params == dict(x=1,y=3) + + def test_parametrize_functional(self, testdir): + testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.parametrize('x', [1,2], indirect=True) + metafunc.parametrize('y', [2]) + def pytest_funcarg__x(request): + return request.param * 10 + def pytest_funcarg__y(request): + return request.param + + def test_simple(x,y): + assert x in (10,20) + assert y == 2 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines([ + "*test_simple*1-2*", + "*test_simple*2-2*", + "*2 passed*", + ]) + + def test_parametrize_onearg(self): + metafunc = self.Metafunc(lambda x: None) + metafunc.parametrize("x", [1,2]) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == dict(x=1) + assert metafunc._calls[0].id == "1" + assert metafunc._calls[1].funcargs == dict(x=2) + assert metafunc._calls[1].id == "2" + + def test_parametrize_onearg_indirect(self): + metafunc = self.Metafunc(lambda x: None) + metafunc.parametrize("x", [1,2], indirect=True) + assert metafunc._calls[0].params == dict(x=1) + assert metafunc._calls[0].id == "1" + assert metafunc._calls[1].params == dict(x=2) + assert metafunc._calls[1].id == "2" + + def test_parametrize_twoargs(self): + metafunc = self.Metafunc(lambda x,y: None) + metafunc.parametrize(("x", "y"), [(1,2), (3,4)]) + assert len(metafunc._calls) == 2 + assert metafunc._calls[0].funcargs == dict(x=1, y=2) + assert metafunc._calls[0].id == "1-2" + assert metafunc._calls[1].funcargs == dict(x=3, y=4) + assert metafunc._calls[1].id == "3-4" + + def test_parametrize_multiple_times(self, testdir): + testdir.makepyfile(""" + import pytest + pytestmark = pytest.mark.parametrize("x", [1,2]) + def test_func(x): + assert 0, x + class TestClass: + pytestmark = pytest.mark.parametrize("y", [3,4]) + def test_meth(self, x, y): + assert 0, x + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*6 fail*", + ]) + + def test_parametrize_class_scenarios(self, testdir): + testdir.makepyfile(""" + # same as doc/en/example/parametrize scenario example + def pytest_generate_tests(metafunc): + idlist = [] + argvalues = [] + for scenario in metafunc.cls.scenarios: + idlist.append(scenario[0]) + items = scenario[1].items() + argnames = [x[0] for x in items] + argvalues.append(([x[1] for x in items])) + metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class") + + class Test(object): + scenarios = [['1', {'arg': {1: 2}, "arg2": "value2"}], + ['2', {'arg':'value2', "arg2": "value2"}]] + + def test_1(self, arg, arg2): + pass + + def test_2(self, arg2, arg): + pass + + def test_3(self, arg, arg2): + pass + """) + result = testdir.runpytest("-v") + assert result.ret == 0 + result.stdout.fnmatch_lines(""" + *test_1*1* + *test_2*1* + *test_3*1* + *test_1*2* + *test_2*2* + *test_3*2* + *6 passed* + """) + +class TestMetafuncFunctional: + def test_attributes(self, testdir): + p = testdir.makepyfile(""" + # assumes that generate/provide runs in the same process + import py, pytest + def pytest_generate_tests(metafunc): + metafunc.addcall(param=metafunc) + + def pytest_funcarg__metafunc(request): + assert request._pyfuncitem._genid == "0" + return request.param + + def test_function(metafunc, pytestconfig): + assert metafunc.config == pytestconfig + assert metafunc.module.__name__ == __name__ + assert metafunc.function == test_function + assert metafunc.cls is None + + class TestClass: + def test_method(self, metafunc, pytestconfig): + assert metafunc.config == pytestconfig + assert metafunc.module.__name__ == __name__ + if py.std.sys.version_info > (3, 0): + unbound = TestClass.test_method + else: + unbound = TestClass.test_method.im_func + # XXX actually have an unbound test function here? + assert metafunc.function == unbound + assert metafunc.cls == TestClass + """) + result = testdir.runpytest(p, "-v") + result.stdout.fnmatch_lines([ + "*2 passed in*", + ]) + + def test_addcall_with_two_funcargs_generators(self, testdir): + testdir.makeconftest(""" + def pytest_generate_tests(metafunc): + assert "arg1" in metafunc.fixturenames + metafunc.addcall(funcargs=dict(arg1=1, arg2=2)) + """) + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall(funcargs=dict(arg1=1, arg2=1)) + + class TestClass: + def test_myfunc(self, arg1, arg2): + assert arg1 == arg2 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_myfunc*0*PASS*", + "*test_myfunc*1*FAIL*", + "*1 failed, 1 passed*" + ]) + + def test_two_functions(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall(param=10) + metafunc.addcall(param=20) + + def pytest_funcarg__arg1(request): + return request.param + + def test_func1(arg1): + assert arg1 == 10 + def test_func2(arg1): + assert arg1 in (10, 20) + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_func1*0*PASS*", + "*test_func1*1*FAIL*", + "*test_func2*PASS*", + "*1 failed, 3 passed*" + ]) + + def test_noself_in_method(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + assert 'xyz' not in metafunc.fixturenames + + class TestHello: + def test_hello(xyz): + pass + """) + result = testdir.runpytest(p) + result.stdout.fnmatch_lines([ + "*1 pass*", + ]) + + + def test_generate_plugin_and_module(self, testdir): + testdir.makeconftest(""" + def pytest_generate_tests(metafunc): + assert "arg1" in metafunc.fixturenames + metafunc.addcall(id="world", param=(2,100)) + """) + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall(param=(1,1), id="hello") + + def pytest_funcarg__arg1(request): + return request.param[0] + def pytest_funcarg__arg2(request): + return request.param[1] + + class TestClass: + def test_myfunc(self, arg1, arg2): + assert arg1 == arg2 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_myfunc*hello*PASS*", + "*test_myfunc*world*FAIL*", + "*1 failed, 1 passed*" + ]) + + def test_generate_tests_in_class(self, testdir): + p = testdir.makepyfile(""" + class TestClass: + def pytest_generate_tests(self, metafunc): + metafunc.addcall(funcargs={'hello': 'world'}, id="hello") + + def test_myfunc(self, hello): + assert hello == "world" + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_myfunc*hello*PASS*", + "*1 passed*" + ]) + + def test_two_functions_not_same_instance(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall({'arg1': 10}) + metafunc.addcall({'arg1': 20}) + + class TestClass: + def test_func(self, arg1): + assert not hasattr(self, 'x') + self.x = 1 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_func*0*PASS*", + "*test_func*1*PASS*", + "*2 pass*", + ]) + + def test_issue28_setup_method_in_generate_tests(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.addcall({'arg1': 1}) + + class TestClass: + def test_method(self, arg1): + assert arg1 == self.val + def setup_method(self, func): + self.val = 1 + """) + result = testdir.runpytest(p) + result.stdout.fnmatch_lines([ + "*1 pass*", + ]) + + def test_parametrize_functional2(self, testdir): + testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.parametrize("arg1", [1,2]) + metafunc.parametrize("arg2", [4,5]) + def test_hello(arg1, arg2): + assert 0, (arg1, arg2) + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*(1, 4)*", + "*(1, 5)*", + "*(2, 4)*", + "*(2, 5)*", + "*4 failed*", + ]) + + def test_parametrize_and_inner_getfuncargvalue(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + metafunc.parametrize("arg1", [1], indirect=True) + metafunc.parametrize("arg2", [10], indirect=True) + + def pytest_funcarg__arg1(request): + x = request.getfuncargvalue("arg2") + return x + request.param + + def pytest_funcarg__arg2(request): + return request.param + + def test_func1(arg1, arg2): + assert arg1 == 11 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_func1*1*PASS*", + "*1 passed*" + ]) + + def test_parametrize_on_setup_arg(self, testdir): + p = testdir.makepyfile(""" + def pytest_generate_tests(metafunc): + assert "arg1" in metafunc.fixturenames + metafunc.parametrize("arg1", [1], indirect=True) + + def pytest_funcarg__arg1(request): + return request.param + + def pytest_funcarg__arg2(request, arg1): + return 10 * arg1 + + def test_func(arg2): + assert arg2 == 10 + """) + result = testdir.runpytest("-v", p) + result.stdout.fnmatch_lines([ + "*test_func*1*PASS*", + "*1 passed*" + ]) + + def test_parametrize_with_ids(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + metafunc.parametrize(("a", "b"), [(1,1), (1,2)], + ids=["basic", "advanced"]) + + def test_function(a, b): + assert a == b + """) + result = testdir.runpytest("-v") + assert result.ret == 1 + result.stdout.fnmatch_lines_random([ + "*test_function*basic*PASSED", + "*test_function*advanced*FAILED", + ]) + + def test_parametrize_without_ids(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + metafunc.parametrize(("a", "b"), + [(1,object()), (1.3,object())]) + + def test_function(a, b): + assert 1 + """) + result = testdir.runpytest("-v") + result.stdout.fnmatch_lines(""" + *test_function*1-b0* + *test_function*1.3-b1* + """) + + + + @pytest.mark.parametrize(("scope", "length"), + [("module", 2), ("function", 4)]) + def test_parametrize_scope_overrides(self, testdir, scope, length): + testdir.makepyfile(""" + import pytest + l = [] + def pytest_generate_tests(metafunc): + if "arg" in metafunc.funcargnames: + metafunc.parametrize("arg", [1,2], indirect=True, + scope=%r) + def pytest_funcarg__arg(request): + l.append(request.param) + return request.param + def test_hello(arg): + assert arg in (1,2) + def test_world(arg): + assert arg in (1,2) + def test_checklength(): + assert len(l) == %d + """ % (scope, length)) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=5) + + def test_usefixtures_seen_in_generate_tests(self, testdir): + testdir.makepyfile(""" + import pytest + def pytest_generate_tests(metafunc): + assert "abc" in metafunc.fixturenames + metafunc.parametrize("abc", [1]) + + @pytest.mark.usefixtures("abc") + def test_function(): + pass + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_generate_tests_only_done_in_subdir(self, testdir): + sub1 = testdir.mkpydir("sub1") + sub2 = testdir.mkpydir("sub2") + sub1.join("conftest.py").write(py.code.Source(""" + def pytest_generate_tests(metafunc): + assert metafunc.function.__name__ == "test_1" + """)) + sub2.join("conftest.py").write(py.code.Source(""" + def pytest_generate_tests(metafunc): + assert metafunc.function.__name__ == "test_2" + """)) + sub1.join("test_in_sub1.py").write("def test_1(): pass") + sub2.join("test_in_sub2.py").write("def test_2(): pass") + result = testdir.runpytest("-v", "-s", sub1, sub2, sub1) + result.stdout.fnmatch_lines([ + "*3 passed*" + ]) + + diff -r aadd426bdd8ca896314b29f1802fae58b7684cea -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c testing/python/raises.py --- /dev/null +++ b/testing/python/raises.py @@ -0,0 +1,64 @@ +import pytest + +class TestRaises: + def test_raises(self): + source = "int('qwe')" + excinfo = pytest.raises(ValueError, source) + code = excinfo.traceback[-1].frame.code + s = str(code.fullsource) + assert s == source + + def test_raises_exec(self): + pytest.raises(ValueError, "a,x = []") + + def test_raises_syntax_error(self): + pytest.raises(SyntaxError, "qwe qwe qwe") + + def test_raises_function(self): + pytest.raises(ValueError, int, 'hello') + + def test_raises_callable_no_exception(self): + class A: + def __call__(self): + pass + try: + pytest.raises(ValueError, A()) + except pytest.raises.Exception: + pass + + def test_raises_flip_builtin_AssertionError(self): + # we replace AssertionError on python level + # however c code might still raise the builtin one + from _pytest.assertion.util import BuiltinAssertionError + pytest.raises(AssertionError,""" + raise BuiltinAssertionError + """) + + @pytest.mark.skipif('sys.version < "2.5"') + def test_raises_as_contextmanager(self, testdir): + testdir.makepyfile(""" + from __future__ import with_statement + import py, pytest + + def test_simple(): + with pytest.raises(ZeroDivisionError) as excinfo: + assert isinstance(excinfo, py.code.ExceptionInfo) + 1/0 + print (excinfo) + assert excinfo.type == ZeroDivisionError + + def test_noraise(): + with pytest.raises(pytest.raises.Exception): + with pytest.raises(ValueError): + int() + + def test_raise_wrong_exception_passes_by(): + with pytest.raises(ZeroDivisionError): + with pytest.raises(ValueError): + 1/0 + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + '*3 passed*', + ]) + diff -r aadd426bdd8ca896314b29f1802fae58b7684cea -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c testing/test_python.py --- a/testing/test_python.py +++ /dev/null @@ -1,3143 +0,0 @@ -import pytest, py, sys -from _pytest import python as funcargs -from _pytest.python import FixtureLookupError - -class TestModule: - def test_failing_import(self, testdir): - modcol = testdir.getmodulecol("import alksdjalskdjalkjals") - pytest.raises(ImportError, modcol.collect) - pytest.raises(ImportError, modcol.collect) - - def test_import_duplicate(self, testdir): - a = testdir.mkdir("a") - b = testdir.mkdir("b") - p = a.ensure("test_whatever.py") - p.pyimport() - del py.std.sys.modules['test_whatever'] - b.ensure("test_whatever.py") - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - "*import*mismatch*", - "*imported*test_whatever*", - "*%s*" % a.join("test_whatever.py"), - "*not the same*", - "*%s*" % b.join("test_whatever.py"), - "*HINT*", - ]) - - def test_syntax_error_in_module(self, testdir): - modcol = testdir.getmodulecol("this is a syntax error") - pytest.raises(modcol.CollectError, modcol.collect) - pytest.raises(modcol.CollectError, modcol.collect) - - def test_module_considers_pluginmanager_at_import(self, testdir): - modcol = testdir.getmodulecol("pytest_plugins='xasdlkj',") - pytest.raises(ImportError, "modcol.obj") - -class TestClass: - def test_class_with_init_not_collected(self, testdir): - modcol = testdir.getmodulecol(""" - class TestClass1: - def __init__(self): - pass - class TestClass2(object): - def __init__(self): - pass - """) - l = modcol.collect() - assert len(l) == 0 - - def test_class_subclassobject(self, testdir): - testdir.getmodulecol(""" - class test(object): - pass - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - "*collected 0*", - ]) - - def test_setup_teardown_class_as_classmethod(self, testdir): - testdir.makepyfile(test_mod1=""" - class TestClassMethod: - @classmethod - def setup_class(cls): - pass - def test_1(self): - pass - @classmethod - def teardown_class(cls): - pass - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - "*1 passed*", - ]) - - -class TestGenerator: - 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: - 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: - 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(""" - 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(): - py.builtin.print_('expected order', expected_list) - py.builtin.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) - 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(""" - 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(): - py.builtin.print_('expected order', expected_list) - py.builtin.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) - 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: - 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') - passed, skipped, failed = reprec.countoutcomes() - assert passed == 4 - assert not skipped and not failed - - -class TestFunction: - def test_getmodulecollector(self, testdir): - item = testdir.getitem("def test_func(): pass") - modcol = item.getparent(pytest.Module) - assert isinstance(modcol, pytest.Module) - assert hasattr(modcol.obj, 'test_func') - - def test_function_equality(self, testdir, tmpdir): - from _pytest.python import FixtureManager - config = testdir.parseconfigure() - session = testdir.Session(config) - session._fixturemanager = FixtureManager(session) - def func1(): - pass - def func2(): - pass - f1 = pytest.Function(name="name", parent=session, config=config, - args=(1,), callobj=func1) - f2 = pytest.Function(name="name",config=config, - args=(1,), callobj=func2, parent=session) - assert not f1 == f2 - assert f1 != f2 - f3 = pytest.Function(name="name", parent=session, config=config, - args=(1,2), callobj=func2) - assert not f3 == f2 - assert f3 != f2 - - assert not f3 == f1 - assert f3 != f1 - - f1_b = pytest.Function(name="name", parent=session, config=config, - args=(1,), callobj=func1) - assert f1 == f1_b - assert not f1 != f1_b - - def test_issue197_parametrize_emptyset(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.mark.parametrize('arg', []) - def test_function(arg): - pass - """) - reprec = testdir.inline_run() - reprec.assertoutcome(skipped=1) - - def test_issue213_parametrize_value_no_equal(self, testdir): - testdir.makepyfile(""" - import pytest - class A: - def __eq__(self, other): - raise ValueError("not possible") - @pytest.mark.parametrize('arg', [A()]) - def test_function(arg): - assert arg.__class__.__name__ == "A" - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - def test_function_equality_with_callspec(self, testdir, tmpdir): - items = testdir.getitems(""" - import pytest - @pytest.mark.parametrize('arg', [1,2]) - def test_function(arg): - pass - """) - assert items[0] != items[1] - assert not (items[0] == items[1]) - - def test_pyfunc_call(self, testdir): - item = testdir.getitem("def test_func(): raise ValueError") - config = item.config - class MyPlugin1: - def pytest_pyfunc_call(self, pyfuncitem): - raise ValueError - class MyPlugin2: - def pytest_pyfunc_call(self, pyfuncitem): - return True - config.pluginmanager.register(MyPlugin1()) - config.pluginmanager.register(MyPlugin2()) - config.hook.pytest_pyfunc_call(pyfuncitem=item) - -class TestSorting: - def test_check_equality(self, testdir): - modcol = testdir.getmodulecol(""" - def test_pass(): pass - def test_fail(): assert 0 - """) - fn1 = testdir.collect_by_name(modcol, "test_pass") - assert isinstance(fn1, pytest.Function) - fn2 = testdir.collect_by_name(modcol, "test_pass") - assert isinstance(fn2, pytest.Function) - - assert fn1 == fn2 - assert fn1 != modcol - if py.std.sys.version_info < (3, 0): - assert cmp(fn1, fn2) == 0 - assert hash(fn1) == hash(fn2) - - fn3 = testdir.collect_by_name(modcol, "test_fail") - assert isinstance(fn3, pytest.Function) - assert not (fn1 == fn3) - assert fn1 != fn3 - - for fn in fn1,fn2,fn3: - assert fn != 3 - assert fn != modcol - assert fn != [1,2,3] - assert [1,2,3] != fn - assert modcol != fn - - def test_allow_sane_sorting_for_decorators(self, testdir): - modcol = testdir.getmodulecol(""" - def dec(f): - g = lambda: f(2) - g.place_as = f - return g - - - def test_b(y): - pass - test_b = dec(test_b) - - def test_a(y): - pass - test_a = dec(test_a) - """) - colitems = modcol.collect() - assert len(colitems) == 2 - assert [item.name for item in colitems] == ['test_b', 'test_a'] - - -class TestConftestCustomization: - def test_pytest_pycollect_module(self, testdir): - testdir.makeconftest(""" - import pytest - class MyModule(pytest.Module): - pass - def pytest_pycollect_makemodule(path, parent): - if path.basename == "test_xyz.py": - return MyModule(path, parent) - """) - testdir.makepyfile("def test_some(): pass") - testdir.makepyfile(test_xyz="def test_func(): pass") - result = testdir.runpytest("--collectonly") - result.stdout.fnmatch_lines([ - "* 3 - - def test_traceback_error_during_import(self, testdir): - testdir.makepyfile(""" - x = 1 - x = 2 - x = 17 - asd - """) - result = testdir.runpytest() - assert result.ret != 0 - out = result.stdout.str() - assert "x = 1" not in out - assert "x = 2" not in out - result.stdout.fnmatch_lines([ - ">*asd*", - "E*NameError*", - ]) - result = testdir.runpytest("--fulltrace") - out = result.stdout.str() - assert "x = 1" in out - assert "x = 2" in out - result.stdout.fnmatch_lines([ - ">*asd*", - "E*NameError*", - ]) - -def test_getfuncargnames(): - def f(): pass - assert not funcargs.getfuncargnames(f) - def g(arg): pass - assert funcargs.getfuncargnames(g) == ('arg',) - def h(arg1, arg2="hello"): pass - assert funcargs.getfuncargnames(h) == ('arg1',) - def h(arg1, arg2, arg3="hello"): pass - assert funcargs.getfuncargnames(h) == ('arg1', 'arg2') - class A: - def f(self, arg1, arg2="hello"): - pass - assert funcargs.getfuncargnames(A().f) == ('arg1',) - if sys.version_info < (3,0): - assert funcargs.getfuncargnames(A.f) == ('arg1',) - - -class TestFillFixtures: - def test_fillfuncargs_exposed(self): - # used by oejskit, kept for compatibility - assert pytest._fillfuncargs == funcargs.fillfixtures - - def test_funcarg_lookupfails(self, testdir): - testdir.makepyfile(""" - def pytest_funcarg__xyzsomething(request): - return 42 - - def test_func(some): - pass - """) - result = testdir.runpytest() # "--collectonly") - assert result.ret != 0 - result.stdout.fnmatch_lines([ - "*def test_func(some)*", - "*fixture*some*not found*", - "*xyzsomething*", - ]) - - def test_funcarg_basic(self, testdir): - item = testdir.getitem(""" - def pytest_funcarg__some(request): - return request.function.__name__ - def pytest_funcarg__other(request): - return 42 - def test_func(some, other): - pass - """) - funcargs.fillfixtures(item) - del item.funcargs["request"] - assert len(item.funcargs) == 2 - assert item.funcargs['some'] == "test_func" - assert item.funcargs['other'] == 42 - - def test_funcarg_lookup_modulelevel(self, testdir): - testdir.makepyfile(""" - def pytest_funcarg__something(request): - return request.function.__name__ - - class TestClass: - def test_method(self, something): - assert something == "test_method" - def test_func(something): - assert something == "test_func" - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=2) - - def test_funcarg_lookup_classlevel(self, testdir): - p = testdir.makepyfile(""" - class TestClass: - def pytest_funcarg__something(self, request): - return request.instance - def test_method(self, something): - assert something is self - """) - result = testdir.runpytest(p) - result.stdout.fnmatch_lines([ - "*1 passed*" - ]) - - -class TestRequest: - def test_request_attributes(self, testdir): - item = testdir.getitem(""" - def pytest_funcarg__something(request): pass - def test_func(something): pass - """) - req = funcargs.FixtureRequest(item) - assert req.function == item.obj - assert req.keywords == item.keywords - assert hasattr(req.module, 'test_func') - assert req.cls is None - assert req.function.__name__ == "test_func" - assert req.config == item.config - assert repr(req).find(req.function.__name__) != -1 - - def test_request_attributes_method(self, testdir): - item, = testdir.getitems(""" - class TestB: - def pytest_funcarg__something(self, request): - return 1 - def test_func(self, something): - pass - """) - req = item._request - assert req.cls.__name__ == "TestB" - assert req.instance.__class__ == req.cls - - def XXXtest_request_contains_funcarg_arg2fixturedefs(self, testdir): - modcol = testdir.getmodulecol(""" - def pytest_funcarg__something(request): - pass - class TestClass: - def test_method(self, something): - pass - """) - item1, = testdir.genitems([modcol]) - assert item1.name == "test_method" - arg2fixturedefs = funcargs.FixtureRequest(item1)._arg2fixturedefs - assert len(arg2fixturedefs) == 1 - assert arg2fixturedefs[0].__name__ == "pytest_funcarg__something" - - def test_getfuncargvalue_recursive(self, testdir): - testdir.makeconftest(""" - def pytest_funcarg__something(request): - return 1 - """) - item = testdir.makepyfile(""" - def pytest_funcarg__something(request): - return request.getfuncargvalue("something") + 1 - def test_func(something): - assert something == 2 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - def test_getfuncargvalue(self, testdir): - item = testdir.getitem(""" - l = [2] - def pytest_funcarg__something(request): return 1 - def pytest_funcarg__other(request): - return l.pop() - def test_func(something): pass - """) - req = item._request - pytest.raises(FixtureLookupError, req.getfuncargvalue, "notexists") - val = req.getfuncargvalue("something") - assert val == 1 - val = req.getfuncargvalue("something") - assert val == 1 - val2 = req.getfuncargvalue("other") - assert val2 == 2 - val2 = req.getfuncargvalue("other") # see about caching - assert val2 == 2 - pytest._fillfuncargs(item) - assert item.funcargs["something"] == 1 - assert len(item.funcargs) == 2 - assert "request" in item.funcargs - #assert item.funcargs == {'something': 1, "other": 2} - - def test_request_addfinalizer(self, testdir): - item = testdir.getitem(""" - teardownlist = [] - def pytest_funcarg__something(request): - request.addfinalizer(lambda: teardownlist.append(1)) - def test_func(something): pass - """) - item.session._setupstate.prepare(item) - pytest._fillfuncargs(item) - # successively check finalization calls - teardownlist = item.getparent(pytest.Module).obj.teardownlist - ss = item.session._setupstate - assert not teardownlist - ss.teardown_exact(item, None) - print(ss.stack) - assert teardownlist == [1] - - def test_request_addfinalizer_partial_setup_failure(self, testdir): - p = testdir.makepyfile(""" - l = [] - def pytest_funcarg__something(request): - request.addfinalizer(lambda: l.append(None)) - def test_func(something, missingarg): - pass - def test_second(): - assert len(l) == 1 - """) - result = testdir.runpytest(p) - result.stdout.fnmatch_lines([ - "*1 error*" # XXX the whole module collection fails - ]) - - def test_request_getmodulepath(self, testdir): - modcol = testdir.getmodulecol("def test_somefunc(): pass") - item, = testdir.genitems([modcol]) - req = funcargs.FixtureRequest(item) - assert req.fspath == modcol.fspath - -class TestMarking: - def test_applymarker(self, testdir): - item1,item2 = testdir.getitems(""" - def pytest_funcarg__something(request): - pass - class TestClass: - def test_func1(self, something): - pass - def test_func2(self, something): - pass - """) - req1 = funcargs.FixtureRequest(item1) - assert 'xfail' not in item1.keywords - req1.applymarker(pytest.mark.xfail) - assert 'xfail' in item1.keywords - assert 'skipif' not in item1.keywords - req1.applymarker(pytest.mark.skipif) - assert 'skipif' in item1.keywords - pytest.raises(ValueError, "req1.applymarker(42)") - - def test_accesskeywords(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture() - def keywords(request): - return request.keywords - @pytest.mark.XYZ - def test_function(keywords): - assert keywords["XYZ"] - assert "abc" not in keywords - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - def test_accessmarker_dynamic(self, testdir): - testdir.makeconftest(""" - import pytest - @pytest.fixture() - def keywords(request): - return request.keywords - - @pytest.fixture(scope="class", autouse=True) - def marking(request): - request.applymarker(pytest.mark.XYZ("hello")) - """) - testdir.makepyfile(""" - import pytest - def test_fun1(keywords): - assert keywords["XYZ"] is not None - assert "abc" not in keywords - def test_fun2(keywords): - assert keywords["XYZ"] is not None - assert "abc" not in keywords - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=2) - - -class TestRequestCachedSetup: - def test_request_cachedsetup_defaultmodule(self, testdir): - reprec = testdir.inline_runsource(""" - mysetup = ["hello",].pop - - def pytest_funcarg__something(request): - return request.cached_setup(mysetup, scope="module") - - def test_func1(something): - assert something == "hello" - class TestClass: - def test_func1a(self, something): - assert something == "hello" - """) - reprec.assertoutcome(passed=2) - - def test_request_cachedsetup_class(self, testdir): - reprec = testdir.inline_runsource(""" - mysetup = ["hello", "hello2"].pop - - def pytest_funcarg__something(request): - return request.cached_setup(mysetup, scope="class") - def test_func1(something): - assert something == "hello2" - def test_func2(something): - assert something == "hello2" - class TestClass: - def test_func1a(self, something): - assert something == "hello" - def test_func2b(self, something): - assert something == "hello" - """) - reprec.assertoutcome(passed=4) - - def test_request_cachedsetup_extrakey(self, testdir): - item1 = testdir.getitem("def test_func(): pass") - req1 = funcargs.FixtureRequest(item1) - l = ["hello", "world"] - def setup(): - return l.pop() - ret1 = req1.cached_setup(setup, extrakey=1) - ret2 = req1.cached_setup(setup, extrakey=2) - assert ret2 == "hello" - assert ret1 == "world" - ret1b = req1.cached_setup(setup, extrakey=1) - ret2b = req1.cached_setup(setup, extrakey=2) - assert ret1 == ret1b - assert ret2 == ret2b - - def test_request_cachedsetup_cache_deletion(self, testdir): - item1 = testdir.getitem("def test_func(): pass") - req1 = funcargs.FixtureRequest(item1) - l = [] - def setup(): - l.append("setup") - def teardown(val): - l.append("teardown") - ret1 = req1.cached_setup(setup, teardown, scope="function") - assert l == ['setup'] - # artificial call of finalizer - setupstate = req1._pyfuncitem.session._setupstate - setupstate._callfinalizers(item1) - assert l == ["setup", "teardown"] - ret2 = req1.cached_setup(setup, teardown, scope="function") - assert l == ["setup", "teardown", "setup"] - setupstate._callfinalizers(item1) - assert l == ["setup", "teardown", "setup", "teardown"] - - def test_request_cached_setup_two_args(self, testdir): - testdir.makepyfile(""" - def pytest_funcarg__arg1(request): - return request.cached_setup(lambda: 42) - def pytest_funcarg__arg2(request): - return request.cached_setup(lambda: 17) - def test_two_different_setups(arg1, arg2): - assert arg1 != arg2 - """) - result = testdir.runpytest("-v") - result.stdout.fnmatch_lines([ - "*1 passed*" - ]) - - def test_request_cached_setup_getfuncargvalue(self, testdir): - testdir.makepyfile(""" - def pytest_funcarg__arg1(request): - arg1 = request.getfuncargvalue("arg2") - return request.cached_setup(lambda: arg1 + 1) - def pytest_funcarg__arg2(request): - return request.cached_setup(lambda: 10) - def test_two_funcarg(arg1): - assert arg1 == 11 - """) - result = testdir.runpytest("-v") - result.stdout.fnmatch_lines([ - "*1 passed*" - ]) - - def test_request_cached_setup_functional(self, testdir): - testdir.makepyfile(test_0=""" - l = [] - def pytest_funcarg__something(request): - val = request.cached_setup(fsetup, fteardown) - return val - def fsetup(mycache=[1]): - l.append(mycache.pop()) - return l - def fteardown(something): - l.remove(something[0]) - l.append(2) - def test_list_once(something): - assert something == [1] - def test_list_twice(something): - assert something == [1] - """) - testdir.makepyfile(test_1=""" - import test_0 # should have run already - def test_check_test0_has_teardown_correct(): - assert test_0.l == [2] - """) - result = testdir.runpytest("-v") - result.stdout.fnmatch_lines([ - "*3 passed*" - ]) - -class TestMetafunc: - def Metafunc(self, func): - # the unit tests of this class check if things work correctly - # on the funcarg level, so we don't need a full blown - # initiliazation - class FixtureInfo: - name2fixturedefs = None - def __init__(self, names): - self.names_closure = names - names = funcargs.getfuncargnames(func) - fixtureinfo = FixtureInfo(names) - return funcargs.Metafunc(func, fixtureinfo, None) - - def test_no_funcargs(self, testdir): - def function(): pass - metafunc = self.Metafunc(function) - assert not metafunc.fixturenames - repr(metafunc._calls) - - def test_function_basic(self): - def func(arg1, arg2="qwe"): pass - metafunc = self.Metafunc(func) - assert len(metafunc.fixturenames) == 1 - assert 'arg1' in metafunc.fixturenames - assert metafunc.function is func - assert metafunc.cls is None - - def test_addcall_no_args(self): - def func(arg1): pass - metafunc = self.Metafunc(func) - metafunc.addcall() - assert len(metafunc._calls) == 1 - call = metafunc._calls[0] - assert call.id == "0" - assert not hasattr(call, 'param') - - def test_addcall_id(self): - def func(arg1): pass - metafunc = self.Metafunc(func) - pytest.raises(ValueError, "metafunc.addcall(id=None)") - - metafunc.addcall(id=1) - pytest.raises(ValueError, "metafunc.addcall(id=1)") - pytest.raises(ValueError, "metafunc.addcall(id='1')") - metafunc.addcall(id=2) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].id == "1" - assert metafunc._calls[1].id == "2" - - def test_addcall_param(self): - def func(arg1): pass - metafunc = self.Metafunc(func) - class obj: pass - metafunc.addcall(param=obj) - metafunc.addcall(param=obj) - metafunc.addcall(param=1) - assert len(metafunc._calls) == 3 - assert metafunc._calls[0].getparam("arg1") == obj - assert metafunc._calls[1].getparam("arg1") == obj - assert metafunc._calls[2].getparam("arg1") == 1 - - def test_addcall_funcargs(self): - def func(x): pass - metafunc = self.Metafunc(func) - class obj: pass - metafunc.addcall(funcargs={"x": 2}) - metafunc.addcall(funcargs={"x": 3}) - pytest.raises(pytest.fail.Exception, "metafunc.addcall({'xyz': 0})") - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == {'x': 2} - assert metafunc._calls[1].funcargs == {'x': 3} - assert not hasattr(metafunc._calls[1], 'param') - - def test_parametrize_error(self): - def func(x, y): pass - metafunc = self.Metafunc(func) - metafunc.parametrize("x", [1,2]) - pytest.raises(ValueError, lambda: metafunc.parametrize("x", [5,6])) - pytest.raises(ValueError, lambda: metafunc.parametrize("x", [5,6])) - metafunc.parametrize("y", [1,2]) - pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6])) - pytest.raises(ValueError, lambda: metafunc.parametrize("y", [5,6])) - - def test_parametrize_and_id(self): - def func(x, y): pass - metafunc = self.Metafunc(func) - - metafunc.parametrize("x", [1,2], ids=['basic', 'advanced']) - metafunc.parametrize("y", ["abc", "def"]) - ids = [x.id for x in metafunc._calls] - assert ids == ["basic-abc", "basic-def", "advanced-abc", "advanced-def"] - - def test_parametrize_with_userobjects(self): - def func(x, y): pass - metafunc = self.Metafunc(func) - class A: - pass - metafunc.parametrize("x", [A(), A()]) - metafunc.parametrize("y", list("ab")) - assert metafunc._calls[0].id == "x0-a" - assert metafunc._calls[1].id == "x0-b" - assert metafunc._calls[2].id == "x1-a" - assert metafunc._calls[3].id == "x1-b" - - def test_idmaker_autoname(self): - from _pytest.python import idmaker - result = idmaker(("a", "b"), [("string", 1.0), - ("st-ring", 2.0)]) - assert result == ["string-1.0", "st-ring-2.0"] - - result = idmaker(("a", "b"), [(object(), 1.0), - (object(), object())]) - assert result == ["a0-1.0", "a1-b1"] - - - def test_addcall_and_parametrize(self): - def func(x, y): pass - metafunc = self.Metafunc(func) - metafunc.addcall({'x': 1}) - metafunc.parametrize('y', [2,3]) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == {'x': 1, 'y': 2} - assert metafunc._calls[1].funcargs == {'x': 1, 'y': 3} - assert metafunc._calls[0].id == "0-2" - assert metafunc._calls[1].id == "0-3" - - def test_parametrize_indirect(self): - def func(x, y): pass - metafunc = self.Metafunc(func) - metafunc.parametrize('x', [1], indirect=True) - metafunc.parametrize('y', [2,3], indirect=True) - metafunc.parametrize('unnamed', [1], indirect=True) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == {} - assert metafunc._calls[1].funcargs == {} - assert metafunc._calls[0].params == dict(x=1,y=2, unnamed=1) - assert metafunc._calls[1].params == dict(x=1,y=3, unnamed=1) - - def test_addcalls_and_parametrize_indirect(self): - def func(x, y): pass - metafunc = self.Metafunc(func) - metafunc.addcall(param="123") - metafunc.parametrize('x', [1], indirect=True) - metafunc.parametrize('y', [2,3], indirect=True) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == {} - assert metafunc._calls[1].funcargs == {} - assert metafunc._calls[0].params == dict(x=1,y=2) - assert metafunc._calls[1].params == dict(x=1,y=3) - - def test_parametrize_functional(self, testdir): - testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - metafunc.parametrize('x', [1,2], indirect=True) - metafunc.parametrize('y', [2]) - def pytest_funcarg__x(request): - return request.param * 10 - def pytest_funcarg__y(request): - return request.param - - def test_simple(x,y): - assert x in (10,20) - assert y == 2 - """) - result = testdir.runpytest("-v") - result.stdout.fnmatch_lines([ - "*test_simple*1-2*", - "*test_simple*2-2*", - "*2 passed*", - ]) - - def test_parametrize_onearg(self): - metafunc = self.Metafunc(lambda x: None) - metafunc.parametrize("x", [1,2]) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == dict(x=1) - assert metafunc._calls[0].id == "1" - assert metafunc._calls[1].funcargs == dict(x=2) - assert metafunc._calls[1].id == "2" - - def test_parametrize_onearg_indirect(self): - metafunc = self.Metafunc(lambda x: None) - metafunc.parametrize("x", [1,2], indirect=True) - assert metafunc._calls[0].params == dict(x=1) - assert metafunc._calls[0].id == "1" - assert metafunc._calls[1].params == dict(x=2) - assert metafunc._calls[1].id == "2" - - def test_parametrize_twoargs(self): - metafunc = self.Metafunc(lambda x,y: None) - metafunc.parametrize(("x", "y"), [(1,2), (3,4)]) - assert len(metafunc._calls) == 2 - assert metafunc._calls[0].funcargs == dict(x=1, y=2) - assert metafunc._calls[0].id == "1-2" - assert metafunc._calls[1].funcargs == dict(x=3, y=4) - assert metafunc._calls[1].id == "3-4" - - def test_parametrize_multiple_times(self, testdir): - testdir.makepyfile(""" - import pytest - pytestmark = pytest.mark.parametrize("x", [1,2]) - def test_func(x): - assert 0, x - class TestClass: - pytestmark = pytest.mark.parametrize("y", [3,4]) - def test_meth(self, x, y): - assert 0, x - """) - result = testdir.runpytest() - assert result.ret == 1 - result.stdout.fnmatch_lines([ - "*6 fail*", - ]) - - def test_parametrize_class_scenarios(self, testdir): - testdir.makepyfile(""" - # same as doc/en/example/parametrize scenario example - def pytest_generate_tests(metafunc): - idlist = [] - argvalues = [] - for scenario in metafunc.cls.scenarios: - idlist.append(scenario[0]) - items = scenario[1].items() - argnames = [x[0] for x in items] - argvalues.append(([x[1] for x in items])) - metafunc.parametrize(argnames, argvalues, ids=idlist, scope="class") - - class Test(object): - scenarios = [['1', {'arg': {1: 2}, "arg2": "value2"}], - ['2', {'arg':'value2', "arg2": "value2"}]] - - def test_1(self, arg, arg2): - pass - - def test_2(self, arg2, arg): - pass - - def test_3(self, arg, arg2): - pass - """) - result = testdir.runpytest("-v") - assert result.ret == 0 - result.stdout.fnmatch_lines(""" - *test_1*1* - *test_2*1* - *test_3*1* - *test_1*2* - *test_2*2* - *test_3*2* - *6 passed* - """) - -class TestMetafuncFunctional: - def test_attributes(self, testdir): - p = testdir.makepyfile(""" - # assumes that generate/provide runs in the same process - import py, pytest - def pytest_generate_tests(metafunc): - metafunc.addcall(param=metafunc) - - def pytest_funcarg__metafunc(request): - assert request._pyfuncitem._genid == "0" - return request.param - - def test_function(metafunc, pytestconfig): - assert metafunc.config == pytestconfig - assert metafunc.module.__name__ == __name__ - assert metafunc.function == test_function - assert metafunc.cls is None - - class TestClass: - def test_method(self, metafunc, pytestconfig): - assert metafunc.config == pytestconfig - assert metafunc.module.__name__ == __name__ - if py.std.sys.version_info > (3, 0): - unbound = TestClass.test_method - else: - unbound = TestClass.test_method.im_func - # XXX actually have an unbound test function here? - assert metafunc.function == unbound - assert metafunc.cls == TestClass - """) - result = testdir.runpytest(p, "-v") - result.stdout.fnmatch_lines([ - "*2 passed in*", - ]) - - def test_addcall_with_two_funcargs_generators(self, testdir): - testdir.makeconftest(""" - def pytest_generate_tests(metafunc): - assert "arg1" in metafunc.fixturenames - metafunc.addcall(funcargs=dict(arg1=1, arg2=2)) - """) - p = testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - metafunc.addcall(funcargs=dict(arg1=1, arg2=1)) - - class TestClass: - def test_myfunc(self, arg1, arg2): - assert arg1 == arg2 - """) - result = testdir.runpytest("-v", p) - result.stdout.fnmatch_lines([ - "*test_myfunc*0*PASS*", - "*test_myfunc*1*FAIL*", - "*1 failed, 1 passed*" - ]) - - def test_two_functions(self, testdir): - p = testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - metafunc.addcall(param=10) - metafunc.addcall(param=20) - - def pytest_funcarg__arg1(request): - return request.param - - def test_func1(arg1): - assert arg1 == 10 - def test_func2(arg1): - assert arg1 in (10, 20) - """) - result = testdir.runpytest("-v", p) - result.stdout.fnmatch_lines([ - "*test_func1*0*PASS*", - "*test_func1*1*FAIL*", - "*test_func2*PASS*", - "*1 failed, 3 passed*" - ]) - - def test_noself_in_method(self, testdir): - p = testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - assert 'xyz' not in metafunc.fixturenames - - class TestHello: - def test_hello(xyz): - pass - """) - result = testdir.runpytest(p) - result.stdout.fnmatch_lines([ - "*1 pass*", - ]) - - - def test_generate_plugin_and_module(self, testdir): - testdir.makeconftest(""" - def pytest_generate_tests(metafunc): - assert "arg1" in metafunc.fixturenames - metafunc.addcall(id="world", param=(2,100)) - """) - p = testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - metafunc.addcall(param=(1,1), id="hello") - - def pytest_funcarg__arg1(request): - return request.param[0] - def pytest_funcarg__arg2(request): - return request.param[1] - - class TestClass: - def test_myfunc(self, arg1, arg2): - assert arg1 == arg2 - """) - result = testdir.runpytest("-v", p) - result.stdout.fnmatch_lines([ - "*test_myfunc*hello*PASS*", - "*test_myfunc*world*FAIL*", - "*1 failed, 1 passed*" - ]) - - def test_generate_tests_in_class(self, testdir): - p = testdir.makepyfile(""" - class TestClass: - def pytest_generate_tests(self, metafunc): - metafunc.addcall(funcargs={'hello': 'world'}, id="hello") - - def test_myfunc(self, hello): - assert hello == "world" - """) - result = testdir.runpytest("-v", p) - result.stdout.fnmatch_lines([ - "*test_myfunc*hello*PASS*", - "*1 passed*" - ]) - - def test_two_functions_not_same_instance(self, testdir): - p = testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - metafunc.addcall({'arg1': 10}) - metafunc.addcall({'arg1': 20}) - - class TestClass: - def test_func(self, arg1): - assert not hasattr(self, 'x') - self.x = 1 - """) - result = testdir.runpytest("-v", p) - result.stdout.fnmatch_lines([ - "*test_func*0*PASS*", - "*test_func*1*PASS*", - "*2 pass*", - ]) - - def test_issue28_setup_method_in_generate_tests(self, testdir): - p = testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - metafunc.addcall({'arg1': 1}) - - class TestClass: - def test_method(self, arg1): - assert arg1 == self.val - def setup_method(self, func): - self.val = 1 - """) - result = testdir.runpytest(p) - result.stdout.fnmatch_lines([ - "*1 pass*", - ]) - - def test_parametrize_functional2(self, testdir): - testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - metafunc.parametrize("arg1", [1,2]) - metafunc.parametrize("arg2", [4,5]) - def test_hello(arg1, arg2): - assert 0, (arg1, arg2) - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - "*(1, 4)*", - "*(1, 5)*", - "*(2, 4)*", - "*(2, 5)*", - "*4 failed*", - ]) - - def test_parametrize_and_inner_getfuncargvalue(self, testdir): - p = testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - metafunc.parametrize("arg1", [1], indirect=True) - metafunc.parametrize("arg2", [10], indirect=True) - - def pytest_funcarg__arg1(request): - x = request.getfuncargvalue("arg2") - return x + request.param - - def pytest_funcarg__arg2(request): - return request.param - - def test_func1(arg1, arg2): - assert arg1 == 11 - """) - result = testdir.runpytest("-v", p) - result.stdout.fnmatch_lines([ - "*test_func1*1*PASS*", - "*1 passed*" - ]) - - def test_parametrize_on_setup_arg(self, testdir): - p = testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - assert "arg1" in metafunc.fixturenames - metafunc.parametrize("arg1", [1], indirect=True) - - def pytest_funcarg__arg1(request): - return request.param - - def pytest_funcarg__arg2(request, arg1): - return 10 * arg1 - - def test_func(arg2): - assert arg2 == 10 - """) - result = testdir.runpytest("-v", p) - result.stdout.fnmatch_lines([ - "*test_func*1*PASS*", - "*1 passed*" - ]) - - def test_parametrize_with_ids(self, testdir): - testdir.makepyfile(""" - import pytest - def pytest_generate_tests(metafunc): - metafunc.parametrize(("a", "b"), [(1,1), (1,2)], - ids=["basic", "advanced"]) - - def test_function(a, b): - assert a == b - """) - result = testdir.runpytest("-v") - assert result.ret == 1 - result.stdout.fnmatch_lines_random([ - "*test_function*basic*PASSED", - "*test_function*advanced*FAILED", - ]) - - def test_parametrize_without_ids(self, testdir): - testdir.makepyfile(""" - import pytest - def pytest_generate_tests(metafunc): - metafunc.parametrize(("a", "b"), - [(1,object()), (1.3,object())]) - - def test_function(a, b): - assert 1 - """) - result = testdir.runpytest("-v") - result.stdout.fnmatch_lines(""" - *test_function*1-b0* - *test_function*1.3-b1* - """) - - - - @pytest.mark.parametrize(("scope", "length"), - [("module", 2), ("function", 4)]) - def test_parametrize_scope_overrides(self, testdir, scope, length): - testdir.makepyfile(""" - import pytest - l = [] - def pytest_generate_tests(metafunc): - if "arg" in metafunc.funcargnames: - metafunc.parametrize("arg", [1,2], indirect=True, - scope=%r) - def pytest_funcarg__arg(request): - l.append(request.param) - return request.param - def test_hello(arg): - assert arg in (1,2) - def test_world(arg): - assert arg in (1,2) - def test_checklength(): - assert len(l) == %d - """ % (scope, length)) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=5) - - def test_usefixtures_seen_in_generate_tests(self, testdir): - testdir.makepyfile(""" - import pytest - def pytest_generate_tests(metafunc): - assert "abc" in metafunc.fixturenames - metafunc.parametrize("abc", [1]) - - @pytest.mark.usefixtures("abc") - def test_function(): - pass - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - def test_usefixtures_seen_in_showmarkers(self, testdir): - result = testdir.runpytest("--markers") - result.stdout.fnmatch_lines(""" - *usefixtures(fixturename1*mark tests*fixtures* - """) - - def test_generate_tests_only_done_in_subdir(self, testdir): - sub1 = testdir.mkpydir("sub1") - sub2 = testdir.mkpydir("sub2") - sub1.join("conftest.py").write(py.code.Source(""" - def pytest_generate_tests(metafunc): - assert metafunc.function.__name__ == "test_1" - """)) - sub2.join("conftest.py").write(py.code.Source(""" - def pytest_generate_tests(metafunc): - assert metafunc.function.__name__ == "test_2" - """)) - sub1.join("test_in_sub1.py").write("def test_1(): pass") - sub2.join("test_in_sub2.py").write("def test_2(): pass") - result = testdir.runpytest("-v", "-s", sub1, sub2, sub1) - result.stdout.fnmatch_lines([ - "*3 passed*" - ]) - - -def test_conftest_funcargs_only_available_in_subdir(testdir): - sub1 = testdir.mkpydir("sub1") - sub2 = testdir.mkpydir("sub2") - sub1.join("conftest.py").write(py.code.Source(""" - import pytest - def pytest_funcarg__arg1(request): - pytest.raises(Exception, "request.getfuncargvalue('arg2')") - """)) - sub2.join("conftest.py").write(py.code.Source(""" - import pytest - def pytest_funcarg__arg2(request): - pytest.raises(Exception, "request.getfuncargvalue('arg1')") - """)) - - sub1.join("test_in_sub1.py").write("def test_1(arg1): pass") - sub2.join("test_in_sub2.py").write("def test_2(arg2): pass") - result = testdir.runpytest("-v") - result.stdout.fnmatch_lines([ - "*2 passed*" - ]) - -class TestOEJSKITSpecials: - def test_funcarg_non_pycollectobj(self, testdir): # rough jstests usage - testdir.makeconftest(""" - import pytest - def pytest_pycollect_makeitem(collector, name, obj): - if name == "MyClass": - return MyCollector(name, parent=collector) - class MyCollector(pytest.Collector): - def reportinfo(self): - return self.fspath, 3, "xyz" - """) - modcol = testdir.getmodulecol(""" - def pytest_funcarg__arg1(request): - return 42 - class MyClass: - pass - """) - # this hook finds funcarg factories - rep = modcol.ihook.pytest_make_collect_report(collector=modcol) - clscol = rep.result[0] - clscol.obj = lambda arg1: None - clscol.funcargs = {} - funcargs.fillfixtures(clscol) - assert clscol.funcargs['arg1'] == 42 - - def test_autouse_fixture(self, testdir): # rough jstests usage - testdir.makeconftest(""" - import pytest - def pytest_pycollect_makeitem(collector, name, obj): - if name == "MyClass": - return MyCollector(name, parent=collector) - class MyCollector(pytest.Collector): - def reportinfo(self): - return self.fspath, 3, "xyz" - """) - modcol = testdir.getmodulecol(""" - import pytest - @pytest.fixture(autouse=True) - def hello(): - pass - def pytest_funcarg__arg1(request): - return 42 - class MyClass: - pass - """) - # this hook finds funcarg factories - rep = modcol.ihook.pytest_make_collect_report(collector=modcol) - clscol = rep.result[0] - clscol.obj = lambda: None - clscol.funcargs = {} - funcargs.fillfixtures(clscol) - assert not clscol.funcargs - - - -def test_funcarg_lookup_error(testdir): - p = testdir.makepyfile(""" - def test_lookup_error(unknown): - pass - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - "*ERROR*test_lookup_error*", - "*def test_lookup_error(unknown):*", - "*fixture*unknown*not found*", - "*available fixtures*", - "*1 error*", - ]) - assert "INTERNAL" not in result.stdout.str() - - -class TestReportInfo: - def test_itemreport_reportinfo(self, testdir, linecomp): - testdir.makeconftest(""" - import pytest - class MyFunction(pytest.Function): - def reportinfo(self): - return "ABCDE", 42, "custom" - def pytest_pycollect_makeitem(collector, name, obj): - if name == "test_func": - return MyFunction(name, parent=collector) - """) - item = testdir.getitem("def test_func(): pass") - runner = item.config.pluginmanager.getplugin("runner") - assert item.location == ("ABCDE", 42, "custom") - - def test_func_reportinfo(self, testdir): - item = testdir.getitem("def test_func(): pass") - fspath, lineno, modpath = item.reportinfo() - assert fspath == item.fspath - assert lineno == 0 - assert modpath == "test_func" - - def test_class_reportinfo(self, testdir): - modcol = testdir.getmodulecol(""" - # lineno 0 - class TestClass: - def test_hello(self): pass - """) - classcol = testdir.collect_by_name(modcol, "TestClass") - fspath, lineno, msg = classcol.reportinfo() - assert fspath == modcol.fspath - assert lineno == 1 - assert msg == "TestClass" - - 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: - def test_method(self): - pass - """ - -class TestShowFixtures: - def test_funcarg_compat(self, testdir): - config = testdir.parseconfigure("--funcargs") - assert config.option.showfixtures - - def test_show_fixtures(self, testdir): - result = testdir.runpytest("--fixtures") - result.stdout.fnmatch_lines([ - "*tmpdir*", - "*temporary directory*", - ] - ) - - def test_show_fixtures_verbose(self, testdir): - result = testdir.runpytest("--fixtures", "-v") - result.stdout.fnmatch_lines([ - "*tmpdir*--*tmpdir.py*", - "*temporary directory*", - ] - ) - - def test_show_fixtures_testmodule(self, testdir): - p = testdir.makepyfile(''' - import pytest - @pytest.fixture - def _arg0(): - """ hidden """ - @pytest.fixture - def arg1(): - """ hello world """ - ''') - result = testdir.runpytest("--fixtures", p) - result.stdout.fnmatch_lines(""" - *tmpdir - *fixtures defined from* - *arg1* - *hello world* - """) - assert "arg0" not in result.stdout.str() - - @pytest.mark.parametrize("testmod", [True, False]) - def test_show_fixtures_conftest(self, testdir, testmod): - testdir.makeconftest(''' - import pytest - @pytest.fixture - def arg1(): - """ hello world """ - ''') - if testmod: - testdir.makepyfile(""" - def test_hello(): - pass - """) - result = testdir.runpytest("--fixtures") - result.stdout.fnmatch_lines(""" - *tmpdir* - *fixtures defined from*conftest* - *arg1* - *hello world* - """) - - - -class TestRaises: - def test_raises(self): - source = "int('qwe')" - excinfo = pytest.raises(ValueError, source) - code = excinfo.traceback[-1].frame.code - s = str(code.fullsource) - assert s == source - - def test_raises_exec(self): - pytest.raises(ValueError, "a,x = []") - - def test_raises_syntax_error(self): - pytest.raises(SyntaxError, "qwe qwe qwe") - - def test_raises_function(self): - pytest.raises(ValueError, int, 'hello') - - def test_raises_callable_no_exception(self): - class A: - def __call__(self): - pass - try: - pytest.raises(ValueError, A()) - except pytest.raises.Exception: - pass - - def test_raises_flip_builtin_AssertionError(self): - # we replace AssertionError on python level - # however c code might still raise the builtin one - from _pytest.assertion.util import BuiltinAssertionError - pytest.raises(AssertionError,""" - raise BuiltinAssertionError - """) - - @pytest.mark.skipif('sys.version < "2.5"') - def test_raises_as_contextmanager(self, testdir): - testdir.makepyfile(""" - from __future__ import with_statement - import py, pytest - - def test_simple(): - with pytest.raises(ZeroDivisionError) as excinfo: - assert isinstance(excinfo, py.code.ExceptionInfo) - 1/0 - print (excinfo) - assert excinfo.type == ZeroDivisionError - - def test_noraise(): - with pytest.raises(pytest.raises.Exception): - with pytest.raises(ValueError): - int() - - def test_raise_wrong_exception_passes_by(): - with pytest.raises(ZeroDivisionError): - with pytest.raises(ValueError): - 1/0 - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - '*3 passed*', - ]) - - - -def test_customized_python_discovery(testdir): - testdir.makeini(""" - [pytest] - python_files=check_*.py - python_classes=Check - python_functions=check - """) - p = testdir.makepyfile(""" - def check_simple(): - pass - class CheckMyApp: - def check_meth(self): - pass - """) - p2 = p.new(basename=p.basename.replace("test", "check")) - p.move(p2) - result = testdir.runpytest("--collectonly", "-s") - result.stdout.fnmatch_lines([ - "*check_customized*", - "*check_simple*", - "*CheckMyApp*", - "*check_meth*", - ]) - - result = testdir.runpytest() - assert result.ret == 0 - result.stdout.fnmatch_lines([ - "*2 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() - 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: - def test_hello(self): - pass - """) - result = testdir.runpytest("--collectonly") - result.stdout.fnmatch_lines([ - "*MyClass*", - "*MyInstance*", - "*MyFunction*test_hello*", - ]) - - -def test_unorderable_types(testdir): - testdir.makepyfile(""" - class TestJoinEmpty: - pass - - def make_test(): - class Test: - pass - Test.__name__ = "TestFoo" - return Test - TestFoo = make_test() - """) - result = testdir.runpytest() - assert "TypeError" not in result.stdout.str() - assert result.ret == 0 - -def test_issue117_sessionscopeteardown(testdir): - testdir.makepyfile(""" - def pytest_funcarg__app(request): - app = request.cached_setup( - scope='session', - setup=lambda: 0, - teardown=lambda x: 3/x) - return app - def test_func(app): - pass - """) - result = testdir.runpytest() - assert result.ret != 0 - result.stdout.fnmatch_lines([ - "*3/x*", - "*ZeroDivisionError*", - ]) - - -class TestFixtureUsages: - def test_noargfixturedec(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture - def arg1(): - return 1 - - def test_func(arg1): - assert arg1 == 1 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - def test_receives_funcargs(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture() - def arg1(): - return 1 - - @pytest.fixture() - def arg2(arg1): - return arg1 + 1 - - def test_add(arg2): - assert arg2 == 2 - def test_all(arg1, arg2): - assert arg1 == 1 - assert arg2 == 2 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=2) - - def test_receives_funcargs_scope_mismatch(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture(scope="function") - def arg1(): - return 1 - - @pytest.fixture(scope="module") - def arg2(arg1): - return arg1 + 1 - - def test_add(arg2): - assert arg2 == 2 - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - "*ScopeMismatch*involved factories*", - "* def arg2*", - "* def arg1*", - "*1 error*" - ]) - - def test_funcarg_parametrized_and_used_twice(self, testdir): - testdir.makepyfile(""" - import pytest - l = [] - @pytest.fixture(params=[1,2]) - def arg1(request): - l.append(1) - return request.param - - @pytest.fixture() - def arg2(arg1): - return arg1 + 1 - - def test_add(arg1, arg2): - assert arg2 == arg1 + 1 - assert len(l) == arg1 - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - "*2 passed*" - ]) - - def test_factory_uses_unknown_funcarg_as_dependency_error(self, testdir): - testdir.makepyfile(""" - import pytest - - @pytest.fixture() - def fail(missing): - return - - @pytest.fixture() - def call_fail(fail): - return - - def test_missing(call_fail): - pass - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines(""" - *pytest.fixture()* - *def call_fail(fail)* - *pytest.fixture()* - *def fail* - *fixture*'missing'*not found* - """) - - def test_factory_setup_as_classes_fails(self, testdir): - testdir.makepyfile(""" - import pytest - class arg1: - def __init__(self, request): - self.x = 1 - arg1 = pytest.fixture()(arg1) - - """) - reprec = testdir.inline_run() - l = reprec.getfailedcollections() - assert len(l) == 1 - - def test_request_can_be_overridden(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture() - def request(request): - request.a = 1 - return request - def test_request(request): - assert request.a == 1 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - def test_usefixtures_marker(self, testdir): - testdir.makepyfile(""" - import pytest - - l = [] - - @pytest.fixture(scope="class") - def myfix(request): - request.cls.hello = "world" - l.append(1) - - class TestClass: - def test_one(self): - assert self.hello == "world" - assert len(l) == 1 - def test_two(self): - assert self.hello == "world" - assert len(l) == 1 - pytest.mark.usefixtures("myfix")(TestClass) - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=2) - - def test_usefixtures_ini(self, testdir): - testdir.makeini(""" - [pytest] - usefixtures = myfix - """) - testdir.makeconftest(""" - import pytest - - @pytest.fixture(scope="class") - def myfix(request): - request.cls.hello = "world" - - """) - testdir.makepyfile(""" - class TestClass: - def test_one(self): - assert self.hello == "world" - def test_two(self): - assert self.hello == "world" - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=2) - - def test_request_instance_issue203(self, testdir): - testdir.makepyfile(""" - import pytest - - class TestClass: - @pytest.fixture - def setup1(self, request): - assert self == request.instance - self.arg1 = 1 - def test_hello(self, setup1): - assert self.arg1 == 1 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - -class TestFixtureManager: - def pytest_funcarg__testdir(self, request): - testdir = request.getfuncargvalue("testdir") - testdir.makeconftest(""" - def pytest_funcarg__hello(request): - return "conftest" - - def pytest_funcarg__fm(request): - return request._fixturemanager - - def pytest_funcarg__item(request): - return request._pyfuncitem - """) - return testdir - - def test_parsefactories_evil_objects_issue214(self, testdir): - testdir.makepyfile(""" - class A: - def __call__(self): - pass - def __getattr__(self, name): - raise RuntimeError() - a = A() - def test_hello(): - pass - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1, failed=0) - - def test_parsefactories_conftest(self, testdir): - testdir.makepyfile(""" - def test_hello(item, fm): - for name in ("fm", "hello", "item"): - faclist = fm.getfixturedefs(name, item.nodeid) - assert len(faclist) == 1 - fac = faclist[0] - assert fac.func.__name__ == "pytest_funcarg__" + name - """) - reprec = testdir.inline_run("-s") - reprec.assertoutcome(passed=1) - - def test_parsefactories_conftest_and_module_and_class(self, testdir): - testdir.makepyfile(""" - def pytest_funcarg__hello(request): - return "module" - class TestClass: - def pytest_funcarg__hello(self, request): - return "class" - def test_hello(self, item, fm): - faclist = fm.getfixturedefs("hello", item.nodeid) - print (faclist) - assert len(faclist) == 3 - assert faclist[0].func(item._request) == "conftest" - assert faclist[1].func(item._request) == "module" - assert faclist[2].func(item._request) == "class" - """) - reprec = testdir.inline_run("-s") - reprec.assertoutcome(passed=1) - -class TestAutouseDiscovery: - def pytest_funcarg__testdir(self, testdir): - testdir.makeconftest(""" - import pytest - @pytest.fixture(autouse=True) - def perfunction(request, tmpdir): - pass - - @pytest.fixture() - def arg1(tmpdir): - pass - @pytest.fixture(autouse=True) - def perfunction2(arg1): - pass - - def pytest_funcarg__fm(request): - return request._fixturemanager - - def pytest_funcarg__item(request): - return request._pyfuncitem - """) - return testdir - - def test_parsefactories_conftest(self, testdir): - testdir.makepyfile(""" - def test_check_setup(item, fm): - autousenames = fm._getautousenames(item.nodeid) - assert len(autousenames) == 2 - assert "perfunction2" in autousenames - assert "perfunction" in autousenames - """) - reprec = testdir.inline_run("-s") - reprec.assertoutcome(passed=1) - - def test_two_classes_separated_autouse(self, testdir): - testdir.makepyfile(""" - import pytest - class TestA: - l = [] - @pytest.fixture(autouse=True) - def setup1(self): - self.l.append(1) - def test_setup1(self): - assert self.l == [1] - class TestB: - l = [] - @pytest.fixture(autouse=True) - def setup2(self): - self.l.append(1) - def test_setup2(self): - assert self.l == [1] - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=2) - - def test_setup_at_classlevel(self, testdir): - testdir.makepyfile(""" - import pytest - class TestClass: - @pytest.fixture(autouse=True) - def permethod(self, request): - request.instance.funcname = request.function.__name__ - def test_method1(self): - assert self.funcname == "test_method1" - def test_method2(self): - assert self.funcname == "test_method2" - """) - reprec = testdir.inline_run("-s") - reprec.assertoutcome(passed=2) - - @pytest.mark.xfail(reason="'enabled' feature not implemented") - def test_setup_enabled_functionnode(self, testdir): - testdir.makepyfile(""" - import pytest - - def enabled(parentnode, markers): - return "needsdb" in markers - - @pytest.fixture(params=[1,2]) - def db(request): - return request.param - - @pytest.fixture(enabled=enabled, autouse=True) - def createdb(db): - pass - - def test_func1(request): - assert "db" not in request.fixturenames - - @pytest.mark.needsdb - def test_func2(request): - assert "db" in request.fixturenames - """) - reprec = testdir.inline_run("-s") - reprec.assertoutcome(passed=2) - - def test_callables_nocode(self, testdir): - """ - a imported mock.call would break setup/factory discovery - due to it being callable and __code__ not being a code object - """ - testdir.makepyfile(""" - class _call(tuple): - def __call__(self, *k, **kw): - pass - def __getattr__(self, k): - return self - - call = _call() - """) - reprec = testdir.inline_run("-s") - reprec.assertoutcome(failed=0, passed=0) - - def test_autouse_in_conftests(self, testdir): - a = testdir.mkdir("a") - b = testdir.mkdir("a1") - conftest = testdir.makeconftest(""" - import pytest - @pytest.fixture(autouse=True) - def hello(): - xxx - """) - conftest.move(a.join(conftest.basename)) - a.join("test_something.py").write("def test_func(): pass") - b.join("test_otherthing.py").write("def test_func(): pass") - result = testdir.runpytest() - result.stdout.fnmatch_lines(""" - *1 passed*1 error* - """) - - def test_autouse_in_module_and_two_classes(self, testdir): - testdir.makepyfile(""" - import pytest - l = [] - @pytest.fixture(autouse=True) - def append1(): - l.append("module") - def test_x(): - assert l == ["module"] - - class TestA: - @pytest.fixture(autouse=True) - def append2(self): - l.append("A") - def test_hello(self): - assert l == ["module", "module", "A"], l - class TestA2: - def test_world(self): - assert l == ["module", "module", "A", "module"], l - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=3) - -class TestAutouseManagement: - def test_funcarg_and_setup(self, testdir): - testdir.makepyfile(""" - import pytest - l = [] - @pytest.fixture(scope="module") - def arg(): - l.append(1) - return 0 - @pytest.fixture(scope="class", autouse=True) - def something(arg): - l.append(2) - - def test_hello(arg): - assert len(l) == 2 - assert l == [1,2] - assert arg == 0 - - def test_hello2(arg): - assert len(l) == 2 - assert l == [1,2] - assert arg == 0 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=2) - - def test_uses_parametrized_resource(self, testdir): - testdir.makepyfile(""" - import pytest - l = [] - @pytest.fixture(params=[1,2]) - def arg(request): - return request.param - - @pytest.fixture(autouse=True) - def something(arg): - l.append(arg) - - def test_hello(): - if len(l) == 1: - assert l == [1] - elif len(l) == 2: - assert l == [1, 2] - else: - 0/0 - - """) - reprec = testdir.inline_run("-s") - reprec.assertoutcome(passed=2) - - def test_session_parametrized_function(self, testdir): - testdir.makepyfile(""" - import pytest - - l = [] - - @pytest.fixture(scope="session", params=[1,2]) - def arg(request): - return request.param - - @pytest.fixture(scope="function", autouse=True) - def append(request, arg): - if request.function.__name__ == "test_some": - l.append(arg) - - def test_some(): - pass - - def test_result(arg): - assert len(l) == arg - assert l[:arg] == [1,2][:arg] - """) - reprec = testdir.inline_run("-v", "-s") - reprec.assertoutcome(passed=4) - - def test_class_function_parametrization_finalization(self, testdir): - p = testdir.makeconftest(""" - import pytest - import pprint - - l = [] - - @pytest.fixture(scope="function", params=[1,2]) - def farg(request): - return request.param - - @pytest.fixture(scope="class", params=list("ab")) - def carg(request): - return request.param - - @pytest.fixture(scope="function", autouse=True) - def append(request, farg, carg): - def fin(): - l.append("fin_%s%s" % (carg, farg)) - request.addfinalizer(fin) - """) - testdir.makepyfile(""" - import pytest - - class TestClass: - def test_1(self): - pass - class TestClass2: - def test_2(self): - pass - """) - reprec = testdir.inline_run("-v","-s") - reprec.assertoutcome(passed=8) - config = reprec.getcalls("pytest_unconfigure")[0].config - l = config._conftest.getconftestmodules(p)[0].l - assert l == ["fin_a1", "fin_a2", "fin_b1", "fin_b2"] * 2 - - def test_scope_ordering(self, testdir): - testdir.makepyfile(""" - import pytest - l = [] - @pytest.fixture(scope="function", autouse=True) - def fappend2(): - l.append(2) - @pytest.fixture(scope="class", autouse=True) - def classappend3(): - l.append(3) - @pytest.fixture(scope="module", autouse=True) - def mappend(): - l.append(1) - - class TestHallo: - def test_method(self): - assert l == [1,3,2] - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - - def test_parametrization_setup_teardown_ordering(self, testdir): - testdir.makepyfile(""" - import pytest - l = [] - def pytest_generate_tests(metafunc): - if metafunc.cls is not None: - metafunc.parametrize("item", [1,2], scope="class") - class TestClass: - @pytest.fixture(scope="class", autouse=True) - def addteardown(self, item, request): - l.append("setup-%d" % item) - request.addfinalizer(lambda: l.append("teardown-%d" % item)) - def test_step1(self, item): - l.append("step1-%d" % item) - def test_step2(self, item): - l.append("step2-%d" % item) - - def test_finish(): - assert l == ["setup-1", "step1-1", "step2-1", "teardown-1", - "setup-2", "step1-2", "step2-2", "teardown-2",] - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=5) - - -class TestFixtureMarker: - def test_parametrize(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture(params=["a", "b", "c"]) - def arg(request): - return request.param - l = [] - def test_param(arg): - l.append(arg) - def test_result(): - assert l == list("abc") - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=4) - - def test_scope_session(self, testdir): - testdir.makepyfile(""" - import pytest - l = [] - @pytest.fixture(scope="module") - def arg(): - l.append(1) - return 1 - - def test_1(arg): - assert arg == 1 - def test_2(arg): - assert arg == 1 - assert len(l) == 1 - class TestClass: - def test3(self, arg): - assert arg == 1 - assert len(l) == 1 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=3) - - def test_scope_module_uses_session(self, testdir): - testdir.makepyfile(""" - import pytest - l = [] - @pytest.fixture(scope="module") - def arg(): - l.append(1) - return 1 - - def test_1(arg): - assert arg == 1 - def test_2(arg): - assert arg == 1 - assert len(l) == 1 - class TestClass: - def test3(self, arg): - assert arg == 1 - assert len(l) == 1 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=3) - - def test_scope_module_and_finalizer(self, testdir): - testdir.makeconftest(""" - import pytest - finalized = [] - created = [] - @pytest.fixture(scope="module") - def arg(request): - created.append(1) - assert request.scope == "module" - request.addfinalizer(lambda: finalized.append(1)) - def pytest_funcarg__created(request): - return len(created) - def pytest_funcarg__finalized(request): - return len(finalized) - """) - testdir.makepyfile( - test_mod1=""" - def test_1(arg, created, finalized): - assert created == 1 - assert finalized == 0 - def test_2(arg, created, finalized): - assert created == 1 - assert finalized == 0""", - test_mod2=""" - def test_3(arg, created, finalized): - assert created == 2 - assert finalized == 1""", - test_mode3=""" - def test_4(arg, created, finalized): - assert created == 3 - assert finalized == 2 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=4) - - @pytest.mark.parametrize("method", [ - 'request.getfuncargvalue("arg")', - 'request.cached_setup(lambda: None, scope="function")', - ], ids=["getfuncargvalue", "cached_setup"]) - def test_scope_mismatch(self, testdir, method): - testdir.makeconftest(""" - import pytest - finalized = [] - created = [] - @pytest.fixture(scope="function") - def arg(request): - pass - """) - testdir.makepyfile( - test_mod1=""" - import pytest - @pytest.fixture(scope="session") - def arg(request): - %s - def test_1(arg): - pass - """ % method) - result = testdir.runpytest() - assert result.ret != 0 - result.stdout.fnmatch_lines([ - "*ScopeMismatch*You tried*function*session*request*", - ]) - - def test_register_only_with_mark(self, testdir): - testdir.makeconftest(""" - import pytest - @pytest.fixture() - def arg(): - return 1 - """) - testdir.makepyfile( - test_mod1=""" - import pytest - @pytest.fixture() - def arg(arg): - return arg + 1 - def test_1(arg): - assert arg == 2 - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - def test_parametrize_and_scope(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture(scope="module", params=["a", "b", "c"]) - def arg(request): - return request.param - l = [] - def test_param(arg): - l.append(arg) - """) - reprec = testdir.inline_run("-v") - reprec.assertoutcome(passed=3) - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l - assert len(l) == 3 - assert "a" in l - assert "b" in l - assert "c" in l - - def test_scope_mismatch(self, testdir): - testdir.makeconftest(""" - import pytest - @pytest.fixture(scope="function") - def arg(request): - pass - """) - testdir.makepyfile(""" - import pytest - @pytest.fixture(scope="session") - def arg(arg): - pass - def test_mismatch(arg): - pass - """) - result = testdir.runpytest() - result.stdout.fnmatch_lines([ - "*ScopeMismatch*", - "*1 error*", - ]) - - def test_parametrize_separated_order(self, testdir): - testdir.makepyfile(""" - import pytest - - @pytest.fixture(scope="module", params=[1, 2]) - def arg(request): - return request.param - - l = [] - def test_1(arg): - l.append(arg) - def test_2(arg): - l.append(arg) - """) - reprec = testdir.inline_run("-v") - reprec.assertoutcome(passed=4) - l = reprec.getcalls("pytest_runtest_call")[0].item.module.l - assert l == [1,1,2,2] - - def test_module_parametrized_ordering(self, testdir): - testdir.makeconftest(""" - import pytest - - @pytest.fixture(scope="session", params="s1 s2".split()) - def sarg(): - pass - @pytest.fixture(scope="module", params="m1 m2".split()) - def marg(): - pass - """) - testdir.makepyfile(test_mod1=""" - def test_func(sarg): - pass - def test_func1(marg): - pass - """, test_mod2=""" - def test_func2(sarg): - pass - def test_func3(sarg, marg): - pass - def test_func3b(sarg, marg): - pass - def test_func4(marg): - pass - """) - result = testdir.runpytest("-v") - result.stdout.fnmatch_lines(""" - test_mod1.py:1: test_func[s1] PASSED - test_mod2.py:1: test_func2[s1] PASSED - test_mod2.py:3: test_func3[s1-m1] PASSED - test_mod2.py:5: test_func3b[s1-m1] PASSED - test_mod2.py:3: test_func3[s1-m2] PASSED - test_mod2.py:5: test_func3b[s1-m2] PASSED - test_mod1.py:1: test_func[s2] PASSED - test_mod2.py:1: test_func2[s2] PASSED - test_mod2.py:3: test_func3[s2-m1] PASSED - test_mod2.py:5: test_func3b[s2-m1] PASSED - test_mod2.py:7: test_func4[m1] PASSED - test_mod2.py:3: test_func3[s2-m2] PASSED - test_mod2.py:5: test_func3b[s2-m2] PASSED - test_mod2.py:7: test_func4[m2] PASSED - test_mod1.py:3: test_func1[m1] PASSED - test_mod1.py:3: test_func1[m2] PASSED - """) - - def test_class_ordering(self, testdir): - p = testdir.makeconftest(""" - import pytest - - l = [] - - @pytest.fixture(scope="function", params=[1,2]) - def farg(request): - return request.param - - @pytest.fixture(scope="class", params=list("ab")) - def carg(request): - return request.param - - @pytest.fixture(scope="function", autouse=True) - def append(request, farg, carg): - def fin(): - l.append("fin_%s%s" % (carg, farg)) - request.addfinalizer(fin) - """) - testdir.makepyfile(""" - import pytest - - class TestClass2: - def test_1(self): - pass - def test_2(self): - pass - class TestClass: - def test_3(self): - pass - """) - result = testdir.runpytest("-vs") - result.stdout.fnmatch_lines(""" - test_class_ordering.py:4: TestClass2.test_1[1-a] PASSED - test_class_ordering.py:4: TestClass2.test_1[2-a] PASSED - test_class_ordering.py:6: TestClass2.test_2[1-a] PASSED - test_class_ordering.py:6: TestClass2.test_2[2-a] PASSED - test_class_ordering.py:4: TestClass2.test_1[1-b] PASSED - test_class_ordering.py:4: TestClass2.test_1[2-b] PASSED - test_class_ordering.py:6: TestClass2.test_2[1-b] PASSED - test_class_ordering.py:6: TestClass2.test_2[2-b] PASSED - test_class_ordering.py:9: TestClass.test_3[1-a] PASSED - test_class_ordering.py:9: TestClass.test_3[2-a] PASSED - test_class_ordering.py:9: TestClass.test_3[1-b] PASSED - test_class_ordering.py:9: TestClass.test_3[2-b] PASSED - """) - - def test_parametrize_separated_order_higher_scope_first(self, testdir): - testdir.makepyfile(""" - import pytest - - @pytest.fixture(scope="function", params=[1, 2]) - def arg(request): - param = request.param - request.addfinalizer(lambda: l.append("fin:%s" % param)) - l.append("create:%s" % param) - return request.param - - @pytest.fixture(scope="module", params=["mod1", "mod2"]) - def modarg(request): - param = request.param - request.addfinalizer(lambda: l.append("fin:%s" % param)) - l.append("create:%s" % param) - return request.param - - l = [] - def test_1(arg): - l.append("test1") - def test_2(modarg): - l.append("test2") - def test_3(arg, modarg): - l.append("test3") - def test_4(modarg, arg): - l.append("test4") - def test_5(): - assert len(l) == 12 * 3 - expected = [ - 'create:1', 'test1', 'fin:1', 'create:2', 'test1', - 'fin:2', 'create:mod1', 'test2', 'create:1', 'test3', - 'fin:1', 'create:2', 'test3', 'fin:2', 'create:1', - 'test4', 'fin:1', 'create:2', 'test4', 'fin:2', - 'fin:mod1', 'create:mod2', 'test2', 'create:1', 'test3', - 'fin:1', 'create:2', 'test3', 'fin:2', 'create:1', - 'test4', 'fin:1', 'create:2', 'test4', 'fin:2', - 'fin:mod2'] - import pprint - pprint.pprint(list(zip(l, expected))) - assert l == expected - """) - reprec = testdir.inline_run("-v") - reprec.assertoutcome(passed=12+1) - - def test_parametrized_fixture_teardown_order(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture(params=[1,2], scope="class") - def param1(request): - return request.param - - l = [] - - class TestClass: - @classmethod - @pytest.fixture(scope="class", autouse=True) - def setup1(self, request, param1): - l.append(1) - request.addfinalizer(self.teardown1) - @classmethod - def teardown1(self): - assert l.pop() == 1 - @pytest.fixture(scope="class", autouse=True) - def setup2(self, request, param1): - l.append(2) - request.addfinalizer(self.teardown2) - @classmethod - def teardown2(self): - assert l.pop() == 2 - def test(self): - pass - - def test_finish(): - assert not l - """) - result = testdir.runpytest("-v") - result.stdout.fnmatch_lines(""" - *3 passed* - """) - assert "error" not in result.stdout.str() - - def test_parametrize_separated_lifecycle(self, testdir): - testdir.makepyfile(""" - import pytest - - @pytest.fixture(scope="module", params=[1, 2]) - def arg(request): - request.config.l = l # to access from outer - x = request.param - request.addfinalizer(lambda: l.append("fin%s" % x)) - return request.param - - l = [] - def test_1(arg): - l.append(arg) - def test_2(arg): - l.append(arg) - """) - reprec = testdir.inline_run("-v") - reprec.assertoutcome(passed=4) - l = reprec.getcalls("pytest_configure")[0].config.l - import pprint - pprint.pprint(l) - assert len(l) == 6 - assert l[0] == l[1] == 1 - assert l[2] == "fin1" - assert l[3] == l[4] == 2 - assert l[5] == "fin2" - - - def test_parametrize_function_scoped_finalizers_called(self, testdir): - testdir.makepyfile(""" - import pytest - - @pytest.fixture(scope="function", params=[1, 2]) - def arg(request): - x = request.param - request.addfinalizer(lambda: l.append("fin%s" % x)) - return request.param - - l = [] - def test_1(arg): - l.append(arg) - def test_2(arg): - l.append(arg) - def test_3(): - assert len(l) == 8 - assert l == [1, "fin1", 2, "fin2", 1, "fin1", 2, "fin2"] - """) - reprec = testdir.inline_run("-v") - reprec.assertoutcome(passed=5) - - def test_parametrize_setup_function(self, testdir): - testdir.makepyfile(""" - import pytest - - @pytest.fixture(scope="module", params=[1, 2]) - def arg(request): - return request.param - - @pytest.fixture(scope="module", autouse=True) - def mysetup(request, arg): - request.addfinalizer(lambda: l.append("fin%s" % arg)) - l.append("setup%s" % arg) - - l = [] - def test_1(arg): - l.append(arg) - def test_2(arg): - l.append(arg) - def test_3(): - import pprint - pprint.pprint(l) - if arg == 1: - assert l == ["setup1", 1, 1, ] - elif arg == 2: - assert l == ["setup1", 1, 1, "fin1", - "setup2", 2, 2, ] - - """) - reprec = testdir.inline_run("-v") - reprec.assertoutcome(passed=6) - -class TestTestContextScopeAccess: - pytestmark = pytest.mark.parametrize(("scope", "ok", "error"),[ - ["session", "", "fspath class function module"], - ["module", "module fspath", "cls function"], - ["class", "module fspath cls", "function"], - ["function", "module fspath cls function", ""] - ]) - - def test_setup(self, testdir, scope, ok, error): - testdir.makepyfile(""" - import pytest - @pytest.fixture(scope=%r, autouse=True) - def myscoped(request): - for x in %r: - assert hasattr(request, x) - for x in %r: - pytest.raises(AttributeError, lambda: - getattr(request, x)) - assert request.session - assert request.config - def test_func(): - pass - """ %(scope, ok.split(), error.split())) - reprec = testdir.inline_run("-l") - reprec.assertoutcome(passed=1) - - def test_funcarg(self, testdir, scope, ok, error): - testdir.makepyfile(""" - import pytest - @pytest.fixture(scope=%r) - def arg(request): - for x in %r: - assert hasattr(request, x) - for x in %r: - pytest.raises(AttributeError, lambda: - getattr(request, x)) - assert request.session - assert request.config - def test_func(arg): - pass - """ %(scope, ok.split(), error.split())) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - -class TestErrors: - def test_subfactory_missing_funcarg(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture() - def gen(qwe123): - return 1 - def test_something(gen): - pass - """) - result = testdir.runpytest() - assert result.ret != 0 - result.stdout.fnmatch_lines([ - "*def gen(qwe123):*", - "*fixture*qwe123*not found*", - "*1 error*", - ]) - - def test_setupfunc_missing_funcarg(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture(autouse=True) - def gen(qwe123): - return 1 - def test_something(): - pass - """) - result = testdir.runpytest() - assert result.ret != 0 - result.stdout.fnmatch_lines([ - "*def gen(qwe123):*", - "*fixture*qwe123*not found*", - "*1 error*", - ]) - - -class TestTestContextVarious: - def test_newstyle_with_request(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture() - def arg(request): - pass - def test_1(arg): - pass - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - def test_setupcontext_no_param(self, testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture(params=[1,2]) - def arg(request): - return request.param - - @pytest.fixture(autouse=True) - def mysetup(request, arg): - assert not hasattr(request, "param") - def test_1(arg): - assert arg in (1,2) - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=2) - -def test_setupdecorator_and_xunit(testdir): - testdir.makepyfile(""" - import pytest - l = [] - @pytest.fixture(scope='module', autouse=True) - def setup_module(): - l.append("module") - @pytest.fixture(autouse=True) - def setup_function(): - l.append("function") - - def test_func(): - pass - - class TestClass: - @pytest.fixture(scope="class", autouse=True) - def setup_class(self): - l.append("class") - @pytest.fixture(autouse=True) - def setup_method(self): - l.append("method") - def test_method(self): - pass - def test_all(): - assert l == ["module", "function", "class", - "function", "method", "function"] - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=3) - - - -def test_setup_funcarg_order(testdir): - testdir.makepyfile(""" - import pytest - - l = [] - @pytest.fixture(autouse=True) - def fix1(): - l.append(1) - @pytest.fixture() - def arg1(): - l.append(2) - def test_hello(arg1): - assert l == [1,2] - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - - -def test_request_fixturenames(testdir): - testdir.makepyfile(""" - import pytest - @pytest.fixture() - def arg1(): - pass - @pytest.fixture() - def farg(arg1): - pass - @pytest.fixture(autouse=True) - def sarg(tmpdir): - pass - def test_function(request, farg): - assert set(request.fixturenames) == \ - set(["tmpdir", "sarg", "arg1", "request", "farg"]) - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - -def test_funcargnames_compatattr(testdir): - testdir.makepyfile(""" - def pytest_generate_tests(metafunc): - assert metafunc.funcargnames == metafunc.fixturenames - def pytest_funcarg__fn(request): - assert request._pyfuncitem.funcargnames == \ - request._pyfuncitem.fixturenames - return request.funcargnames, request.fixturenames - - def test_hello(fn): - assert fn[0] == fn[1] - """) - reprec = testdir.inline_run() - reprec.assertoutcome(passed=1) - -def test_fixtures_sub_subdir_normalize_sep(testdir): - # this makes sure that normlization of nodeids takes place - b = testdir.mkdir("tests").mkdir("unit") - b.join("conftest.py").write(py.code.Source(""" - def pytest_funcarg__arg1(): - pass - """)) - p = b.join("test_module.py") - p.write("def test_func(arg1): pass") - result = testdir.runpytest(p, "--fixtures") - assert result.ret == 0 - result.stdout.fnmatch_lines(""" - *fixtures defined*conftest* - *arg1* - """) diff -r aadd426bdd8ca896314b29f1802fae58b7684cea -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c tox.ini --- a/tox.ini +++ b/tox.ini @@ -96,7 +96,7 @@ #--pyargs --doctest-modules --ignore=.tox addopts= -rxs rsyncdirs=tox.ini pytest.py _pytest testing -python_files=test_*.py *_test.py +python_files=test_*.py *_test.py testing/*/*.py python_classes=Test Acceptance python_functions=test pep8ignore = E401 E225 E261 E128 E124 E302 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Sat Nov 3 21:15:46 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Sat, 03 Nov 2012 20:15:46 -0000 Subject: [py-svn] commit/pytest: hpk42: fix issue148 - recognize @unittest.skip on classes, avoid setup/teardown Message-ID: <20121103201546.30682.30337@bitbucket16.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/dd4b2fddc75d/ changeset: dd4b2fddc75d user: hpk42 date: 2012-11-03 20:54:48 summary: fix issue148 - recognize @unittest.skip on classes, avoid setup/teardown affected #: 3 files diff -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c -r dd4b2fddc75d80c596b458614088456ee409c09c CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,8 @@ - fix issue215 - split test_python.org into multiple files +- fix issue148 - @unittest.skip on classes is now recognized and avoids + calling setUpClass/tearDownClass Changes between 2.3.1 and 2.3.2 ----------------------------------- diff -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c -r dd4b2fddc75d80c596b458614088456ee409c09c _pytest/unittest.py --- a/_pytest/unittest.py +++ b/_pytest/unittest.py @@ -46,12 +46,16 @@ yield TestCaseFunction('runTest', parent=self) def setup(self): + if getattr(self.obj, '__unittest_skip__', False): + return meth = getattr(self.obj, 'setUpClass', None) if meth is not None: meth() super(UnitTestCase, self).setup() def teardown(self): + if getattr(self.obj, '__unittest_skip__', False): + return meth = getattr(self.obj, 'tearDownClass', None) if meth is not None: meth() diff -r 62026bb7a7f3931a8d3f5fb5c2ac54b39017091c -r dd4b2fddc75d80c596b458614088456ee409c09c testing/test_unittest.py --- a/testing/test_unittest.py +++ b/testing/test_unittest.py @@ -96,6 +96,25 @@ assert passed == 2 assert passed + skipped + failed == 2 + at pytest.mark.skipif("sys.version_info < (3,1)") +def test_unittest_skip_issue148(testdir): + testpath = testdir.makepyfile(""" + import unittest + + @unittest.skip("hello") + class MyTestCase(unittest.TestCase): + @classmethod + def setUpClass(self): + xxx + def test_one(self): + pass + @classmethod + def tearDownClass(self): + xxx + """) + reprec = testdir.inline_run(testpath) + reprec.assertoutcome(skipped=1) + def test_method_and_teardown_failing_reporting(testdir): testdir.makepyfile(""" import unittest, pytest Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Nov 5 12:11:12 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 05 Nov 2012 11:11:12 -0000 Subject: [py-svn] commit/py: 2 new changesets Message-ID: <20121105111112.14264.91674@bitbucket03.managed.contegix.com> 2 new commits in py: https://bitbucket.org/hpk42/py/changeset/8fb4e833f068/ changeset: 8fb4e833f068 user: hpk42 date: 2012-11-05 11:10:50 summary: minor cleanup affected #: 1 file diff -r 8cca692742d7c89697b25aaac7ee7dd9ff5343fc -r 8fb4e833f068de85606a9ea703f4244cfe140cd0 py/_path/common.py --- a/py/_path/common.py +++ b/py/_path/common.py @@ -261,8 +261,8 @@ current = current.dirpath() if last == current: break - l.insert(0, current) - if reverse: + l.append(current) + if not reverse: l.reverse() return l https://bitbucket.org/hpk42/py/changeset/88c67bb04849/ changeset: 88c67bb04849 user: hpk42 date: 2012-11-05 12:11:00 summary: fix pytest issue209 - reintroduce old statementfinding algo for Pythons (e.g. cpython2.4) which don't come with an AST affected #: 6 files diff -r 8fb4e833f068de85606a9ea703f4244cfe140cd0 -r 88c67bb0484990537681b03840cc488690719311 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ Changes between 1.4.11 and 1.4.12.dev ================================================== +- fix python2.4 support - for pre-AST interpreters re-introduce + old way to find statements in exceptions (closes pytest issue 209) - add tox.ini to distribution Changes between 1.4.10 and 1.4.11 diff -r 8fb4e833f068de85606a9ea703f4244cfe140cd0 -r 88c67bb0484990537681b03840cc488690719311 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.11' +__version__ = '1.4.12.dev1' from py import _apipkg diff -r 8fb4e833f068de85606a9ea703f4244cfe140cd0 -r 88c67bb0484990537681b03840cc488690719311 py/_code/source.py --- a/py/_code/source.py +++ b/py/_code/source.py @@ -358,10 +358,14 @@ #print "returning nodelist", l return l -def getstatementrange_ast(lineno, source, astnode=None): +def getstatementrange_ast(lineno, source, assertion=False, astnode=None): if astnode is None: content = "\n".join(source.lines) - astnode = compile(content, "source", "exec", 1024) # 1024 for AST + try: + astnode = compile(content, "source", "exec", 1024) # 1024 for AST + except ValueError: + start, end = getstatementrange_old(lineno, source, assertion) + return None, start, end start, end = get_statement_startend(lineno, getnodelist(astnode)) # we need to correct the end: # - ast-parsing strips comments @@ -378,3 +382,38 @@ break return astnode, start, end +def getstatementrange_old(lineno, source, assertion=False): + """ return (start, end) tuple which spans the minimal + statement region which containing the given lineno. + raise an IndexError if no such statementrange can be found. + """ + # XXX this logic is only used on python2.4 and below + # 1. find the start of the statement + from codeop import compile_command + for start in range(lineno, -1, -1): + if assertion: + line = source.lines[start] + # the following lines are not fully tested, change with care + if 'super' in line and 'self' in line and '__init__' in line: + raise IndexError("likely a subclass") + if "assert" not in line and "raise" not in line: + continue + trylines = source.lines[start:lineno+1] + # quick hack to prepare parsing an indented line with + # compile_command() (which errors on "return" outside defs) + trylines.insert(0, 'def xxx():') + trysource = '\n '.join(trylines) + # ^ space here + try: + compile_command(trysource) + except (SyntaxError, OverflowError, ValueError): + continue + + # 2. find the end of the statement + for end in range(lineno+1, len(source)+1): + trysource = source[start:end] + if trysource.isparseable(): + return start, end + raise SyntaxError("no valid source range around line %d " % (lineno,)) + + diff -r 8fb4e833f068de85606a9ea703f4244cfe140cd0 -r 88c67bb0484990537681b03840cc488690719311 setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.11', + version='1.4.12.dev1', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 8fb4e833f068de85606a9ea703f4244cfe140cd0 -r 88c67bb0484990537681b03840cc488690719311 testing/code/test_excinfo.py --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -4,6 +4,7 @@ queue = py.builtin._tryimport('queue', 'Queue') failsonjython = py.test.mark.xfail("sys.platform.startswith('java')") +from test_source import astonly try: import importlib @@ -91,6 +92,7 @@ assert s.startswith("def f():") assert s.endswith("raise ValueError") + @astonly @failsonjython def test_traceback_entry_getsource_in_construct(self): source = py.code.Source("""\ @@ -108,7 +110,7 @@ print (tb[-1].getsource()) s = str(tb[-1].getsource()) assert s.startswith("def xyz():\n try:") - assert s.endswith("except somenoname:") + assert s.strip().endswith("except somenoname:") def test_traceback_cut(self): co = py.code.Code(f) diff -r 8fb4e833f068de85606a9ea703f4244cfe140cd0 -r 88c67bb0484990537681b03840cc488690719311 testing/code/test_source.py --- a/testing/code/test_source.py +++ b/testing/code/test_source.py @@ -2,6 +2,12 @@ import py import sys +from py._code.source import _ast +if _ast is not None: + astonly = py.test.mark.nothing +else: + astonly = py.test.mark.xfail("True", reason="only works with AST-compile") + failsonjython = py.test.mark.xfail("sys.platform.startswith('java')") def test_source_str_function(): @@ -185,6 +191,7 @@ s = source.getstatement(1) assert s == str(source) + @astonly def test_getstatementrange_within_constructs(self): source = Source("""\ try: @@ -484,6 +491,7 @@ assert str(source) == "raise ValueError(\n 23\n)" class TestTry: + pytestmark = astonly source = """\ try: raise ValueError @@ -528,6 +536,7 @@ class TestIf: + pytestmark = astonly source = """\ if 1: y = 3 Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Nov 5 12:22:06 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 05 Nov 2012 11:22:06 -0000 Subject: [py-svn] commit/pytest: hpk42: fix issue209 - depend on pylib dev version which again supports python2.4 Message-ID: <20121105112206.380.97026@bitbucket02.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/08e713c68aba/ changeset: 08e713c68aba user: hpk42 date: 2012-11-05 12:21:58 summary: fix issue209 - depend on pylib dev version which again supports python2.4 affected #: 3 files diff -r dd4b2fddc75d80c596b458614088456ee409c09c -r 08e713c68aba7134a29f8d24980a78500b137abe CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,10 @@ - fix issue148 - @unittest.skip on classes is now recognized and avoids calling setUpClass/tearDownClass +- fix issue209 - reintroduce python2.4 support by depending on newer + pylib which re-introduced statement-finding for pre-AST interpreters + + Changes between 2.3.1 and 2.3.2 ----------------------------------- diff -r dd4b2fddc75d80c596b458614088456ee409c09c -r 08e713c68aba7134a29f8d24980a78500b137abe setup.py --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ entry_points= make_entry_points(), cmdclass = {'test': PyTest}, # the following should be enabled for release - install_requires=['py>=1.4.11'], + install_requires=['py>=1.4.12.dev1'], classifiers=['Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', diff -r dd4b2fddc75d80c596b458614088456ee409c09c -r 08e713c68aba7134a29f8d24980a78500b137abe tox.ini --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,10 @@ [tox] distshare={homedir}/.tox/distshare -envlist=py26,py27,py27-nobyte,py31,py32,py33,py27-xdist,py25,trial +envlist=py24,py26,py27,py27-nobyte,py31,py32,py33,py27-xdist,py25,trial indexserver= pypi = http://pypi.python.org/simple testrun = http://pypi.testrun.org - #default = http://pypi.testrun.org + default = http://pypi.testrun.org [testenv] changedir=testing Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Nov 5 21:19:12 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 05 Nov 2012 20:19:12 -0000 Subject: [py-svn] commit/pytest: 3 new changesets Message-ID: <20121105201912.19933.74922@bitbucket21.managed.contegix.com> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/593347ff1537/ changeset: 593347ff1537 user: ataumoefolau date: 2012-10-12 06:39:17 summary: nose.py: don't try to call setup if it's not callable affected #: 1 file diff -r 4ff9c2bc50bdf82809f9ded29f55c50c8103e92c -r 593347ff153799d98ea1faeefc3641f28a3503d2 _pytest/nose.py --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -41,7 +41,7 @@ def call_optional(obj, name): method = getattr(obj, name, None) - if method is not None and not hasattr(method, "_pytestfixturefunction"): + if method is not None and not hasattr(method, "_pytestfixturefunction") and callable(method): # If there's any problems allow the exception to raise rather than # silently ignoring them method() https://bitbucket.org/hpk42/pytest/changeset/efc2693750ab/ changeset: efc2693750ab user: RonnyPfannschmidt date: 2012-11-05 21:17:58 summary: test call_optional not calling non-callable functions affected #: 1 file diff -r 593347ff153799d98ea1faeefc3641f28a3503d2 -r efc2693750ab613fd4f32e8549f3e0fd719ce2b4 testing/test_nose.py --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -35,6 +35,12 @@ assert not l +def test_setup_func_not_callable(): + from _pytest.nose import call_optional + class A: + f = 1 + call_optional(A(), "f") + def test_nose_setup_func(testdir): p = testdir.makepyfile(""" from nose.tools import with_setup https://bitbucket.org/hpk42/pytest/changeset/2bde7353ee7d/ changeset: 2bde7353ee7d user: RonnyPfannschmidt date: 2012-11-05 21:18:50 summary: merge pull request affected #: 2 files diff -r 08e713c68aba7134a29f8d24980a78500b137abe -r 2bde7353ee7d24bb45198cb469b12d05e7207d30 _pytest/nose.py --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -41,7 +41,7 @@ def call_optional(obj, name): method = getattr(obj, name, None) - if method is not None and not hasattr(method, "_pytestfixturefunction"): + if method is not None and not hasattr(method, "_pytestfixturefunction") and callable(method): # If there's any problems allow the exception to raise rather than # silently ignoring them method() diff -r 08e713c68aba7134a29f8d24980a78500b137abe -r 2bde7353ee7d24bb45198cb469b12d05e7207d30 testing/test_nose.py --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -35,6 +35,12 @@ assert not l +def test_setup_func_not_callable(): + from _pytest.nose import call_optional + class A: + f = 1 + call_optional(A(), "f") + def test_nose_setup_func(testdir): p = testdir.makepyfile(""" from nose.tools import with_setup Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Nov 5 21:31:15 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 05 Nov 2012 20:31:15 -0000 Subject: [py-svn] commit/pytest: RonnyPfannschmidt: update changelog Message-ID: <20121105203115.9452.39290@bitbucket13.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/661a74564579/ changeset: 661a74564579 user: RonnyPfannschmidt date: 2012-11-05 21:31:08 summary: update changelog affected #: 1 file diff -r 2bde7353ee7d24bb45198cb469b12d05e7207d30 -r 661a745645796f8e3221f35b95468e27753c6900 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,8 @@ - fix issue209 - reintroduce python2.4 support by depending on newer pylib which re-introduced statement-finding for pre-AST interpreters +- nose support: only call setup, if its a callable + Changes between 2.3.1 and 2.3.2 ----------------------------------- Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Nov 5 21:52:19 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 05 Nov 2012 20:52:19 -0000 Subject: [py-svn] commit/pytest: RonnyPfannschmidt: add a xfailing test for issue 199 Message-ID: <20121105205219.21377.9503@bitbucket20.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/273a571c618f/ changeset: 273a571c618f user: RonnyPfannschmidt date: 2012-11-05 21:52:12 summary: add a xfailing test for issue 199 affected #: 1 file diff -r 661a745645796f8e3221f35b95468e27753c6900 -r 273a571c618fa2f153de117ef86e78ae2907893b testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -237,6 +237,25 @@ assert l[1].args == () assert l[2].args == ("pos1", ) + @pytest.mark.xfail(reason='unfixed') + def test_merging_markers_deep(self, testdir): + # issue 199 - propagate markers into nested classes + p = testdir.makepyfile(""" + import pytest + class TestA: + pytestmark = pytest.mark.a + def test_b(self): + assert True + class TestC: + # this one didnt get marked + def test_d(self): + assert True + """) + items, rec = testdir.inline_genitems(p) + for item in items: + print item, item.keywords + assert 'a' in item.keywords + def test_mark_with_wrong_marker(self, testdir): reprec = testdir.inline_runsource(""" import pytest Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 09:09:59 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 08:09:59 -0000 Subject: [py-svn] commit/pytest: hpk42: addresses issue209 - avoid error messages from pip on python2.4 related to file, however, never be imported with this interpreter Message-ID: <20121106080959.14474.24832@bitbucket12.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/b3c9ed1fad2f/ changeset: b3c9ed1fad2f user: hpk42 date: 2012-11-06 09:08:54 summary: addresses issue209 - avoid error messages from pip on python2.4 related to file, however, never be imported with this interpreter affected #: 3 files diff -r 273a571c618fa2f153de117ef86e78ae2907893b -r b3c9ed1fad2f4fef2e9959b2032dd56b224f6e15 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.3.dev1' +__version__ = '2.3.3.dev2' diff -r 273a571c618fa2f153de117ef86e78ae2907893b -r b3c9ed1fad2f4fef2e9959b2032dd56b224f6e15 _pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -34,7 +34,7 @@ PYTEST_TAG = "%s-%s%s-PYTEST" % (impl, ver[0], ver[1]) del ver, impl -PYC_EXT = ".py" + ("c" if __debug__ else "o") +PYC_EXT = ".py" + (__debug__ and "c" or "o") PYC_TAIL = "." + PYTEST_TAG + PYC_EXT REWRITE_NEWLINES = sys.version_info[:2] != (2, 7) and sys.version_info < (3, 2) diff -r 273a571c618fa2f153de117ef86e78ae2907893b -r b3c9ed1fad2f4fef2e9959b2032dd56b224f6e15 setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.3.dev1', + version='2.3.3.dev2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 09:14:54 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 08:14:54 -0000 Subject: [py-svn] commit/pytest: hpk42: fix issue219 - add trove classifiers for py24-py33 Message-ID: <20121106081454.15179.63010@bitbucket05.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/de91b23c2d0d/ changeset: de91b23c2d0d user: hpk42 date: 2012-11-06 09:14:41 summary: fix issue219 - add trove classifiers for py24-py33 affected #: 2 files diff -r b3c9ed1fad2f4fef2e9959b2032dd56b224f6e15 -r de91b23c2d0d9dc9f8d8cc6966f0c7fe1c1fc8dd CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -18,6 +18,8 @@ - nose support: only call setup, if its a callable +- fix issue219 - add py2.4-3.3 classifiers to TROVE list + Changes between 2.3.1 and 2.3.2 ----------------------------------- diff -r b3c9ed1fad2f4fef2e9959b2032dd56b224f6e15 -r de91b23c2d0d9dc9f8d8cc6966f0c7fe1c1fc8dd setup.py --- a/setup.py +++ b/setup.py @@ -43,8 +43,10 @@ 'Topic :: Software Development :: Testing', 'Topic :: Software Development :: Libraries', 'Topic :: Utilities', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3'], + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3'] + [ + ("Programming Language :: Python :: %s" % x) for x in + "2.4 2.5 2.6 2.7 3.0 3.1 3.2 3.3".split()], packages=['_pytest', '_pytest.assertion'], py_modules=['pytest'], zip_safe=False, Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 09:18:05 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 08:18:05 -0000 Subject: [py-svn] commit/py: Manuel Jacob: Include * and ** arguments in py.code.FormattedExcinfo. Message-ID: <20121106081805.17414.72550@bitbucket21.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/22bf546e4878/ changeset: 22bf546e4878 user: Manuel Jacob date: 2012-11-05 23:49:21 summary: Include * and ** arguments in py.code.FormattedExcinfo. affected #: 3 files diff -r 88c67bb0484990537681b03840cc488690719311 -r 22bf546e487897b1b88fa075f45753bc1a4eb538 py/_code/code.py --- a/py/_code/code.py +++ b/py/_code/code.py @@ -1,5 +1,6 @@ import py import sys, os.path +from inspect import CO_VARARGS, CO_VARKEYWORDS builtin_repr = repr @@ -49,12 +50,19 @@ # return source only for that part of code return py.code.Source(self.raw) - def getargs(self): + def getargs(self, var=False): """ return a tuple with the argument names for the code object + + if 'var' is set True also return the names of the variable and + keyword arguments when present """ # handfull shortcut for getting args raw = self.raw - return raw.co_varnames[:raw.co_argcount] + argcount = raw.co_argcount + if var: + argcount += raw.co_flags & CO_VARARGS + argcount += raw.co_flags & CO_VARKEYWORDS + return raw.co_varnames[:argcount] class Frame(object): """Wrapper around a Python frame holding f_locals and f_globals @@ -102,11 +110,14 @@ def is_true(self, object): return object - def getargs(self): + def getargs(self, var=False): """ return a list of tuples (name, value) for all arguments + + if 'var' is set True also include the variable and keyword + arguments when present """ retval = [] - for arg in self.code.getargs(): + for arg in self.code.getargs(var): try: retval.append((arg, self.f_locals[arg])) except KeyError: @@ -432,7 +443,7 @@ def repr_args(self, entry): if self.funcargs: args = [] - for argname, argvalue in entry.frame.getargs(): + for argname, argvalue in entry.frame.getargs(var=True): args.append((argname, self._saferepr(argvalue))) return ReprFuncArgs(args) diff -r 88c67bb0484990537681b03840cc488690719311 -r 22bf546e487897b1b88fa075f45753bc1a4eb538 testing/code/test_code.py --- a/testing/code/test_code.py +++ b/testing/code/test_code.py @@ -104,3 +104,48 @@ s = unicode_or_repr(A()) assert 'print-error' in s assert 'ValueError' in s + + +def test_code_getargs(): + def f1(x): + pass + c1 = py.code.Code(f1) + assert c1.getargs(var=True) == ('x',) + + def f2(x, *y): + pass + c2 = py.code.Code(f2) + assert c2.getargs(var=True) == ('x', 'y') + + def f3(x, **z): + pass + c3 = py.code.Code(f3) + assert c3.getargs(var=True) == ('x', 'z') + + def f4(x, *y, **z): + pass + c4 = py.code.Code(f4) + assert c4.getargs(var=True) == ('x', 'y', 'z') + + +def test_frame_getargs(): + def f1(x): + return sys._getframe(0) + fr1 = py.code.Frame(f1('a')) + assert fr1.getargs(var=True) == [('x', 'a')] + + def f2(x, *y): + return sys._getframe(0) + fr2 = py.code.Frame(f2('a', 'b', 'c')) + assert fr2.getargs(var=True) == [('x', 'a'), ('y', ('b', 'c'))] + + def f3(x, **z): + return sys._getframe(0) + fr3 = py.code.Frame(f3('a', b='c')) + assert fr3.getargs(var=True) == [('x', 'a'), ('z', {'b': 'c'})] + + def f4(x, *y, **z): + return sys._getframe(0) + fr4 = py.code.Frame(f4('a', 'b', c='d')) + assert fr4.getargs(var=True) == [('x', 'a'), ('y', ('b',)), + ('z', {'c': 'd'})] diff -r 88c67bb0484990537681b03840cc488690719311 -r 22bf546e487897b1b88fa075f45753bc1a4eb538 testing/code/test_excinfo.py --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -494,6 +494,27 @@ assert tw.lines[1] == "x = 5, y = 13" assert tw.lines[2] == "z = " + repr('z' * 120) + def test_repr_tracebackentry_lines_var_kw_args(self, importasmod): + mod = importasmod(""" + def func1(x, *y, **z): + raise ValueError("hello\\nworld") + """) + excinfo = py.test.raises(ValueError, mod.func1, 'a', 'b', c='d') + excinfo.traceback = excinfo.traceback.filter() + entry = excinfo.traceback[-1] + p = FormattedExcinfo(funcargs=True) + reprfuncargs = p.repr_args(entry) + assert reprfuncargs.args[0] == ('x', repr('a')) + assert reprfuncargs.args[1] == ('y', repr(('b',))) + assert reprfuncargs.args[2] == ('z', repr({'c': 'd'})) + + p = FormattedExcinfo(funcargs=True) + repr_entry = p.repr_traceback_entry(entry) + assert repr_entry.reprfuncargs.args == reprfuncargs.args + tw = TWMock() + repr_entry.toterminal(tw) + assert tw.lines[0] == "x = 'a', y = ('b',), z = {'c': 'd'}" + def test_repr_tracebackentry_short(self, importasmod): mod = importasmod(""" def func1(): Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 09:19:52 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 08:19:52 -0000 Subject: [py-svn] commit/py: hpk42: fix issue23 - *, ** support by Manuel Jacob (already merged, just added CHANGELOG entry) Message-ID: <20121106081952.26523.62536@bitbucket24.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/f5a4b5f2a9a0/ changeset: f5a4b5f2a9a0 user: hpk42 date: 2012-11-06 09:19:43 summary: fix issue23 - *,** support by Manuel Jacob (already merged, just added CHANGELOG entry) affected #: 3 files diff -r 22bf546e487897b1b88fa075f45753bc1a4eb538 -r f5a4b5f2a9a027e6cf7d9d6cb7f9d1c79623bd81 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,9 @@ - fix python2.4 support - for pre-AST interpreters re-introduce old way to find statements in exceptions (closes pytest issue 209) - add tox.ini to distribution +- fix issue23 - print *,** args information in tracebacks, + thanks Manuel Jacob + Changes between 1.4.10 and 1.4.11 ================================================== diff -r 22bf546e487897b1b88fa075f45753bc1a4eb538 -r f5a4b5f2a9a027e6cf7d9d6cb7f9d1c79623bd81 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.12.dev1' +__version__ = '1.4.12.dev2' from py import _apipkg diff -r 22bf546e487897b1b88fa075f45753bc1a4eb538 -r f5a4b5f2a9a027e6cf7d9d6cb7f9d1c79623bd81 setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.12.dev1', + version='1.4.12.dev2', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 09:28:05 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 08:28:05 -0000 Subject: [py-svn] commit/pytest: hpk42: amend changelog entries Message-ID: <20121106082805.30160.36715@bitbucket02.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/7621cd3e3423/ changeset: 7621cd3e3423 user: hpk42 date: 2012-11-06 09:27:58 summary: amend changelog entries affected #: 3 files diff -r de91b23c2d0d9dc9f8d8cc6966f0c7fe1c1fc8dd -r 7621cd3e34239576f07b716125776adb83fd487d CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,7 +3,7 @@ - fix issue214 - parse modules that contain special objects like e. g. flask's request object which blows up on getattr access if no request - is active. + is active. thanks Thomas Waldmann. - fix issue213 - allow to parametrize with values like numpy arrays that do not support an __eq__ operator @@ -11,15 +11,18 @@ - fix issue215 - split test_python.org into multiple files - fix issue148 - @unittest.skip on classes is now recognized and avoids - calling setUpClass/tearDownClass + calling setUpClass/tearDownClass, thanks Pavel Repin - fix issue209 - reintroduce python2.4 support by depending on newer pylib which re-introduced statement-finding for pre-AST interpreters -- nose support: only call setup, if its a callable +- nose support: only call setup if its a callable, thanks Andrew + Taumoefolau - fix issue219 - add py2.4-3.3 classifiers to TROVE list +- in tracebacks *,** arg values are now shown next to normal arguments + (thanks Manuel Jacob) Changes between 2.3.1 and 2.3.2 ----------------------------------- diff -r de91b23c2d0d9dc9f8d8cc6966f0c7fe1c1fc8dd -r 7621cd3e34239576f07b716125776adb83fd487d _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.3.dev2' +__version__ = '2.3.3.dev3' diff -r de91b23c2d0d9dc9f8d8cc6966f0c7fe1c1fc8dd -r 7621cd3e34239576f07b716125776adb83fd487d setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.3.dev2', + version='2.3.3.dev3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -33,7 +33,7 @@ entry_points= make_entry_points(), cmdclass = {'test': PyTest}, # the following should be enabled for release - install_requires=['py>=1.4.12.dev1'], + install_requires=['py>=1.4.12.dev2'], classifiers=['Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 11:04:27 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 10:04:27 -0000 Subject: [py-svn] commit/pytest: hpk42: fix issue217 - to support @mock.patch with pytest funcarg-fixtures, also split out python integration tests into python/integration.py and fix nose/mark tests Message-ID: <20121106100427.3472.49300@bitbucket15.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/8bd54f9c01c6/ changeset: 8bd54f9c01c6 user: hpk42 date: 2012-11-06 11:04:11 summary: fix issue217 - to support @mock.patch with pytest funcarg-fixtures, also split out python integration tests into python/integration.py and fix nose/mark tests affected #: 9 files diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -24,6 +24,9 @@ - in tracebacks *,** arg values are now shown next to normal arguments (thanks Manuel Jacob) +- fix issue217 - support mock.patch with pytest's fixtures - note that + you need either mock-1.0.1 or the python3.3 builtin unittest.mock. + Changes between 2.3.1 and 2.3.2 ----------------------------------- diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.3.dev3' +__version__ = '2.3.3.dev4' diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1659,8 +1659,14 @@ def getfuncargnames(function, startindex=None): # XXX merge with main.py's varnames #assert not inspect.isclass(function) + realfunction = function + while hasattr(realfunction, "__wrapped__"): + realfunction = realfunction.__wrapped__ if startindex is None: startindex = inspect.ismethod(function) and 1 or 0 + if realfunction != function: + startindex += len(getattr(function, "patchings", [])) + function = realfunction argnames = inspect.getargs(py.code.getrawcode(function))[0] defaults = getattr(function, 'func_defaults', getattr(function, '__defaults__', None)) or () diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.3.dev3', + version='2.3.3.dev4', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 testing/python/fixture.py --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -541,59 +541,6 @@ "*ZeroDivisionError*", ]) -class TestOEJSKITSpecials: - def test_funcarg_non_pycollectobj(self, testdir): # rough jstests usage - testdir.makeconftest(""" - import pytest - def pytest_pycollect_makeitem(collector, name, obj): - if name == "MyClass": - return MyCollector(name, parent=collector) - class MyCollector(pytest.Collector): - def reportinfo(self): - return self.fspath, 3, "xyz" - """) - modcol = testdir.getmodulecol(""" - def pytest_funcarg__arg1(request): - return 42 - class MyClass: - pass - """) - # this hook finds funcarg factories - rep = modcol.ihook.pytest_make_collect_report(collector=modcol) - clscol = rep.result[0] - clscol.obj = lambda arg1: None - clscol.funcargs = {} - funcargs.fillfixtures(clscol) - assert clscol.funcargs['arg1'] == 42 - - def test_autouse_fixture(self, testdir): # rough jstests usage - testdir.makeconftest(""" - import pytest - def pytest_pycollect_makeitem(collector, name, obj): - if name == "MyClass": - return MyCollector(name, parent=collector) - class MyCollector(pytest.Collector): - def reportinfo(self): - return self.fspath, 3, "xyz" - """) - modcol = testdir.getmodulecol(""" - import pytest - @pytest.fixture(autouse=True) - def hello(): - pass - def pytest_funcarg__arg1(request): - return 42 - class MyClass: - pass - """) - # this hook finds funcarg factories - rep = modcol.ihook.pytest_make_collect_report(collector=modcol) - clscol = rep.result[0] - clscol.obj = lambda: None - clscol.funcargs = {} - funcargs.fillfixtures(clscol) - assert not clscol.funcargs - class TestFixtureUsages: def test_noargfixturedec(self, testdir): testdir.makepyfile(""" diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 testing/python/integration.py --- /dev/null +++ b/testing/python/integration.py @@ -0,0 +1,119 @@ +import pytest, py, sys + +class TestOEJSKITSpecials: + def test_funcarg_non_pycollectobj(self, testdir): # rough jstests usage + testdir.makeconftest(""" + import pytest + def pytest_pycollect_makeitem(collector, name, obj): + if name == "MyClass": + return MyCollector(name, parent=collector) + class MyCollector(pytest.Collector): + def reportinfo(self): + return self.fspath, 3, "xyz" + """) + modcol = testdir.getmodulecol(""" + def pytest_funcarg__arg1(request): + return 42 + class MyClass: + pass + """) + # this hook finds funcarg factories + rep = modcol.ihook.pytest_make_collect_report(collector=modcol) + clscol = rep.result[0] + clscol.obj = lambda arg1: None + clscol.funcargs = {} + pytest._fillfuncargs(clscol) + assert clscol.funcargs['arg1'] == 42 + + def test_autouse_fixture(self, testdir): # rough jstests usage + testdir.makeconftest(""" + import pytest + def pytest_pycollect_makeitem(collector, name, obj): + if name == "MyClass": + return MyCollector(name, parent=collector) + class MyCollector(pytest.Collector): + def reportinfo(self): + return self.fspath, 3, "xyz" + """) + modcol = testdir.getmodulecol(""" + import pytest + @pytest.fixture(autouse=True) + def hello(): + pass + def pytest_funcarg__arg1(request): + return 42 + class MyClass: + pass + """) + # this hook finds funcarg factories + rep = modcol.ihook.pytest_make_collect_report(collector=modcol) + clscol = rep.result[0] + clscol.obj = lambda: None + clscol.funcargs = {} + pytest._fillfuncargs(clscol) + assert not clscol.funcargs + + +class TestMockDecoration: + def test_wrapped_getfuncargnames(self): + from _pytest.python import getfuncargnames + def wrap(f): + def func(): + pass + func.__wrapped__ = f + return func + @wrap + def f(x): + pass + l = getfuncargnames(f) + assert l == ("x",) + + def test_wrapped_getfuncargnames_patching(self): + from _pytest.python import getfuncargnames + def wrap(f): + def func(): + pass + func.__wrapped__ = f + func.patchings = ["qwe"] + return func + @wrap + def f(x, y, z): + pass + l = getfuncargnames(f) + assert l == ("y", "z") + + def test_unittest_mock(self, testdir): + pytest.importorskip("unittest.mock") + testdir.makepyfile(""" + import unittest.mock + class T(unittest.TestCase): + @unittest.mock.patch("os.path.abspath") + def test_hello(self, abspath): + import os + os.path.abspath("hello") + abspath.assert_any_call("hello") + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) + + def test_mock(self, testdir): + pytest.importorskip("mock", "1.0.1") + testdir.makepyfile(""" + import os + import unittest + import mock + + class T(unittest.TestCase): + @mock.patch("os.path.abspath") + def test_hello(self, abspath): + os.path.abspath("hello") + abspath.assert_any_call("hello") + @mock.patch("os.path.abspath") + @mock.patch("os.path.normpath") + def test_someting(normpath, abspath, tmpdir): + abspath.return_value = "this" + os.path.normpath(os.path.abspath("hello")) + normpath.assert_any_call("this") + """) + reprec = testdir.inline_run() + reprec.assertoutcome(passed=2) diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -253,7 +253,7 @@ """) items, rec = testdir.inline_genitems(p) for item in items: - print item, item.keywords + print (item, item.keywords) assert 'a' in item.keywords def test_mark_with_wrong_marker(self, testdir): diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 testing/test_nose.py --- a/testing/test_nose.py +++ b/testing/test_nose.py @@ -103,21 +103,13 @@ my_teardown = 2 def test_hello(): - print (l) - assert l == [1] - - def test_world(): - print (l) - assert l == [1,2] + assert l == [] test_hello.setup = my_setup test_hello.teardown = my_teardown """) - result = testdir.runpytest(p, '-p', 'nose') - result.stdout.fnmatch_lines([ - "*TypeError: 'int' object is not callable*" - ]) - + reprec = testdir.inline_run() + reprec.assertoutcome(passed=1) def test_nose_setup_partial(testdir): py.test.importorskip("functools") diff -r 7621cd3e34239576f07b716125776adb83fd487d -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 tox.ini --- a/tox.ini +++ b/tox.ini @@ -21,6 +21,8 @@ changedir=. basepython=python2.7 deps=pytest-xdist + :pypi:mock + :pypi:nose commands= py.test -n3 -rfsxX \ --junitxml={envlogdir}/junit-{envname}.xml testing Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 14:13:06 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 13:13:06 -0000 Subject: [py-svn] commit/pytest: hpk42: fix issue127 improve pytest_addoption docs, add new config.getoption(name) method for consistency. Message-ID: <20121106131306.14955.28339@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/d12ea5ebf62b/ changeset: d12ea5ebf62b user: hpk42 date: 2012-11-06 14:09:12 summary: fix issue127 improve pytest_addoption docs, add new config.getoption(name) method for consistency. affected #: 10 files diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -27,6 +27,9 @@ - fix issue217 - support mock.patch with pytest's fixtures - note that you need either mock-1.0.1 or the python3.3 builtin unittest.mock. +- fix issue127 - improve documentation for pytest_addoption() and + add a ``config.getoption(name)`` helper function for consistency. + Changes between 2.3.1 and 2.3.2 ----------------------------------- diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.3.dev4' +__version__ = '2.3.3.dev5' diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 _pytest/config.py --- a/_pytest/config.py +++ b/_pytest/config.py @@ -271,9 +271,8 @@ class Config(object): """ access to configuration values, pluginmanager and plugin hooks. """ def __init__(self, pluginmanager=None): - #: command line option values, which must have been previously added - #: via calls like ``parser.addoption(...)`` or - #: ``parser.getgroup(groupname).addoption(...)`` + #: access to command line option as attributes. + #: (deprecated), use :py:func:`getoption() <_pytest.config.Config.getoption>` instead self.option = CmdOptions() self._parser = Parser( usage="usage: %prog [options] [file_or_dir] [file_or_dir] [...]", @@ -285,6 +284,7 @@ self._conftest = Conftest(onimport=self._onimportconftest) self.hook = self.pluginmanager.hook self._inicache = {} + self._opt2dest = {} self._cleanup = [] @classmethod @@ -305,6 +305,9 @@ self.pluginmanager.consider_conftest(conftestmodule) def _processopt(self, opt): + for name in opt._short_opts + opt._long_opts: + self._opt2dest[name] = opt.dest + if hasattr(opt, 'default') and opt.dest: if not hasattr(self.option, opt.dest): setattr(self.option, opt.dest, opt.default) @@ -383,8 +386,9 @@ x.append(line) # modifies the cached list inline def getini(self, name): - """ return configuration value from an ini file. If the - specified name hasn't been registered through a prior ``parse.addini`` + """ return configuration value from an :ref:`ini file `. If the + specified name hasn't been registered through a prior + :py:func:`parser.addini ` call (usually from a plugin), a ValueError is raised. """ try: return self._inicache[name] @@ -438,8 +442,22 @@ self._checkconftest(name) return self._conftest.rget(name, path) + def getoption(self, name): + """ return command line option value. + + :arg name: name of the option. You may also specify + the literal ``--OPT`` option instead of the "dest" option name. + """ + name = self._opt2dest.get(name, name) + try: + return getattr(self.option, name) + except AttributeError: + raise ValueError("no option named %r" % (name,)) + def getvalue(self, name, path=None): - """ return ``name`` value looked set from command line options. + """ return command line option value. + + :arg name: name of the command line option (deprecated) if we can't find the option also lookup the name in a matching conftest file. diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 _pytest/hookspec.py --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -23,10 +23,28 @@ """modify command line arguments before option parsing. """ def pytest_addoption(parser): - """use the parser to add optparse-style options and ini-style - config values via calls, see :py:func:`parser.addoption(...) - <_pytest.config.Parser.addoption>` - and :py:func:`parser.addini(...) <_pytest.config.Parser.addini>`. + """register optparse-style options and ini-style config values. + + This function must be implemented in a :ref:`plugin ` and is + called once at the beginning of a test run. + + :arg parser: To add command line options, call + :py:func:`parser.addoption(...) <_pytest.config.Parser.addoption>`. + To add ini-file values call :py:func:`parser.addini(...) + <_pytest.config.Parser.addini>`. + + Options can later be accessed through the + :py:class:`config <_pytest.config.Config>` object, respectively: + + - :py:func:`config.getoption(name) <_pytest.config.Config.getoption>` to + retrieve the value of a command line option. + + - :py:func:`config.getini(name) <_pytest.config.Config.getini>` to retrieve + a value read from an ini-style file. + + The config object is passed around on many internal objects via the ``.config`` + attribute or can be retrieved as the ``pytestconfig`` fixture or accessed + via (deprecated) ``pytest.config``. """ def pytest_cmdline_main(config): @@ -35,7 +53,7 @@ pytest_cmdline_main.firstresult = True def pytest_configure(config): - """ called after command line options have been parsed. + """ called after command line options have been parsed and all plugins and initial conftest files been loaded. """ diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 doc/en/customize.txt --- a/doc/en/customize.txt +++ b/doc/en/customize.txt @@ -12,6 +12,8 @@ This will display command line and configuration file settings which were registered by installed plugins. +.. _inifiles: + How test configuration is read from configuration INI-files ------------------------------------------------------------- diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -194,7 +194,7 @@ import pytest def pytest_addoption(parser): - parser.addoption("-E", dest="env", action="store", metavar="NAME", + parser.addoption("-E", action="store", metavar="NAME", help="only run tests matching the environment NAME.") def pytest_configure(config): @@ -206,7 +206,7 @@ envmarker = item.keywords.get("env", None) if envmarker is not None: envname = envmarker.args[0] - if envname != item.config.option.env: + if envname != item.config.getoption("-E"): pytest.skip("test requires env %r" % envname) A test file using this local plugin:: diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -33,7 +33,7 @@ @pytest.fixture def cmdopt(request): - return request.config.option.cmdopt + return request.config.getoption("--cmdopt") Let's run this without supplying our new option:: @@ -129,7 +129,7 @@ help="run slow tests") def pytest_runtest_setup(item): - if 'slow' in item.keywords and not item.config.getvalue("runslow"): + if 'slow' in item.keywords and not item.config.getoption("--runslow"): pytest.skip("need --runslow option to run") We can now write a test module like this:: diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 doc/en/plugins.txt --- a/doc/en/plugins.txt +++ b/doc/en/plugins.txt @@ -5,7 +5,7 @@ py.test implements all aspects of configuration, collection, running and reporting by calling `well specified hooks`_. Virtually any Python module can be registered as a plugin. It can implement any number of hook functions (usually two or three) which all have a ``pytest_`` prefix, making hook functions easy to distinguish and find. There are three basic location types: -* `builtin plugins`_: loaded from py.test's own ``pytest/plugin`` directory. +* `builtin plugins`_: loaded from py.test's internal ``_pytest`` directory. * `external plugins`_: modules discovered through `setuptools entry points`_ * `conftest.py plugins`_: modules auto-discovered in test directories @@ -155,6 +155,8 @@ ``myproject.pluginmodule`` as a plugin which can define `well specified hooks`_. +.. _`pluginorder`: + Plugin discovery order at tool startup -------------------------------------------- @@ -175,6 +177,7 @@ * by recursively loading all plugins specified by the ``pytest_plugins`` variable in ``conftest.py`` files + Requiring/Loading plugins in a test module or conftest file ------------------------------------------------------------- diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.3.dev4', + version='2.3.3.dev5', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 8bd54f9c01c61757fc6fe14bccae930a540a90c3 -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 testing/test_config.py --- a/testing/test_config.py +++ b/testing/test_config.py @@ -103,6 +103,16 @@ assert config.getvalue("x", o) == 1 pytest.raises(KeyError, 'config.getvalue("y", o)') + def test_config_getoption(self, testdir): + testdir.makeconftest(""" + def pytest_addoption(parser): + parser.addoption("--hello", "-X", dest="hello") + """) + config = testdir.parseconfig("--hello=this") + for x in ("hello", "--hello", "-X"): + assert config.getoption(x) == "this" + pytest.raises(ValueError, "config.getoption('qweqwe')") + def test_config_getvalueorskip(self, testdir): config = testdir.parseconfig() pytest.raises(pytest.skip.Exception, @@ -304,3 +314,4 @@ "*pytest*", "*-h*", ]) + Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 14:50:08 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 13:50:08 -0000 Subject: [py-svn] commit/py: hpk42: fix windows bug, bump version Message-ID: <20121106135008.25185.52507@bitbucket05.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/f07af25a2678/ changeset: f07af25a2678 user: hpk42 date: 2012-11-06 14:48:41 summary: fix windows bug, bump version affected #: 4 files diff -r f5a4b5f2a9a027e6cf7d9d6cb7f9d1c79623bd81 -r f07af25a26786e4825b5170e17ad693245cb3426 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Changes between 1.4.11 and 1.4.12.dev +Changes between 1.4.11 and 1.4.12 ================================================== - fix python2.4 support - for pre-AST interpreters re-introduce diff -r f5a4b5f2a9a027e6cf7d9d6cb7f9d1c79623bd81 -r f07af25a26786e4825b5170e17ad693245cb3426 py/__init__.py --- a/py/__init__.py +++ b/py/__init__.py @@ -8,7 +8,7 @@ (c) Holger Krekel and others, 2004-2010 """ -__version__ = '1.4.12.dev2' +__version__ = '1.4.12' from py import _apipkg diff -r f5a4b5f2a9a027e6cf7d9d6cb7f9d1c79623bd81 -r f07af25a26786e4825b5170e17ad693245cb3426 py/_io/terminalwriter.py --- a/py/_io/terminalwriter.py +++ b/py/_io/terminalwriter.py @@ -199,7 +199,7 @@ def write(self, msg, **kw): if msg: if not isinstance(msg, (bytes, text)): - msg = text(s) + msg = text(msg) oldcolors = None if self.hasmarkup and kw: handle = GetStdHandle(STD_OUTPUT_HANDLE) diff -r f5a4b5f2a9a027e6cf7d9d6cb7f9d1c79623bd81 -r f07af25a26786e4825b5170e17ad693245cb3426 setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='py', description='library with cross-python path, ini-parsing, io, code, log facilities', long_description = open('README.txt').read(), - version='1.4.12.dev2', + version='1.4.12', url='http://pylib.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 15:02:04 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 14:02:04 -0000 Subject: [py-svn] commit/pytest: hpk42: bump to 2.3.3, add release announce Message-ID: <20121106140204.22256.81232@bitbucket25.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/14583b72af10/ changeset: 14583b72af10 user: hpk42 date: 2012-11-06 14:41:10 summary: bump to 2.3.3, add release announce affected #: 21 files diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -Changes between 2.3.2 and 2.3.3.dev +Changes between 2.3.2 and 2.3.3 ----------------------------------- - fix issue214 - parse modules that contain special objects like e. g. diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.3.dev5' +__version__ = '2.3.3' diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/announce/index.txt --- a/doc/en/announce/index.txt +++ b/doc/en/announce/index.txt @@ -5,6 +5,7 @@ .. toctree:: :maxdepth: 2 + release-2.3.3 release-2.3.2 release-2.3.1 release-2.3.0 diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/assert.txt --- a/doc/en/assert.txt +++ b/doc/en/assert.txt @@ -26,7 +26,7 @@ $ py.test test_assert1.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items test_assert1.py F @@ -110,7 +110,7 @@ $ py.test test_assert2.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items test_assert2.py F diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/capture.txt --- a/doc/en/capture.txt +++ b/doc/en/capture.txt @@ -64,7 +64,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_module.py .F @@ -78,7 +78,7 @@ test_module.py:9: AssertionError ----------------------------- Captured stdout ------------------------------ - setting up + setting up ==================== 1 failed, 1 passed in 0.01 seconds ==================== Accessing captured output from a test function diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,7 +17,7 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = release = "2.3.2" +version = release = "2.3.3" import sys, os diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/doctest.txt --- a/doc/en/doctest.txt +++ b/doc/en/doctest.txt @@ -44,7 +44,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items mymodule.py . diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -26,19 +26,19 @@ $ py.test -v -m webtest =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_server.py:3: test_send_http PASSED =================== 1 tests deselected by "-m 'webtest'" =================== - ================== 1 passed, 1 deselected in 0.01 seconds ================== + ================== 1 passed, 1 deselected in 0.02 seconds ================== Or the inverse, running all tests except the webtest ones:: $ py.test -v -m "not webtest" =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_server.py:6: test_something_quick PASSED @@ -145,7 +145,7 @@ $ py.test -k send_http # running with the above defined examples =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items test_server.py . @@ -157,7 +157,7 @@ $ py.test -k-send_http =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items test_mark_classlevel.py .. @@ -170,7 +170,7 @@ $ py.test -kTestClass =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items test_mark_classlevel.py .. @@ -223,7 +223,7 @@ $ py.test -E stage2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items test_someenv.py s @@ -234,7 +234,7 @@ $ py.test -E stage1 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items test_someenv.py . @@ -351,12 +351,12 @@ $ py.test -rs # this option reports skip reasons =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items test_plat.py s.s. ========================= short test summary info ========================== - SKIP [2] /tmp/doc-exec-99/conftest.py:12: cannot run on platform linux2 + SKIP [2] /tmp/doc-exec-57/conftest.py:12: cannot run on platform linux2 =================== 2 passed, 2 skipped in 0.01 seconds ==================== @@ -364,7 +364,7 @@ $ py.test -m linux2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items test_plat.py . diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/example/nonpython.txt --- a/doc/en/example/nonpython.txt +++ b/doc/en/example/nonpython.txt @@ -27,7 +27,7 @@ nonpython $ py.test test_simple.yml =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_simple.yml .F @@ -37,7 +37,7 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.03 seconds ==================== + ==================== 1 failed, 1 passed in 0.04 seconds ==================== You get one dot for the passing ``sub1: sub1`` check and one failure. Obviously in the above ``conftest.py`` you'll want to implement a more @@ -56,7 +56,7 @@ nonpython $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_simple.yml:1: usecase: ok PASSED @@ -67,17 +67,17 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.03 seconds ==================== + ==================== 1 failed, 1 passed in 0.04 seconds ==================== While developing your custom test collection and execution it's also interesting to just look at the collection tree:: nonpython $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items - ============================= in 0.02 seconds ============================= + ============================= in 0.04 seconds ============================= diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/example/parametrize.txt --- a/doc/en/example/parametrize.txt +++ b/doc/en/example/parametrize.txt @@ -104,7 +104,7 @@ $ py.test test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items test_scenarios.py .... @@ -116,7 +116,7 @@ $ py.test --collectonly test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items @@ -180,7 +180,7 @@ $ py.test test_backends.py --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items @@ -195,7 +195,7 @@ ================================= FAILURES ================================= _________________________ test_db_initialized[d2] __________________________ - db = + db = def test_db_initialized(db): # a dummy test @@ -250,7 +250,7 @@ ================================= FAILURES ================================= ________________________ TestClass.test_equals[1-2] ________________________ - self = , a = 1, b = 2 + self = , a = 1, b = 2 def test_equals(self, a, b): > assert a == b diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/example/pythoncollection.txt --- a/doc/en/example/pythoncollection.txt +++ b/doc/en/example/pythoncollection.txt @@ -43,7 +43,7 @@ $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items @@ -82,7 +82,7 @@ . $ py.test --collectonly pythoncollection.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 3 items @@ -91,7 +91,7 @@ - ============================= in 0.00 seconds ============================= + ============================= in 0.01 seconds ============================= customizing test collection to find all .py files --------------------------------------------------------- @@ -135,7 +135,7 @@ $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/example/reportingdemo.txt --- a/doc/en/example/reportingdemo.txt +++ b/doc/en/example/reportingdemo.txt @@ -13,7 +13,7 @@ assertion $ py.test failure_demo.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 39 items failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF @@ -30,7 +30,7 @@ failure_demo.py:15: AssertionError _________________________ TestFailing.test_simple __________________________ - self = + self = def test_simple(self): def f(): @@ -40,13 +40,13 @@ > assert f() == g() E assert 42 == 43 - E + where 42 = () - E + and 43 = () + E + where 42 = () + E + and 43 = () failure_demo.py:28: AssertionError ____________________ TestFailing.test_simple_multiline _____________________ - self = + self = def test_simple_multiline(self): otherfunc_multi( @@ -66,19 +66,19 @@ failure_demo.py:11: AssertionError ___________________________ TestFailing.test_not ___________________________ - self = + self = def test_not(self): def f(): return 42 > assert not f() E assert not 42 - E + where 42 = () + E + where 42 = () failure_demo.py:38: AssertionError _________________ TestSpecialisedExplanations.test_eq_text _________________ - self = + self = def test_eq_text(self): > assert 'spam' == 'eggs' @@ -89,7 +89,7 @@ failure_demo.py:42: AssertionError _____________ TestSpecialisedExplanations.test_eq_similar_text _____________ - self = + self = def test_eq_similar_text(self): > assert 'foo 1 bar' == 'foo 2 bar' @@ -102,7 +102,7 @@ failure_demo.py:45: AssertionError ____________ TestSpecialisedExplanations.test_eq_multiline_text ____________ - self = + self = def test_eq_multiline_text(self): > assert 'foo\nspam\nbar' == 'foo\neggs\nbar' @@ -115,7 +115,7 @@ failure_demo.py:48: AssertionError ______________ TestSpecialisedExplanations.test_eq_long_text _______________ - self = + self = def test_eq_long_text(self): a = '1'*100 + 'a' + '2'*100 @@ -132,7 +132,7 @@ failure_demo.py:53: AssertionError _________ TestSpecialisedExplanations.test_eq_long_text_multiline __________ - self = + self = def test_eq_long_text_multiline(self): a = '1\n'*100 + 'a' + '2\n'*100 @@ -156,7 +156,7 @@ failure_demo.py:58: AssertionError _________________ TestSpecialisedExplanations.test_eq_list _________________ - self = + self = def test_eq_list(self): > assert [0, 1, 2] == [0, 1, 3] @@ -166,7 +166,7 @@ failure_demo.py:61: AssertionError ______________ TestSpecialisedExplanations.test_eq_list_long _______________ - self = + self = def test_eq_list_long(self): a = [0]*100 + [1] + [3]*100 @@ -178,7 +178,7 @@ failure_demo.py:66: AssertionError _________________ TestSpecialisedExplanations.test_eq_dict _________________ - self = + self = def test_eq_dict(self): > assert {'a': 0, 'b': 1} == {'a': 0, 'b': 2} @@ -191,7 +191,7 @@ failure_demo.py:69: AssertionError _________________ TestSpecialisedExplanations.test_eq_set __________________ - self = + self = def test_eq_set(self): > assert set([0, 10, 11, 12]) == set([0, 20, 21]) @@ -207,7 +207,7 @@ failure_demo.py:72: AssertionError _____________ TestSpecialisedExplanations.test_eq_longer_list ______________ - self = + self = def test_eq_longer_list(self): > assert [1,2] == [1,2,3] @@ -217,7 +217,7 @@ failure_demo.py:75: AssertionError _________________ TestSpecialisedExplanations.test_in_list _________________ - self = + self = def test_in_list(self): > assert 1 in [0, 2, 3, 4, 5] @@ -226,7 +226,7 @@ failure_demo.py:78: AssertionError __________ TestSpecialisedExplanations.test_not_in_text_multiline __________ - self = + self = def test_not_in_text_multiline(self): text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail' @@ -244,7 +244,7 @@ failure_demo.py:82: AssertionError ___________ TestSpecialisedExplanations.test_not_in_text_single ____________ - self = + self = def test_not_in_text_single(self): text = 'single foo line' @@ -257,7 +257,7 @@ failure_demo.py:86: AssertionError _________ TestSpecialisedExplanations.test_not_in_text_single_long _________ - self = + self = def test_not_in_text_single_long(self): text = 'head ' * 50 + 'foo ' + 'tail ' * 20 @@ -270,7 +270,7 @@ failure_demo.py:90: AssertionError ______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______ - self = + self = def test_not_in_text_single_long_term(self): text = 'head ' * 50 + 'f'*70 + 'tail ' * 20 @@ -289,7 +289,7 @@ i = Foo() > assert i.b == 2 E assert 1 == 2 - E + where 1 = .b + E + where 1 = .b failure_demo.py:101: AssertionError _________________________ test_attribute_instance __________________________ @@ -299,8 +299,8 @@ b = 1 > assert Foo().b == 2 E assert 1 == 2 - E + where 1 = .b - E + where = () + E + where 1 = .b + E + where = () failure_demo.py:107: AssertionError __________________________ test_attribute_failure __________________________ @@ -316,7 +316,7 @@ failure_demo.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - self = + self = def _get_b(self): > raise Exception('Failed to get attrib') @@ -332,15 +332,15 @@ b = 2 > assert Foo().b == Bar().b E assert 1 == 2 - E + where 1 = .b - E + where = () - E + and 2 = .b - E + where = () + E + where 1 = .b + E + where = () + E + and 2 = .b + E + where = () failure_demo.py:124: AssertionError __________________________ TestRaises.test_raises __________________________ - self = + self = def test_raises(self): s = 'qwe' @@ -352,10 +352,10 @@ > int(s) E ValueError: invalid literal for int() with base 10: 'qwe' - <0-codegen /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:851>:1: ValueError + <0-codegen /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:851>:1: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ - self = + self = def test_raises_doesnt(self): > raises(IOError, "int('3')") @@ -364,7 +364,7 @@ failure_demo.py:136: Failed __________________________ TestRaises.test_raise ___________________________ - self = + self = def test_raise(self): > raise ValueError("demo error") @@ -373,7 +373,7 @@ failure_demo.py:139: ValueError ________________________ TestRaises.test_tupleerror ________________________ - self = + self = def test_tupleerror(self): > a,b = [1] @@ -382,7 +382,7 @@ failure_demo.py:142: ValueError ______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______ - self = + self = def test_reinterpret_fails_with_print_for_the_fun_of_it(self): l = [1,2,3] @@ -395,7 +395,7 @@ l is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ - self = + self = def test_some_error(self): > if namenotexi: @@ -423,7 +423,7 @@ <2-codegen 'abc-123' /home/hpk/p/pytest/doc/en/example/assertion/failure_demo.py:162>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ - self = + self = def test_complex_error(self): def f(): @@ -452,7 +452,7 @@ failure_demo.py:5: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ - self = + self = def test_z1_unpack_error(self): l = [] @@ -462,7 +462,7 @@ failure_demo.py:179: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ - self = + self = def test_z2_type_error(self): l = 3 @@ -472,19 +472,19 @@ failure_demo.py:183: TypeError ______________________ TestMoreErrors.test_startswith ______________________ - self = + self = def test_startswith(self): s = "123" g = "456" > assert s.startswith(g) - E assert ('456') - E + where = '123'.startswith + E assert ('456') + E + where = '123'.startswith failure_demo.py:188: AssertionError __________________ TestMoreErrors.test_startswith_nested ___________________ - self = + self = def test_startswith_nested(self): def f(): @@ -492,15 +492,15 @@ def g(): return "456" > assert f().startswith(g()) - E assert ('456') - E + where = '123'.startswith - E + where '123' = () - E + and '456' = () + E assert ('456') + E + where = '123'.startswith + E + where '123' = () + E + and '456' = () failure_demo.py:195: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ - self = + self = def test_global_func(self): > assert isinstance(globf(42), float) @@ -510,18 +510,18 @@ failure_demo.py:198: AssertionError _______________________ TestMoreErrors.test_instance _______________________ - self = + self = def test_instance(self): self.x = 6*7 > assert self.x != 42 E assert 42 != 42 - E + where 42 = .x + E + where 42 = .x failure_demo.py:202: AssertionError _______________________ TestMoreErrors.test_compare ________________________ - self = + self = def test_compare(self): > assert globf(10) < 5 @@ -531,7 +531,7 @@ failure_demo.py:205: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ - self = + self = def test_try_finally(self): x = 1 @@ -540,4 +540,4 @@ E assert 1 == 0 failure_demo.py:210: AssertionError - ======================== 39 failed in 0.21 seconds ========================= + ======================== 39 failed in 0.25 seconds ========================= diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -106,7 +106,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 0 items ============================= in 0.00 seconds ============================= @@ -150,12 +150,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-104/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-62/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -163,7 +163,7 @@ $ py.test --runslow =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_module.py .. @@ -253,7 +253,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 project deps: mylib-1.1 collected 0 items @@ -276,7 +276,7 @@ $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python info1: did you know that ... did you? collecting ... collected 0 items @@ -287,7 +287,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 0 items ============================= in 0.00 seconds ============================= @@ -319,7 +319,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 3 items test_some_are_slow.py ... @@ -380,7 +380,7 @@ $ py.test -rx =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items test_step.py .Fx. @@ -388,7 +388,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -398,7 +398,7 @@ ========================= short test summary info ========================== XFAIL test_step.py::TestUserHandling::()::test_deletion reason: previous test failed (test_modification) - ============== 1 failed, 2 passed, 1 xfailed in 0.01 seconds =============== + ============== 1 failed, 2 passed, 1 xfailed in 0.02 seconds =============== We'll see that ``test_deletion`` was not executed because ``test_modification`` failed. It is reported as an "expected failure". diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -71,7 +71,7 @@ $ py.test test_smtpsimple.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items test_smtpsimple.py F @@ -79,7 +79,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response, msg = smtp.ehlo() @@ -89,7 +89,7 @@ E assert 0 test_smtpsimple.py:12: AssertionError - ========================= 1 failed in 0.16 seconds ========================= + ========================= 1 failed in 0.30 seconds ========================= In the failure traceback we see that the test function was called with a ``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture @@ -189,7 +189,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_module.py FF @@ -197,7 +197,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -209,7 +209,7 @@ test_module.py:6: AssertionError ________________________________ test_noop _________________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -218,7 +218,7 @@ E assert 0 test_module.py:11: AssertionError - ========================= 2 failed in 0.17 seconds ========================= + ========================= 2 failed in 0.48 seconds ========================= You see the two ``assert 0`` failing and more importantly you can also see that the same (module-scoped) ``smtp`` object was passed into the two @@ -271,7 +271,7 @@ $ py.test -s -q --tb=no FF - finalizing + finalizing We see that the ``smtp`` instance is finalized after the two tests using it tests executed. If we had specified ``scope='function'`` @@ -342,7 +342,7 @@ ================================= FAILURES ================================= __________________________ test_ehlo[merlinux.eu] __________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -354,7 +354,7 @@ test_module.py:6: AssertionError __________________________ test_noop[merlinux.eu] __________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -365,7 +365,7 @@ test_module.py:11: AssertionError ________________________ test_ehlo[mail.python.org] ________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -376,7 +376,7 @@ test_module.py:5: AssertionError ________________________ test_noop[mail.python.org] ________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -424,13 +424,13 @@ $ py.test -v test_appsetup.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_appsetup.py:12: test_smtp_exists[merlinux.eu] PASSED test_appsetup.py:12: test_smtp_exists[mail.python.org] PASSED - ========================= 2 passed in 5.45 seconds ========================= + ========================= 2 passed in 6.79 seconds ========================= Due to the parametrization of ``smtp`` the test will run twice with two different ``App`` instances and respective smtp servers. There is no @@ -489,7 +489,7 @@ $ py.test -v -s test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 8 items test_module.py:16: test_0[1] PASSED diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/getting-started.txt --- a/doc/en/getting-started.txt +++ b/doc/en/getting-started.txt @@ -23,7 +23,7 @@ To check your installation has installed the correct version:: $ py.test --version - This is py.test version 2.3.2, imported from /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/pytest.pyc + This is py.test version 2.3.3, imported from /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/pytest.pyc If you get an error checkout :ref:`installation issues`. @@ -45,7 +45,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items test_sample.py F @@ -122,7 +122,7 @@ ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - self = + self = def test_two(self): x = "hello" @@ -157,7 +157,7 @@ ================================= FAILURES ================================= _____________________________ test_needsfiles ______________________________ - tmpdir = local('/tmp/pytest-917/test_needsfiles0') + tmpdir = local('/tmp/pytest-594/test_needsfiles0') def test_needsfiles(tmpdir): print tmpdir @@ -166,7 +166,7 @@ test_tmpdir.py:3: AssertionError ----------------------------- Captured stdout ------------------------------ - /tmp/pytest-917/test_needsfiles0 + /tmp/pytest-594/test_needsfiles0 Before the test runs, a unique-per-test-invocation temporary directory was created. More info at :ref:`tmpdir handling`. diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/parametrize.txt --- a/doc/en/parametrize.txt +++ b/doc/en/parametrize.txt @@ -53,7 +53,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 3 items test_expectation.py ..F @@ -135,8 +135,8 @@ def test_valid_string(stringinput): > assert stringinput.isalpha() - E assert () - E + where = '!'.isalpha + E assert () + E + where = '!'.isalpha test_strings.py:3: AssertionError @@ -149,7 +149,7 @@ $ py.test -q -rs test_strings.py s ========================= short test summary info ========================== - SKIP [1] /home/hpk/p/pytest/.tox/regen/local/lib/python2.7/site-packages/_pytest/python.py:960: got empty parameter set, function test_valid_string at /tmp/doc-exec-69/test_strings.py:1 + SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:960: got empty parameter set, function test_valid_string at /tmp/doc-exec-26/test_strings.py:1 For further examples, you might want to look at :ref:`more parametrization examples `. diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -132,7 +132,7 @@ example $ py.test -rx xfail_demo.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 6 items xfail_demo.py xxxxxx @@ -149,7 +149,7 @@ XFAIL xfail_demo.py::test_hello6 reason: reason - ======================== 6 xfailed in 0.04 seconds ========================= + ======================== 6 xfailed in 0.05 seconds ========================= .. _`evaluation of skipif/xfail conditions`: diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/tmpdir.txt --- a/doc/en/tmpdir.txt +++ b/doc/en/tmpdir.txt @@ -29,7 +29,7 @@ $ py.test test_tmpdir.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 1 items test_tmpdir.py F @@ -37,7 +37,7 @@ ================================= FAILURES ================================= _____________________________ test_create_file _____________________________ - tmpdir = local('/tmp/pytest-918/test_create_file0') + tmpdir = local('/tmp/pytest-595/test_create_file0') def test_create_file(tmpdir): p = tmpdir.mkdir("sub").join("hello.txt") @@ -48,7 +48,7 @@ E assert 0 test_tmpdir.py:7: AssertionError - ========================= 1 failed in 0.04 seconds ========================= + ========================= 1 failed in 0.03 seconds ========================= .. _`base temporary directory`: diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 doc/en/unittest.txt --- a/doc/en/unittest.txt +++ b/doc/en/unittest.txt @@ -88,7 +88,7 @@ $ py.test test_unittest_db.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.2 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_unittest_db.py FF @@ -101,7 +101,7 @@ def test_method1(self): assert hasattr(self, "db") > assert 0, self.db # fail for demo purposes - E AssertionError: + E AssertionError: test_unittest_db.py:9: AssertionError ___________________________ MyTest.test_method2 ____________________________ @@ -110,7 +110,7 @@ def test_method2(self): > assert 0, self.db # fail for demo purposes - E AssertionError: + E AssertionError: test_unittest_db.py:12: AssertionError ========================= 2 failed in 0.02 seconds ========================= diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 setup.py --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.3.dev5', + version='2.3.3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], @@ -33,7 +33,7 @@ entry_points= make_entry_points(), cmdclass = {'test': PyTest}, # the following should be enabled for release - install_requires=['py>=1.4.12.dev2'], + install_requires=['py>=1.4.12'], classifiers=['Development Status :: 6 - Mature', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', diff -r d12ea5ebf62b0b60a71ab1a3293e098cd8162023 -r 14583b72af1023ad058ad763ab9ceec3d0f12828 tox.ini --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ indexserver= pypi = http://pypi.python.org/simple testrun = http://pypi.testrun.org - default = http://pypi.testrun.org + #default = http://pypi.testrun.org [testenv] changedir=testing Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 15:03:28 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 14:03:28 -0000 Subject: [py-svn] commit/py: hpk42: Added tag 1.4.12 for changeset f07af25a2678 Message-ID: <20121106140328.19392.73629@bitbucket15.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/462a333b9d4b/ changeset: 462a333b9d4b user: hpk42 date: 2012-11-06 15:03:13 summary: Added tag 1.4.12 for changeset f07af25a2678 affected #: 1 file diff -r f07af25a26786e4825b5170e17ad693245cb3426 -r 462a333b9d4b64c28288bf1f18210750a58256b4 .hgtags --- a/.hgtags +++ b/.hgtags @@ -41,3 +41,4 @@ abfabd07a1d328f13c730e8a50d80d2e470afd3b 1.4.9 7f37ee0aff9be4b839d6759cfee336f60e8393a4 1.4.10 fe4593263efa10ea7ba014db6e3379e0b82368a2 1.4.11 +f07af25a26786e4825b5170e17ad693245cb3426 1.4.12 Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 15:39:03 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 14:39:03 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20121106143903.6778.92814@bitbucket23.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/7fe44182c434/ changeset: 7fe44182c434 user: hpk42 date: 2012-11-06 15:36:11 summary: fix py31 compat, amend setup.py long description affected #: 2 files diff -r 14583b72af1023ad058ad763ab9ceec3d0f12828 -r 7fe44182c434f8ac89149a3c340479872a5d5ccb _pytest/nose.py --- a/_pytest/nose.py +++ b/_pytest/nose.py @@ -41,7 +41,7 @@ def call_optional(obj, name): method = getattr(obj, name, None) - if method is not None and not hasattr(method, "_pytestfixturefunction") and callable(method): + if method is not None and not hasattr(method, "_pytestfixturefunction") and py.builtin.callable(method): # If there's any problems allow the exception to raise rather than # silently ignoring them method() diff -r 14583b72af1023ad058ad763ab9ceec3d0f12828 -r 7fe44182c434f8ac89149a3c340479872a5d5ccb setup.py --- a/setup.py +++ b/setup.py @@ -7,15 +7,39 @@ from setuptools import setup, Command long_description = """ -cross-project testing tool for Python. +The `py.test`` testing tool makes it easy to write small tests, yet +scales to support complex functional testing. It provides -Platforms: Linux, Win32, OSX +- `auto-discovery + `_ + of test modules and functions, +- detailed info on failing `assert statements `_ (no need to remember ``self.assert*`` names) +- `modular fixtures `_ for + managing small or parametrized long-lived test resources. +- multi-paradigm support: you can use ``py.test`` to run test suites based + on `unittest `_ (or trial), + `nose `_ +- single-source compatibility to Python2.4 all the way up to Python3.3, + PyPy and Jython. -Interpreters: Python versions 2.4 through to 3.3, Jython 2.5.1 and PyPy-1.9 +- many `external plugins `_. -Bugs and issues: http://bitbucket.org/hpk42/pytest/issues/ +A simple example for a test:: -Web page: http://pytest.org + # content of test_module.py + def test_function(): + i = 4 + assert i == 3 + +which can be run with ``py.test test_module.py``. See `getting-started `_ for more examples. + +For much more info, including PDF docs, see + + http://pytest.org + +and report bugs at: + + http://bitbucket.org/hpk42/pytest/issues/ (c) Holger Krekel and others, 2004-2012 """ https://bitbucket.org/hpk42/pytest/changeset/3a19b692db44/ changeset: 3a19b692db44 user: hpk42 date: 2012-11-06 15:38:49 summary: Added tag 2.3.3 for changeset 7fe44182c434 affected #: 1 file diff -r 7fe44182c434f8ac89149a3c340479872a5d5ccb -r 3a19b692db4484dfcdddba6d61615612afa58941 .hgtags --- a/.hgtags +++ b/.hgtags @@ -52,3 +52,4 @@ c27a60097767c16a54ae56d9669a77925b213b9b 2.3.0 acf0e1477fb19a1d35a4e40242b77fa6af32eb17 2.3.1 8738b828dec53937765db71951ef955cca4c51f6 2.3.2 +7fe44182c434f8ac89149a3c340479872a5d5ccb 2.3.3 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 15:44:00 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 14:44:00 -0000 Subject: [py-svn] commit/pytest: hpk42: add release announce for 2.3.3 Message-ID: <20121106144400.13296.40918@bitbucket24.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/dc50e8435687/ changeset: dc50e8435687 user: hpk42 date: 2012-11-06 15:41:51 summary: add release announce for 2.3.3 affected #: 1 file diff -r 3a19b692db4484dfcdddba6d61615612afa58941 -r dc50e84356877e67abfb145f423236ec872108f4 doc/en/announce/release-2.3.3.txt --- /dev/null +++ b/doc/en/announce/release-2.3.3.txt @@ -0,0 +1,62 @@ +pytest-2.3.3: integration fixes, py24 suport, ``*/**`` shown in traceback +=========================================================================== + +pytest-2.3.3 is a another stabilization release of the py.test tool +which offers uebersimple assertions, scalable fixture mechanisms +and deep customization for testing with Python. Particularly, +this release provides: + +- integration fixes and improvements related to flask, numpy, nose, + unittest, mock + +- makes pytest work on py24 again (yes, people sometimes still need to use it) + +- show *,** args in pytest tracebacks + +Thanks to Manuel Jacob, Thomas Waldmann, Ronny Pfannschmidt, Pavel Repin +and Andreas Taumoefolau for providing patches and all for the issues. + +See + + http://pytest.org/ + +for general information. To install or upgrade pytest: + + pip install -U pytest # or + easy_install -U pytest + +best, +holger krekel + +Changes between 2.3.2 and 2.3.3 +----------------------------------- + +- fix issue214 - parse modules that contain special objects like e. g. + flask's request object which blows up on getattr access if no request + is active. thanks Thomas Waldmann. + +- fix issue213 - allow to parametrize with values like numpy arrays that + do not support an __eq__ operator + +- fix issue215 - split test_python.org into multiple files + +- fix issue148 - @unittest.skip on classes is now recognized and avoids + calling setUpClass/tearDownClass, thanks Pavel Repin + +- fix issue209 - reintroduce python2.4 support by depending on newer + pylib which re-introduced statement-finding for pre-AST interpreters + +- nose support: only call setup if its a callable, thanks Andrew + Taumoefolau + +- fix issue219 - add py2.4-3.3 classifiers to TROVE list + +- in tracebacks *,** arg values are now shown next to normal arguments + (thanks Manuel Jacob) + +- fix issue217 - support mock.patch with pytest's fixtures - note that + you need either mock-1.0.1 or the python3.3 builtin unittest.mock. + +- fix issue127 - improve documentation for pytest_addoption() and + add a ``config.getoption(name)`` helper function for consistency. + Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 6 16:02:54 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 06 Nov 2012 15:02:54 -0000 Subject: [py-svn] commit/pytest-pep8: 2 new changesets Message-ID: <20121106150254.32723.86089@bitbucket22.managed.contegix.com> 2 new commits in pytest-pep8: https://bitbucket.org/hpk42/pytest-pep8/changeset/f8a92d028dcd/ changeset: f8a92d028dcd user: hpk42 date: 2012-11-06 16:01:44 summary: finalize affected #: 2 files diff -r 47c4298aedfd090458d914c80c35a6ad3dfce991 -r f8a92d028dcd09ecd737d46b62585ef89571aa4d pytest_pep8.py --- a/pytest_pep8.py +++ b/pytest_pep8.py @@ -3,7 +3,7 @@ import pytest import pep8 -__version__ = '1.0.3.dev1' +__version__ = '1.0.3' HISTKEY = "pep8/mtimes" diff -r 47c4298aedfd090458d914c80c35a6ad3dfce991 -r f8a92d028dcd09ecd737d46b62585ef89571aa4d setup.py --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ name='pytest-pep8', description='pytest plugin to check PEP8 requirements', long_description=open("README.txt").read(), - version='1.0.3.dev1', + version='1.0.3', author='Holger Krekel and Ronny Pfannschmidt', author_email='holger.krekel at gmail.com', url='http://bitbucket.org/hpk42/pytest-pep8/', https://bitbucket.org/hpk42/pytest-pep8/changeset/e7c446c82018/ changeset: e7c446c82018 user: hpk42 date: 2012-11-06 16:02:45 summary: Added tag 1.0.3 for changeset f8a92d028dcd affected #: 1 file diff -r f8a92d028dcd09ecd737d46b62585ef89571aa4d -r e7c446c820180183af8c9f5ecc54f4ee79e9a8a6 .hgtags --- a/.hgtags +++ b/.hgtags @@ -6,3 +6,4 @@ 1160e1328095d879238cdda32173476ecc5a5072 0.9.1 dc4ae3a75b4c285c81c7044232b0426a23c9a221 1.0.1 2e5abd094f9f1abe88d764f3070dbfdb0823213f 1.0.2 +f8a92d028dcd09ecd737d46b62585ef89571aa4d 1.0.3 Repository URL: https://bitbucket.org/hpk42/pytest-pep8/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Nov 7 10:05:50 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 07 Nov 2012 09:05:50 -0000 Subject: [py-svn] commit/pytest: 3 new changesets Message-ID: <20121107090550.12040.25178@bitbucket03.managed.contegix.com> 3 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/c12e50dc9e72/ changeset: c12e50dc9e72 user: hpk42 date: 2012-11-06 15:46:52 summary: fix typo affected #: 1 file diff -r dc50e84356877e67abfb145f423236ec872108f4 -r c12e50dc9e7267b68fd42999edfa9d8beaf6d148 doc/en/announce/release-2.3.3.txt --- a/doc/en/announce/release-2.3.3.txt +++ b/doc/en/announce/release-2.3.3.txt @@ -11,7 +11,7 @@ - makes pytest work on py24 again (yes, people sometimes still need to use it) -- show *,** args in pytest tracebacks +- show ``*,**`` args in pytest tracebacks Thanks to Manuel Jacob, Thomas Waldmann, Ronny Pfannschmidt, Pavel Repin and Andreas Taumoefolau for providing patches and all for the issues. https://bitbucket.org/hpk42/pytest/changeset/657bd61a148b/ changeset: 657bd61a148b user: hpk42 date: 2012-11-07 09:35:49 summary: mention that jython-2.5.1 works affected #: 1 file diff -r c12e50dc9e7267b68fd42999edfa9d8beaf6d148 -r 657bd61a148bb7d7dcd236e24139aa370452e1ac setup.py --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ on `unittest `_ (or trial), `nose `_ - single-source compatibility to Python2.4 all the way up to Python3.3, - PyPy and Jython. + PyPy-1.9 and Jython-2.5.1. - many `external plugins `_. https://bitbucket.org/hpk42/pytest/changeset/2737384b7149/ changeset: 2737384b7149 user: hpk42 date: 2012-11-07 10:05:39 summary: prolong workaround for jython AST bug http://bugs.jython.org/issue1497 to make pytest work for post-2.5.1 jython versions affected #: 3 files diff -r 657bd61a148bb7d7dcd236e24139aa370452e1ac -r 2737384b71498a53f1dde1e01de09921a58cfc5e _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.3' +__version__ = '2.3.4.dev1' diff -r 657bd61a148bb7d7dcd236e24139aa370452e1ac -r 2737384b71498a53f1dde1e01de09921a58cfc5e _pytest/assertion/newinterpret.py --- a/_pytest/assertion/newinterpret.py +++ b/_pytest/assertion/newinterpret.py @@ -11,7 +11,7 @@ from _pytest.assertion.reinterpret import BuiltinAssertionError -if sys.platform.startswith("java") and sys.version_info < (2, 5, 2): +if sys.platform.startswith("java"): # See http://bugs.jython.org/issue1497 _exprs = ("BoolOp", "BinOp", "UnaryOp", "Lambda", "IfExp", "Dict", "ListComp", "GeneratorExp", "Yield", "Compare", "Call", diff -r 657bd61a148bb7d7dcd236e24139aa370452e1ac -r 2737384b71498a53f1dde1e01de09921a58cfc5e setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.3', + version='2.3.4.dev1', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Nov 7 11:12:51 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 07 Nov 2012 10:12:51 -0000 Subject: [py-svn] commit/pytest: hpk42: - add a Package/dir level setup example Message-ID: <20121107101251.8257.61298@bitbucket23.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/81580e70517e/ changeset: 81580e70517e user: hpk42 date: 2012-11-07 11:11:40 summary: - add a Package/dir level setup example - make tox.ini's doc/regen use pytest release instead of dev version affected #: 15 files diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Changes between 2.3.3 and 2.3.4.dev +----------------------------------- + +- fix issue91 - add/discuss package/directory level setups in example + Changes between 2.3.2 and 2.3.3 ----------------------------------- diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/capture.txt --- a/doc/en/capture.txt +++ b/doc/en/capture.txt @@ -78,7 +78,7 @@ test_module.py:9: AssertionError ----------------------------- Captured stdout ------------------------------ - setting up + setting up ==================== 1 failed, 1 passed in 0.01 seconds ==================== Accessing captured output from a test function diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,7 +17,7 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = release = "2.3.3" +version = release = "2.3.3.1" import sys, os diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/doctest.txt --- a/doc/en/doctest.txt +++ b/doc/en/doctest.txt @@ -49,4 +49,4 @@ mymodule.py . - ========================= 1 passed in 0.02 seconds ========================= + ========================= 1 passed in 0.11 seconds ========================= diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -32,7 +32,7 @@ test_server.py:3: test_send_http PASSED =================== 1 tests deselected by "-m 'webtest'" =================== - ================== 1 passed, 1 deselected in 0.02 seconds ================== + ================== 1 passed, 1 deselected in 0.01 seconds ================== Or the inverse, running all tests except the webtest ones:: @@ -356,7 +356,7 @@ test_plat.py s.s. ========================= short test summary info ========================== - SKIP [2] /tmp/doc-exec-57/conftest.py:12: cannot run on platform linux2 + SKIP [2] /tmp/doc-exec-135/conftest.py:12: cannot run on platform linux2 =================== 2 passed, 2 skipped in 0.01 seconds ==================== diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/example/nonpython.txt --- a/doc/en/example/nonpython.txt +++ b/doc/en/example/nonpython.txt @@ -37,7 +37,7 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.04 seconds ==================== + ==================== 1 failed, 1 passed in 0.05 seconds ==================== You get one dot for the passing ``sub1: sub1`` check and one failure. Obviously in the above ``conftest.py`` you'll want to implement a more @@ -67,7 +67,7 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.04 seconds ==================== + ==================== 1 failed, 1 passed in 0.05 seconds ==================== While developing your custom test collection and execution it's also interesting to just look at the collection tree:: diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/example/parametrize.txt --- a/doc/en/example/parametrize.txt +++ b/doc/en/example/parametrize.txt @@ -195,7 +195,7 @@ ================================= FAILURES ================================= _________________________ test_db_initialized[d2] __________________________ - db = + db = def test_db_initialized(db): # a dummy test @@ -250,7 +250,7 @@ ================================= FAILURES ================================= ________________________ TestClass.test_equals[1-2] ________________________ - self = , a = 1, b = 2 + self = , a = 1, b = 2 def test_equals(self, a, b): > assert a == b diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/example/reportingdemo.txt --- a/doc/en/example/reportingdemo.txt +++ b/doc/en/example/reportingdemo.txt @@ -30,7 +30,7 @@ failure_demo.py:15: AssertionError _________________________ TestFailing.test_simple __________________________ - self = + self = def test_simple(self): def f(): @@ -40,13 +40,13 @@ > assert f() == g() E assert 42 == 43 - E + where 42 = () - E + and 43 = () + E + where 42 = () + E + and 43 = () failure_demo.py:28: AssertionError ____________________ TestFailing.test_simple_multiline _____________________ - self = + self = def test_simple_multiline(self): otherfunc_multi( @@ -66,19 +66,19 @@ failure_demo.py:11: AssertionError ___________________________ TestFailing.test_not ___________________________ - self = + self = def test_not(self): def f(): return 42 > assert not f() E assert not 42 - E + where 42 = () + E + where 42 = () failure_demo.py:38: AssertionError _________________ TestSpecialisedExplanations.test_eq_text _________________ - self = + self = def test_eq_text(self): > assert 'spam' == 'eggs' @@ -89,7 +89,7 @@ failure_demo.py:42: AssertionError _____________ TestSpecialisedExplanations.test_eq_similar_text _____________ - self = + self = def test_eq_similar_text(self): > assert 'foo 1 bar' == 'foo 2 bar' @@ -102,7 +102,7 @@ failure_demo.py:45: AssertionError ____________ TestSpecialisedExplanations.test_eq_multiline_text ____________ - self = + self = def test_eq_multiline_text(self): > assert 'foo\nspam\nbar' == 'foo\neggs\nbar' @@ -115,7 +115,7 @@ failure_demo.py:48: AssertionError ______________ TestSpecialisedExplanations.test_eq_long_text _______________ - self = + self = def test_eq_long_text(self): a = '1'*100 + 'a' + '2'*100 @@ -132,7 +132,7 @@ failure_demo.py:53: AssertionError _________ TestSpecialisedExplanations.test_eq_long_text_multiline __________ - self = + self = def test_eq_long_text_multiline(self): a = '1\n'*100 + 'a' + '2\n'*100 @@ -156,7 +156,7 @@ failure_demo.py:58: AssertionError _________________ TestSpecialisedExplanations.test_eq_list _________________ - self = + self = def test_eq_list(self): > assert [0, 1, 2] == [0, 1, 3] @@ -166,7 +166,7 @@ failure_demo.py:61: AssertionError ______________ TestSpecialisedExplanations.test_eq_list_long _______________ - self = + self = def test_eq_list_long(self): a = [0]*100 + [1] + [3]*100 @@ -178,7 +178,7 @@ failure_demo.py:66: AssertionError _________________ TestSpecialisedExplanations.test_eq_dict _________________ - self = + self = def test_eq_dict(self): > assert {'a': 0, 'b': 1} == {'a': 0, 'b': 2} @@ -191,7 +191,7 @@ failure_demo.py:69: AssertionError _________________ TestSpecialisedExplanations.test_eq_set __________________ - self = + self = def test_eq_set(self): > assert set([0, 10, 11, 12]) == set([0, 20, 21]) @@ -207,7 +207,7 @@ failure_demo.py:72: AssertionError _____________ TestSpecialisedExplanations.test_eq_longer_list ______________ - self = + self = def test_eq_longer_list(self): > assert [1,2] == [1,2,3] @@ -217,7 +217,7 @@ failure_demo.py:75: AssertionError _________________ TestSpecialisedExplanations.test_in_list _________________ - self = + self = def test_in_list(self): > assert 1 in [0, 2, 3, 4, 5] @@ -226,7 +226,7 @@ failure_demo.py:78: AssertionError __________ TestSpecialisedExplanations.test_not_in_text_multiline __________ - self = + self = def test_not_in_text_multiline(self): text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail' @@ -244,7 +244,7 @@ failure_demo.py:82: AssertionError ___________ TestSpecialisedExplanations.test_not_in_text_single ____________ - self = + self = def test_not_in_text_single(self): text = 'single foo line' @@ -257,7 +257,7 @@ failure_demo.py:86: AssertionError _________ TestSpecialisedExplanations.test_not_in_text_single_long _________ - self = + self = def test_not_in_text_single_long(self): text = 'head ' * 50 + 'foo ' + 'tail ' * 20 @@ -270,7 +270,7 @@ failure_demo.py:90: AssertionError ______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______ - self = + self = def test_not_in_text_single_long_term(self): text = 'head ' * 50 + 'f'*70 + 'tail ' * 20 @@ -289,7 +289,7 @@ i = Foo() > assert i.b == 2 E assert 1 == 2 - E + where 1 = .b + E + where 1 = .b failure_demo.py:101: AssertionError _________________________ test_attribute_instance __________________________ @@ -299,8 +299,8 @@ b = 1 > assert Foo().b == 2 E assert 1 == 2 - E + where 1 = .b - E + where = () + E + where 1 = .b + E + where = () failure_demo.py:107: AssertionError __________________________ test_attribute_failure __________________________ @@ -316,7 +316,7 @@ failure_demo.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - self = + self = def _get_b(self): > raise Exception('Failed to get attrib') @@ -332,15 +332,15 @@ b = 2 > assert Foo().b == Bar().b E assert 1 == 2 - E + where 1 = .b - E + where = () - E + and 2 = .b - E + where = () + E + where 1 = .b + E + where = () + E + and 2 = .b + E + where = () failure_demo.py:124: AssertionError __________________________ TestRaises.test_raises __________________________ - self = + self = def test_raises(self): s = 'qwe' @@ -355,7 +355,7 @@ <0-codegen /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:851>:1: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ - self = + self = def test_raises_doesnt(self): > raises(IOError, "int('3')") @@ -364,7 +364,7 @@ failure_demo.py:136: Failed __________________________ TestRaises.test_raise ___________________________ - self = + self = def test_raise(self): > raise ValueError("demo error") @@ -373,7 +373,7 @@ failure_demo.py:139: ValueError ________________________ TestRaises.test_tupleerror ________________________ - self = + self = def test_tupleerror(self): > a,b = [1] @@ -382,7 +382,7 @@ failure_demo.py:142: ValueError ______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______ - self = + self = def test_reinterpret_fails_with_print_for_the_fun_of_it(self): l = [1,2,3] @@ -395,7 +395,7 @@ l is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ - self = + self = def test_some_error(self): > if namenotexi: @@ -423,7 +423,7 @@ <2-codegen 'abc-123' /home/hpk/p/pytest/doc/en/example/assertion/failure_demo.py:162>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ - self = + self = def test_complex_error(self): def f(): @@ -452,7 +452,7 @@ failure_demo.py:5: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ - self = + self = def test_z1_unpack_error(self): l = [] @@ -462,7 +462,7 @@ failure_demo.py:179: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ - self = + self = def test_z2_type_error(self): l = 3 @@ -472,19 +472,19 @@ failure_demo.py:183: TypeError ______________________ TestMoreErrors.test_startswith ______________________ - self = + self = def test_startswith(self): s = "123" g = "456" > assert s.startswith(g) - E assert ('456') - E + where = '123'.startswith + E assert ('456') + E + where = '123'.startswith failure_demo.py:188: AssertionError __________________ TestMoreErrors.test_startswith_nested ___________________ - self = + self = def test_startswith_nested(self): def f(): @@ -492,15 +492,15 @@ def g(): return "456" > assert f().startswith(g()) - E assert ('456') - E + where = '123'.startswith - E + where '123' = () - E + and '456' = () + E assert ('456') + E + where = '123'.startswith + E + where '123' = () + E + and '456' = () failure_demo.py:195: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ - self = + self = def test_global_func(self): > assert isinstance(globf(42), float) @@ -510,18 +510,18 @@ failure_demo.py:198: AssertionError _______________________ TestMoreErrors.test_instance _______________________ - self = + self = def test_instance(self): self.x = 6*7 > assert self.x != 42 E assert 42 != 42 - E + where 42 = .x + E + where 42 = .x failure_demo.py:202: AssertionError _______________________ TestMoreErrors.test_compare ________________________ - self = + self = def test_compare(self): > assert globf(10) < 5 @@ -531,7 +531,7 @@ failure_demo.py:205: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ - self = + self = def test_try_finally(self): x = 1 @@ -540,4 +540,4 @@ E assert 1 == 0 failure_demo.py:210: AssertionError - ======================== 39 failed in 0.25 seconds ========================= + ======================== 39 failed in 0.23 seconds ========================= diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -155,7 +155,7 @@ test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-62/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-140/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -388,7 +388,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -403,3 +403,95 @@ We'll see that ``test_deletion`` was not executed because ``test_modification`` failed. It is reported as an "expected failure". + +Package/Directory-level fixtures (setups) +------------------------------------------------------- + +If you have nested test directories, you can have per-directory fixture scopes +by placing fixture functions in a ``conftest.py`` file in that directory +You can use all types of fixtures including :ref:`autouse fixtures +` which are the equivalent of xUnit's setup/teardown +concept. It's however recommended to have explicit fixture references in your +tests or test classes rather than relying on implicitely executing +setup/teardown functions, especially if they are far away from the actual tests. + +Here is a an example for making a ``db`` fixture available in a directory:: + + # content of a/conftest.py + import pytest + + class DB: + pass + + @pytest.fixture(scope="session") + def db(): + return DB() + +and then a test module in that directory:: + + # content of a/test_db.py + def test_a1(db): + assert 0, db # to show value + +another test module:: + + # content of a/test_db2.py + def test_a2(db): + assert 0, db # to show value + +and then a module in a sister directory which will not see +the ``db`` fixture:: + + # content of b/test_error.py + def test_root(db): # no db here, will error out + pass + +We can run this:: + + $ py.test + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + collected 3 items + + a/test_db.py F + a/test_db2.py F + b/test_error.py E + + ================================== ERRORS ================================== + _______________________ ERROR at setup of test_root ________________________ + file /tmp/doc-exec-133/b/test_error.py, line 1 + def test_root(db): # no db here, will error out + fixture 'db' not found + available fixtures: pytestconfig, recwarn, monkeypatch, capfd, capsys, tmpdir + use 'py.test --fixtures [testpath]' for help on them. + + /tmp/doc-exec-133/b/test_error.py:1 + ================================= FAILURES ================================= + _________________________________ test_a1 __________________________________ + + db = + + def test_a1(db): + > assert 0, db # to show value + E AssertionError: + + a/test_db.py:2: AssertionError + _________________________________ test_a2 __________________________________ + + db = + + def test_a2(db): + > assert 0, db # to show value + E AssertionError: + + a/test_db2.py:2: AssertionError + ==================== 2 failed, 1 error in 0.02 seconds ===================== + +The two test modules in the ``a`` directory see the same ``db`` fixture instance +while the one test in the sister-directory ``b`` doesn't see it. We could of course +also define a ``db`` fixture in that sister directory's ``conftest.py`` file. +Note that each fixture is only instantiated if there is a test actually needing +it (unless you use "autouse" fixture which are always executed ahead of the first test +executing). + + diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -79,7 +79,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response, msg = smtp.ehlo() @@ -89,7 +89,7 @@ E assert 0 test_smtpsimple.py:12: AssertionError - ========================= 1 failed in 0.30 seconds ========================= + ========================= 1 failed in 0.26 seconds ========================= In the failure traceback we see that the test function was called with a ``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture @@ -197,7 +197,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -209,7 +209,7 @@ test_module.py:6: AssertionError ________________________________ test_noop _________________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -218,7 +218,7 @@ E assert 0 test_module.py:11: AssertionError - ========================= 2 failed in 0.48 seconds ========================= + ========================= 2 failed in 0.22 seconds ========================= You see the two ``assert 0`` failing and more importantly you can also see that the same (module-scoped) ``smtp`` object was passed into the two @@ -271,7 +271,7 @@ $ py.test -s -q --tb=no FF - finalizing + finalizing We see that the ``smtp`` instance is finalized after the two tests using it tests executed. If we had specified ``scope='function'`` @@ -342,7 +342,7 @@ ================================= FAILURES ================================= __________________________ test_ehlo[merlinux.eu] __________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -354,7 +354,7 @@ test_module.py:6: AssertionError __________________________ test_noop[merlinux.eu] __________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -365,7 +365,7 @@ test_module.py:11: AssertionError ________________________ test_ehlo[mail.python.org] ________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -376,7 +376,7 @@ test_module.py:5: AssertionError ________________________ test_noop[mail.python.org] ________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -430,7 +430,7 @@ test_appsetup.py:12: test_smtp_exists[merlinux.eu] PASSED test_appsetup.py:12: test_smtp_exists[mail.python.org] PASSED - ========================= 2 passed in 6.79 seconds ========================= + ========================= 2 passed in 6.43 seconds ========================= Due to the parametrization of ``smtp`` the test will run twice with two different ``App`` instances and respective smtp servers. There is no diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/getting-started.txt --- a/doc/en/getting-started.txt +++ b/doc/en/getting-started.txt @@ -122,7 +122,7 @@ ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - self = + self = def test_two(self): x = "hello" @@ -157,7 +157,7 @@ ================================= FAILURES ================================= _____________________________ test_needsfiles ______________________________ - tmpdir = local('/tmp/pytest-594/test_needsfiles0') + tmpdir = local('/tmp/pytest-780/test_needsfiles0') def test_needsfiles(tmpdir): print tmpdir @@ -166,7 +166,7 @@ test_tmpdir.py:3: AssertionError ----------------------------- Captured stdout ------------------------------ - /tmp/pytest-594/test_needsfiles0 + /tmp/pytest-780/test_needsfiles0 Before the test runs, a unique-per-test-invocation temporary directory was created. More info at :ref:`tmpdir handling`. diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/parametrize.txt --- a/doc/en/parametrize.txt +++ b/doc/en/parametrize.txt @@ -135,8 +135,8 @@ def test_valid_string(stringinput): > assert stringinput.isalpha() - E assert () - E + where = '!'.isalpha + E assert () + E + where = '!'.isalpha test_strings.py:3: AssertionError @@ -149,7 +149,7 @@ $ py.test -q -rs test_strings.py s ========================= short test summary info ========================== - SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:960: got empty parameter set, function test_valid_string at /tmp/doc-exec-26/test_strings.py:1 + SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:960: got empty parameter set, function test_valid_string at /tmp/doc-exec-103/test_strings.py:1 For further examples, you might want to look at :ref:`more parametrization examples `. diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/tmpdir.txt --- a/doc/en/tmpdir.txt +++ b/doc/en/tmpdir.txt @@ -37,7 +37,7 @@ ================================= FAILURES ================================= _____________________________ test_create_file _____________________________ - tmpdir = local('/tmp/pytest-595/test_create_file0') + tmpdir = local('/tmp/pytest-781/test_create_file0') def test_create_file(tmpdir): p = tmpdir.mkdir("sub").join("hello.txt") @@ -48,7 +48,7 @@ E assert 0 test_tmpdir.py:7: AssertionError - ========================= 1 failed in 0.03 seconds ========================= + ========================= 1 failed in 0.04 seconds ========================= .. _`base temporary directory`: diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 doc/en/unittest.txt --- a/doc/en/unittest.txt +++ b/doc/en/unittest.txt @@ -101,7 +101,7 @@ def test_method1(self): assert hasattr(self, "db") > assert 0, self.db # fail for demo purposes - E AssertionError: + E AssertionError: test_unittest_db.py:9: AssertionError ___________________________ MyTest.test_method2 ____________________________ @@ -110,7 +110,7 @@ def test_method2(self): > assert 0, self.db # fail for demo purposes - E AssertionError: + E AssertionError: test_unittest_db.py:12: AssertionError ========================= 2 failed in 0.02 seconds ========================= diff -r 2737384b71498a53f1dde1e01de09921a58cfc5e -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 tox.ini --- a/tox.ini +++ b/tox.ini @@ -68,6 +68,7 @@ :pypi:PyYAML commands= rm -rf /tmp/doc-exec* + pip install pytest==2.3.3 make regen [testenv:py31] Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Nov 8 19:05:54 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 08 Nov 2012 18:05:54 -0000 Subject: [py-svn] commit/pytest: hpk42: fix misleading typo Message-ID: <20121108180554.21419.84254@bitbucket24.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/e465c4eeaa2b/ changeset: e465c4eeaa2b user: hpk42 date: 2012-11-08 19:05:46 summary: fix misleading typo affected #: 2 files diff -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 -r e465c4eeaa2bd7b5bbbd9dd0e1aa3153dfab4b2b doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,7 +17,7 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = release = "2.3.3.1" +version = release = "2.3.3.2" import sys, os diff -r 81580e70517e2af175a3848c8a5a2b4ed2dc7770 -r e465c4eeaa2bd7b5bbbd9dd0e1aa3153dfab4b2b doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -168,7 +168,7 @@ return smtplib.SMTP("merlinux.eu") The name of the fixture again is ``smtp`` and you can access its result by -listing the name ``smtp`` as an input parameter in any test or setup +listing the name ``smtp`` as an input parameter in any test or fixture function (in or below the directory where ``conftest.py`` is located):: # content of test_module.py Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Nov 8 23:36:58 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 08 Nov 2012 22:36:58 -0000 Subject: [py-svn] commit/pytest: hpk42: add an example for postprocessing a test failure Message-ID: <20121108223658.20018.33142@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/c6085e0c39c2/ changeset: c6085e0c39c2 user: hpk42 date: 2012-11-08 23:36:16 summary: add an example for postprocessing a test failure affected #: 2 files diff -r e465c4eeaa2bd7b5bbbd9dd0e1aa3153dfab4b2b -r c6085e0c39c2182f2663e7e969849a279523c1ac doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,7 +17,7 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = release = "2.3.3.2" +version = release = "2.3.3.3" import sys, os diff -r e465c4eeaa2bd7b5bbbd9dd0e1aa3153dfab4b2b -r c6085e0c39c2182f2663e7e969849a279523c1ac doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -106,7 +106,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 collected 0 items ============================= in 0.00 seconds ============================= @@ -150,12 +150,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-140/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-156/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -163,7 +163,7 @@ $ py.test --runslow =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 collected 2 items test_module.py .. @@ -253,7 +253,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 project deps: mylib-1.1 collected 0 items @@ -276,7 +276,7 @@ $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 -- /home/hpk/venv/0/bin/python info1: did you know that ... did you? collecting ... collected 0 items @@ -287,7 +287,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 collected 0 items ============================= in 0.00 seconds ============================= @@ -319,7 +319,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 collected 3 items test_some_are_slow.py ... @@ -380,7 +380,7 @@ $ py.test -rx =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 collected 4 items test_step.py .Fx. @@ -388,7 +388,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -398,7 +398,7 @@ ========================= short test summary info ========================== XFAIL test_step.py::TestUserHandling::()::test_deletion reason: previous test failed (test_modification) - ============== 1 failed, 2 passed, 1 xfailed in 0.02 seconds =============== + ============== 1 failed, 2 passed, 1 xfailed in 0.01 seconds =============== We'll see that ``test_deletion`` was not executed because ``test_modification`` failed. It is reported as an "expected failure". @@ -450,42 +450,52 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 - collected 3 items + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + collected 7 items + test_step.py .Fx. a/test_db.py F a/test_db2.py F b/test_error.py E ================================== ERRORS ================================== _______________________ ERROR at setup of test_root ________________________ - file /tmp/doc-exec-133/b/test_error.py, line 1 + file /tmp/doc-exec-156/b/test_error.py, line 1 def test_root(db): # no db here, will error out fixture 'db' not found available fixtures: pytestconfig, recwarn, monkeypatch, capfd, capsys, tmpdir use 'py.test --fixtures [testpath]' for help on them. - /tmp/doc-exec-133/b/test_error.py:1 + /tmp/doc-exec-156/b/test_error.py:1 ================================= FAILURES ================================= + ____________________ TestUserHandling.test_modification ____________________ + + self = + + def test_modification(self): + > assert 0 + E assert 0 + + test_step.py:9: AssertionError _________________________________ test_a1 __________________________________ - db = + db = def test_a1(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db.py:2: AssertionError _________________________________ test_a2 __________________________________ - db = + db = def test_a2(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db2.py:2: AssertionError - ==================== 2 failed, 1 error in 0.02 seconds ===================== + ========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.03 seconds ========== The two test modules in the ``a`` directory see the same ``db`` fixture instance while the one test in the sister-directory ``b`` doesn't see it. We could of course @@ -495,3 +505,77 @@ executing). +post-process test reports / failures +--------------------------------------- + +If you want to postprocess test reports and need access to the executing +environment you can implement a hook that gets called when the test +"report" object is about to be created. Here we write out all failing +test calls and also access a fixture (if it was used by the test) in +case you want to query/look at it during your post processing. In our +case we just write some informations out to a ``failures`` file:: + + # content of conftest.py + + import pytest + import os.path + + @pytest.mark.tryfirst + def pytest_runtest_makereport(item, call, __multicall__): + # execute all other hooks to obtain the report object + rep = __multicall__.execute() + + # we only look at actual failing test calls, not setup/teardown + if rep.when == "call" and rep.failed: + mode = "a" if os.path.exists("failures") else "w" + with open("failures", mode) as f: + # let's also access a fixture for the fun of it + if "tmpdir" in item.funcargs: + extra = " (%s)" % item.funcargs["tmpdir"] + else: + extra = "" + + f.write(rep.nodeid + extra + "\n") + return rep + +if you then have failing tests:: + + # content of test_module.py + def test_fail1(tmpdir): + assert 0 + def test_fail2(): + assert 0 + +and run them:: + + $ py.test test_module.py + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + collected 2 items + + test_module.py FF + + ================================= FAILURES ================================= + ________________________________ test_fail1 ________________________________ + + tmpdir = local('/tmp/pytest-3/test_fail10') + + def test_fail1(tmpdir): + > assert 0 + E assert 0 + + test_module.py:2: AssertionError + ________________________________ test_fail2 ________________________________ + + def test_fail2(): + > assert 0 + E assert 0 + + test_module.py:4: AssertionError + ========================= 2 failed in 0.01 seconds ========================= + +you will have a "failures" file which contains the failing test ids:: + + $ cat failures + test_module.py::test_fail1 (/tmp/pytest-3/test_fail10) + test_module.py::test_fail2 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Nov 9 12:30:01 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 09 Nov 2012 11:30:01 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20121109113001.15431.36024@bitbucket24.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/4e85705ea0dc/ changeset: 4e85705ea0dc user: hpk42 date: 2012-11-09 12:07:41 summary: allow to dynamically define markers (e.g. during pytest_collection_modifyitems) affected #: 5 files diff -r c6085e0c39c2182f2663e7e969849a279523c1ac -r 4e85705ea0dc4233542fef7f819b315e2376a99d CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,8 @@ ----------------------------------- - fix issue91 - add/discuss package/directory level setups in example +- allow to dynamically define markers/keywords via + item.keywords[...]=assignment Changes between 2.3.2 and 2.3.3 ----------------------------------- diff -r c6085e0c39c2182f2663e7e969849a279523c1ac -r 4e85705ea0dc4233542fef7f819b315e2376a99d _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.4.dev1' +__version__ = '2.3.4.dev2' diff -r c6085e0c39c2182f2663e7e969849a279523c1ac -r 4e85705ea0dc4233542fef7f819b315e2376a99d _pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -73,7 +73,7 @@ return name in self._mydict def matchmark(colitem, matchexpr): - return eval(matchexpr, {}, BoolDict(colitem.obj.__dict__)) + return eval(matchexpr, {}, BoolDict(colitem.keywords)) def pytest_configure(config): if config.option.strict: diff -r c6085e0c39c2182f2663e7e969849a279523c1ac -r 4e85705ea0dc4233542fef7f819b315e2376a99d setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.4.dev1', + version='2.3.4.dev2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r c6085e0c39c2182f2663e7e969849a279523c1ac -r 4e85705ea0dc4233542fef7f819b315e2376a99d testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -137,6 +137,30 @@ assert len(passed) == len(passed_result) assert list(passed) == list(passed_result) + at pytest.mark.multi(spec=[ + ("interface", ("test_interface",)), + ("not interface", ("test_nointer",)), +]) +def test_mark_option_custom(spec, testdir): + testdir.makeconftest(""" + import pytest + def pytest_collection_modifyitems(items): + for item in items: + if "interface" in item.nodeid: + item.keywords["interface"] = pytest.mark.interface + """) + testdir.makepyfile(""" + def test_interface(): + pass + def test_nointer(): + pass + """) + opt, passed_result = spec + rec = testdir.inline_run("-m", opt) + passed, skipped, fail = rec.listoutcomes() + passed = [x.nodeid.split("::")[-1] for x in passed] + assert len(passed) == len(passed_result) + assert list(passed) == list(passed_result) class TestFunctional: @@ -386,7 +410,6 @@ item = dlist[0].items[0] assert item.name == "test_one" - def test_keyword_extra(self, testdir): p = testdir.makepyfile(""" def test_one(): https://bitbucket.org/hpk42/pytest/changeset/d16cc2de7a1f/ changeset: d16cc2de7a1f user: hpk42 date: 2012-11-09 12:29:33 summary: allow to pass expressions to "-k" option, just like with the "-m" option affected #: 5 files diff -r 4e85705ea0dc4233542fef7f819b315e2376a99d -r d16cc2de7a1fc2363a4abfd4cf46a141227eb5f3 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -2,8 +2,13 @@ ----------------------------------- - fix issue91 - add/discuss package/directory level setups in example -- allow to dynamically define markers/keywords via - item.keywords[...]=assignment +- allow to dynamically define markers via + item.keywords[...]=assignment integrating with "-m" option +- make "-k" accept an expressions the same as with "-m" so that one + can write: -k "name1 or name2" etc. This is a slight incompatibility + if you used special syntax like "TestClass.test_method" which you now + need to write as -k "TestClass and test_method" to match a certain + method in a certain test class. Changes between 2.3.2 and 2.3.3 ----------------------------------- diff -r 4e85705ea0dc4233542fef7f819b315e2376a99d -r d16cc2de7a1fc2363a4abfd4cf46a141227eb5f3 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.4.dev2' +__version__ = '2.3.4.dev3' diff -r 4e85705ea0dc4233542fef7f819b315e2376a99d -r d16cc2de7a1fc2363a4abfd4cf46a141227eb5f3 _pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -51,7 +51,7 @@ remaining = [] deselected = [] for colitem in items: - if keywordexpr and skipbykeyword(colitem, keywordexpr): + if keywordexpr and not matchkeyword(colitem, keywordexpr): deselected.append(colitem) else: if selectuntil: @@ -72,37 +72,26 @@ def __getitem__(self, name): return name in self._mydict +class SubstringDict: + def __init__(self, mydict): + self._mydict = mydict + def __getitem__(self, name): + for key in self._mydict: + if name in key: + return True + return False + def matchmark(colitem, matchexpr): return eval(matchexpr, {}, BoolDict(colitem.keywords)) +def matchkeyword(colitem, keywordexpr): + keywordexpr = keywordexpr.replace("-", "not ") + return eval(keywordexpr, {}, SubstringDict(colitem.keywords)) + def pytest_configure(config): if config.option.strict: pytest.mark._config = config -def skipbykeyword(colitem, keywordexpr): - """ return True if they given keyword expression means to - skip this collector/item. - """ - if not keywordexpr: - return - - itemkeywords = colitem.keywords - for key in filter(None, keywordexpr.split()): - eor = key[:1] == '-' - if eor: - key = key[1:] - if not (eor ^ matchonekeyword(key, itemkeywords)): - return True - -def matchonekeyword(key, itemkeywords): - for elem in key.split("."): - for kw in itemkeywords: - if elem in kw: - break - else: - return False - return True - class MarkGenerator: """ Factory for :class:`MarkDecorator` objects - exposed as a ``py.test.mark`` singleton instance. Example:: diff -r 4e85705ea0dc4233542fef7f819b315e2376a99d -r d16cc2de7a1fc2363a4abfd4cf46a141227eb5f3 setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.4.dev2', + version='2.3.4.dev3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 4e85705ea0dc4233542fef7f819b315e2376a99d -r d16cc2de7a1fc2363a4abfd4cf46a141227eb5f3 testing/test_mark.py --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -162,6 +162,24 @@ assert len(passed) == len(passed_result) assert list(passed) == list(passed_result) + at pytest.mark.multi(spec=[ + ("interface", ("test_interface",)), + ("not interface", ("test_nointer",)), +]) +def test_keyword_option_custom(spec, testdir): + testdir.makepyfile(""" + def test_interface(): + pass + def test_nointer(): + pass + """) + opt, passed_result = spec + rec = testdir.inline_run("-k", opt) + passed, skipped, fail = rec.listoutcomes() + passed = [x.nodeid.split("::")[-1] for x in passed] + assert len(passed) == len(passed_result) + assert list(passed) == list(passed_result) + class TestFunctional: def test_mark_per_function(self, testdir): @@ -366,11 +384,11 @@ for keyword in ['test_one', 'est_on']: #yield check, keyword, 'test_one' check(keyword, 'test_one') - check('TestClass.test', 'test_method_one') + check('TestClass and test', 'test_method_one') @pytest.mark.parametrize("keyword", [ - 'xxx', 'xxx test_2', 'TestClass', 'xxx -test_1', - 'TestClass test_2', 'xxx TestClass test_2']) + 'xxx', 'xxx and test_2', 'TestClass', 'xxx and -test_1', + 'TestClass and test_2', 'xxx and TestClass and test_2']) def test_select_extra_keywords(self, testdir, keyword): p = testdir.makepyfile(test_select=""" def test_1(): Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Nov 9 12:44:54 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 09 Nov 2012 11:44:54 -0000 Subject: [py-svn] commit/pytest: hpk42: switch to pushing docs to dev, amend markers example which needs the dev candidate Message-ID: <20121109114454.26927.76856@bitbucket13.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/e853a8edbbbf/ changeset: e853a8edbbbf user: hpk42 date: 2012-11-09 12:40:48 summary: switch to pushing docs to dev, amend markers example which needs the dev candidate affected #: 2 files diff -r d16cc2de7a1fc2363a4abfd4cf46a141227eb5f3 -r e853a8edbbbfd2563f301926352a9cd571225e41 doc/en/Makefile --- a/doc/en/Makefile +++ b/doc/en/Makefile @@ -12,7 +12,7 @@ PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -SITETARGET=latest +SITETARGET=dev .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest diff -r d16cc2de7a1fc2363a4abfd4cf46a141227eb5f3 -r e853a8edbbbfd2563f301926352a9cd571225e41 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -19,6 +19,8 @@ pass # perform some webtest test for your app def test_something_quick(): pass + def test_another(): + pass .. versionadded:: 2.2 @@ -26,25 +28,82 @@ $ py.test -v -m webtest =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python - collecting ... collected 2 items + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python + cachedir: /tmp/doc-exec-196/.cache + plugins: pep8, cache, xdist + collecting ... collected 3 items test_server.py:3: test_send_http PASSED - =================== 1 tests deselected by "-m 'webtest'" =================== - ================== 1 passed, 1 deselected in 0.01 seconds ================== + =================== 2 tests deselected by "-m 'webtest'" =================== + ================== 1 passed, 2 deselected in 0.01 seconds ================== Or the inverse, running all tests except the webtest ones:: $ py.test -v -m "not webtest" =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python - collecting ... collected 2 items + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python + cachedir: /tmp/doc-exec-196/.cache + plugins: pep8, cache, xdist + collecting ... collected 3 items test_server.py:6: test_something_quick PASSED + test_server.py:8: test_another PASSED ================= 1 tests deselected by "-m 'not webtest'" ================= - ================== 1 passed, 1 deselected in 0.01 seconds ================== + ================== 2 passed, 1 deselected in 0.02 seconds ================== + +Using ``-k expr`` to select tests based on their name +------------------------------------------------------- + +.. versionadded: 2.0/2.3.4 + +You can use the ``-k`` command line option to specify an expression +which implements a substring match on the test names instead of the +exact match on markers that ``-m`` provides. This makes it easy to +select tests based on their names:: + + $ py.test -v -k http # running with the above defined example module + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python + cachedir: /tmp/doc-exec-196/.cache + plugins: pep8, cache, xdist + collecting ... collected 3 items + + test_server.py:3: test_send_http PASSED + + =================== 2 tests deselected by '-ksend_http' ==================== + ================== 1 passed, 2 deselected in 0.01 seconds ================== + +And you can also run all tests except the ones that match the keyword:: + + $ py.test -k "not send_http" -v + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python + cachedir: /tmp/doc-exec-196/.cache + plugins: pep8, cache, xdist + collecting ... collected 3 items + + test_server.py:6: test_something_quick PASSED + test_server.py:8: test_another PASSED + + ================= 1 tests deselected by '-knot send_http' ================== + ================== 2 passed, 1 deselected in 0.01 seconds ================== + +Or to select "http" and "quick" tests:: + + $ py.test -k "http or quick" -v + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python + cachedir: /tmp/doc-exec-196/.cache + plugins: pep8, cache, xdist + collecting ... collected 3 items + + test_server.py:3: test_send_http PASSED + test_server.py:6: test_something_quick PASSED + + ================= 1 tests deselected by '-khttp or quick' ================== + ================== 2 passed, 1 deselected in 0.01 seconds ================== Registering markers ------------------------------------- @@ -137,46 +196,6 @@ methods defined in the module. -Using ``-k TEXT`` to select tests ----------------------------------------------------- - -You can use the ``-k`` command line option to only run tests with names matching -the given argument:: - - $ py.test -k send_http # running with the above defined examples - =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 - collected 4 items - - test_server.py . - - =================== 3 tests deselected by '-ksend_http' ==================== - ================== 1 passed, 3 deselected in 0.01 seconds ================== - -And you can also run all tests except the ones that match the keyword:: - - $ py.test -k-send_http - =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 - collected 4 items - - test_mark_classlevel.py .. - test_server.py . - - =================== 1 tests deselected by '-k-send_http' =================== - ================== 3 passed, 1 deselected in 0.01 seconds ================== - -Or to only select the class:: - - $ py.test -kTestClass - =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 - collected 4 items - - test_mark_classlevel.py .. - - =================== 2 tests deselected by '-kTestClass' ==================== - ================== 2 passed, 2 deselected in 0.01 seconds ================== .. _`adding a custom marker from a plugin`: @@ -223,7 +242,8 @@ $ py.test -E stage2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 + plugins: pep8, cache, xdist collected 1 items test_someenv.py s @@ -234,7 +254,8 @@ $ py.test -E stage1 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 + plugins: pep8, cache, xdist collected 1 items test_someenv.py . @@ -351,25 +372,112 @@ $ py.test -rs # this option reports skip reasons =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 + plugins: pep8, cache, xdist collected 4 items test_plat.py s.s. ========================= short test summary info ========================== - SKIP [2] /tmp/doc-exec-135/conftest.py:12: cannot run on platform linux2 + SKIP [2] /tmp/doc-exec-196/conftest.py:12: cannot run on platform linux2 - =================== 2 passed, 2 skipped in 0.01 seconds ==================== + =================== 2 passed, 2 skipped in 0.02 seconds ==================== Note that if you specify a platform via the marker-command line option like this:: $ py.test -m linux2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 + plugins: pep8, cache, xdist collected 4 items test_plat.py . =================== 3 tests deselected by "-m 'linux2'" ==================== - ================== 1 passed, 3 deselected in 0.01 seconds ================== + ================== 1 passed, 3 deselected in 0.02 seconds ================== then the unmarked-tests will not be run. It is thus a way to restrict the run to the specific tests. + +Automatically adding markers based on test names +-------------------------------------------------------- + +.. regendoc:wipe + +If you a test suite where test function names indicate a certain +type of test, you can implement a hook that automatically defines +markers so that you can use the ``-m`` option with it. Let's look +at this test module:: + + # content of test_module.py + + def test_interface_simple(): + assert 0 + + def test_interface_complex(): + assert 0 + + def test_event_simple(): + assert 0 + + def test_something_else(): + assert 0 + +We want to dynamically define two markers and can do it in a +``conftest.py`` plugin:: + + # content of conftest.py + + import pytest + def pytest_collection_modifyitems(items): + for item in items: + if "interface" in item.nodeid: + item.keywords["interface"] = pytest.mark.interface + elif "event" in item.nodeid: + item.keywords["event"] = pytest.mark.event + +We can now use the ``-m option`` to select one set:: + + $ py.test -m interface --tb=short + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 + plugins: pep8, cache, xdist + collected 4 items + + test_module.py FF + + ================================= FAILURES ================================= + __________________________ test_interface_simple ___________________________ + test_module.py:3: in test_interface_simple + > assert 0 + E assert 0 + __________________________ test_interface_complex __________________________ + test_module.py:6: in test_interface_complex + > assert 0 + E assert 0 + ================== 2 tests deselected by "-m 'interface'" ================== + ================== 2 failed, 2 deselected in 0.02 seconds ================== + +or to select both "event" and "interface" tests:: + + $ py.test -m "interface or event" --tb=short + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 + plugins: pep8, cache, xdist + collected 4 items + + test_module.py FFF + + ================================= FAILURES ================================= + __________________________ test_interface_simple ___________________________ + test_module.py:3: in test_interface_simple + > assert 0 + E assert 0 + __________________________ test_interface_complex __________________________ + test_module.py:6: in test_interface_complex + > assert 0 + E assert 0 + ____________________________ test_event_simple _____________________________ + test_module.py:9: in test_event_simple + > assert 0 + E assert 0 + ============= 1 tests deselected by "-m 'interface or event'" ============== + ================== 3 failed, 1 deselected in 0.02 seconds ================== Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Sat Nov 10 11:16:59 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Sat, 10 Nov 2012 10:16:59 -0000 Subject: [py-svn] commit/pytest: MiCHiLU: Fix typos in a document Message-ID: <20121110101659.9675.80359@bitbucket25.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/c4ba9d8ace0f/ changeset: c4ba9d8ace0f user: MiCHiLU date: 2012-11-10 08:29:43 summary: Fix typos in a document affected #: 1 file diff -r e853a8edbbbfd2563f301926352a9cd571225e41 -r c4ba9d8ace0f4fd62720817863c2e314dbc0529f doc/en/goodpractises.txt --- a/doc/en/goodpractises.txt +++ b/doc/en/goodpractises.txt @@ -73,7 +73,7 @@ pass def run(self): import sys,subprocess - errno = subprocess.call([sys.executable, 'runtest.py']) + errno = subprocess.call([sys.executable, 'runtests.py']) raise SystemExit(errno) setup( #..., @@ -85,7 +85,7 @@ python setup.py test -this will execute your tests using ``runtest.py``. As this is a +this will execute your tests using ``runtests.py``. As this is a standalone version of ``py.test`` no prior installation whatsoever is required for calling the test command. You can also pass additional arguments to the subprocess-calls such as your test directory or other Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Mon Nov 12 10:16:08 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 12 Nov 2012 09:16:08 -0000 Subject: [py-svn] commit/pytest: hpk42: fix issue224 - invocations with >256 char arguments now work Message-ID: <20121112091608.20255.72856@bitbucket01.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/8f615e58d664/ changeset: 8f615e58d664 user: hpk42 date: 2012-11-12 10:15:43 summary: fix issue224 - invocations with >256 char arguments now work affected #: 5 files diff -r c4ba9d8ace0f4fd62720817863c2e314dbc0529f -r 8f615e58d66436d4561a8478b345fcacb03323df CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Changes between 2.3.3 and 2.3.4.dev ----------------------------------- +- fix issue224 - invocations with >256 char arguments now work - fix issue91 - add/discuss package/directory level setups in example - allow to dynamically define markers via item.keywords[...]=assignment integrating with "-m" option diff -r c4ba9d8ace0f4fd62720817863c2e314dbc0529f -r 8f615e58d66436d4561a8478b345fcacb03323df _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.4.dev3' +__version__ = '2.3.4.dev4' diff -r c4ba9d8ace0f4fd62720817863c2e314dbc0529f -r 8f615e58d66436d4561a8478b345fcacb03323df _pytest/config.py --- a/_pytest/config.py +++ b/_pytest/config.py @@ -181,7 +181,7 @@ if hasattr(arg, 'startswith') and arg.startswith("--"): continue anchor = current.join(arg, abs=1) - if anchor.check(): # we found some file object + if exists(anchor): # we found some file object self._try_load_conftest(anchor) foundanchor = True if not foundanchor: @@ -479,6 +479,11 @@ except KeyError: py.test.skip("no %r value found" %(name,)) +def exists(path, ignore=EnvironmentError): + try: + return path.check() + except ignore: + return False def getcfg(args, inibasenames): args = [x for x in args if not str(x).startswith("-")] @@ -489,7 +494,7 @@ for base in arg.parts(reverse=True): for inibasename in inibasenames: p = base.join(inibasename) - if p.check(): + if exists(p): iniconfig = py.iniconfig.IniConfig(p) if 'pytest' in iniconfig.sections: return iniconfig['pytest'] diff -r c4ba9d8ace0f4fd62720817863c2e314dbc0529f -r 8f615e58d66436d4561a8478b345fcacb03323df setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.4.dev3', + version='2.3.4.dev4', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r c4ba9d8ace0f4fd62720817863c2e314dbc0529f -r 8f615e58d66436d4561a8478b345fcacb03323df testing/test_config.py --- a/testing/test_config.py +++ b/testing/test_config.py @@ -315,3 +315,7 @@ "*-h*", ]) + +def test_toolongargs_issue224(testdir): + result = testdir.runpytest("-m", "hello" * 500) + assert result.ret == 0 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Nov 14 09:40:50 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 14 Nov 2012 08:40:50 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20121114084050.13935.44023@bitbucket03.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/3a975e5766a9/ changeset: 3a975e5766a9 user: hpk42 date: 2012-11-14 09:39:21 summary: add example for accessing test result information from fixture affected #: 1 file diff -r 8f615e58d66436d4561a8478b345fcacb03323df -r 3a975e5766a9fe1abaef82d561161b2b80791f1a doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -106,7 +106,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 0 items ============================= in 0.00 seconds ============================= @@ -150,12 +150,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-156/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-4/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -163,7 +163,7 @@ $ py.test --runslow =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_module.py .. @@ -253,7 +253,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 project deps: mylib-1.1 collected 0 items @@ -276,7 +276,7 @@ $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 -- /home/hpk/venv/0/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/venv/regen/bin/python2.7 info1: did you know that ... did you? collecting ... collected 0 items @@ -287,7 +287,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 0 items ============================= in 0.00 seconds ============================= @@ -319,7 +319,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 3 items test_some_are_slow.py ... @@ -380,7 +380,7 @@ $ py.test -rx =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 4 items test_step.py .Fx. @@ -388,7 +388,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -398,7 +398,7 @@ ========================= short test summary info ========================== XFAIL test_step.py::TestUserHandling::()::test_deletion reason: previous test failed (test_modification) - ============== 1 failed, 2 passed, 1 xfailed in 0.01 seconds =============== + ============== 1 failed, 2 passed, 1 xfailed in 0.02 seconds =============== We'll see that ``test_deletion`` was not executed because ``test_modification`` failed. It is reported as an "expected failure". @@ -450,7 +450,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 7 items test_step.py .Fx. @@ -460,17 +460,17 @@ ================================== ERRORS ================================== _______________________ ERROR at setup of test_root ________________________ - file /tmp/doc-exec-156/b/test_error.py, line 1 + file /tmp/doc-exec-4/b/test_error.py, line 1 def test_root(db): # no db here, will error out fixture 'db' not found available fixtures: pytestconfig, recwarn, monkeypatch, capfd, capsys, tmpdir use 'py.test --fixtures [testpath]' for help on them. - /tmp/doc-exec-156/b/test_error.py:1 + /tmp/doc-exec-4/b/test_error.py:1 ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -479,20 +479,20 @@ test_step.py:9: AssertionError _________________________________ test_a1 __________________________________ - db = + db = def test_a1(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db.py:2: AssertionError _________________________________ test_a2 __________________________________ - db = + db = def test_a2(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db2.py:2: AssertionError ========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.03 seconds ========== @@ -550,7 +550,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev1 + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 collected 2 items test_module.py FF @@ -558,7 +558,7 @@ ================================= FAILURES ================================= ________________________________ test_fail1 ________________________________ - tmpdir = local('/tmp/pytest-3/test_fail10') + tmpdir = local('/tmp/pytest-6/test_fail10') def test_fail1(tmpdir): > assert 0 @@ -577,5 +577,105 @@ you will have a "failures" file which contains the failing test ids:: $ cat failures - test_module.py::test_fail1 (/tmp/pytest-3/test_fail10) + test_module.py::test_fail1 (/tmp/pytest-6/test_fail10) test_module.py::test_fail2 + +Making test result information available in fixtures +----------------------------------------------------------- + +.. regendoc:wipe + +If you want to make test result reports available in fixture finalizers +here is a little example implemented via a local plugin:: + + # content of conftest.py + + import pytest + + @pytest.mark.tryfirst + def pytest_runtest_makereport(item, call, __multicall__): + # execute all other hooks to obtain the report object + rep = __multicall__.execute() + + # set an report attribute for each phase of a call, which can + # be "setup", "call", "teardown" + + setattr(item, "rep_" + rep.when, rep) + return rep + + + @pytest.fixture + def something(request): + def fin(): + # request.node is an "item" because we use the default + # "function" scope + if request.node.rep_setup.failed: + print "setting up a test failed!", request.node.nodeid + elif request.node.rep_setup.passed: + if request.node.rep_call.failed: + print "executing test failed", request.node.nodeid + request.addfinalizer(fin) + + +if you then have failing tests:: + + # content of test_module.py + + import pytest + + @pytest.fixture + def other(): + assert 0 + + def test_setup_fails(something, other): + pass + + def test_call_fails(something): + assert 0 + + def test_fail2(): + assert 0 + +and run it:: + + $ py.test -s test_module.py + =========================== test session starts ============================ + platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + collected 3 items + + test_module.py EFF + + ================================== ERRORS ================================== + ____________________ ERROR at setup of test_setup_fails ____________________ + + @pytest.fixture + def other(): + > assert 0 + E assert 0 + + test_module.py:6: AssertionError + ================================= FAILURES ================================= + _____________________________ test_call_fails ______________________________ + + something = None + + def test_call_fails(something): + > assert 0 + E assert 0 + + test_module.py:12: AssertionError + ________________________________ test_fail2 ________________________________ + + def test_fail2(): + > assert 0 + E assert 0 + + test_module.py:15: AssertionError + ==================== 2 failed, 1 error in 0.01 seconds ===================== + setting up a test failed! test_module.py::test_setup_fails + executing test failed test_module.py::test_call_fails + + +You'll see that the fixture finalizers could use the precise reporting +information. + https://bitbucket.org/hpk42/pytest/changeset/7aabd6e854e2/ changeset: 7aabd6e854e2 user: hpk42 date: 2012-11-14 09:40:01 summary: fix typo (thanks Thomas Waldmann) affected #: 1 file diff -r 3a975e5766a9fe1abaef82d561161b2b80791f1a -r 7aabd6e854e29c5846f0061258d338feac119c42 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1601,9 +1601,9 @@ class FixtureDef: """ A container for a factory definition. """ - def __init__(self, fixturenanager, baseid, argname, func, scope, params, + def __init__(self, fixturemanager, baseid, argname, func, scope, params, unittest=False): - self._fixturemanager = fixturenanager + self._fixturemanager = fixturemanager self.baseid = baseid self.func = func self.argname = argname Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From issues-reply at bitbucket.org Wed Nov 14 09:55:58 2012 From: issues-reply at bitbucket.org (Thomas Waldmann) Date: Wed, 14 Nov 2012 08:55:58 -0000 Subject: [py-svn] [hpk42/pytest] fixture init and finalize order (issue #226) Message-ID: <34979f4fabb971fcb3fa305a52fb40d4@bitbucket.org> --- you can reply above this line --- New issue 226: fixture init and finalize order https://bitbucket.org/hpk42/pytest/issue/226/fixture-init-and-finalize-order Thomas Waldmann: if fixture init order is like a, b, c, then fixture finalize order should be c, b, a. e.g. if "a" is a fundamental thing that was created because it was required by "b" (or "c"), then teardown (finalizing) of it should be last, otherwise there might be issues like "b" still using "a" somehow. -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From issues-reply at bitbucket.org Thu Nov 15 16:40:07 2012 From: issues-reply at bitbucket.org (James Laska) Date: Thu, 15 Nov 2012 15:40:07 -0000 Subject: [py-svn] [hpk42/pytest] yield and funcarg don't mix (issue #227) Message-ID: <142a761db65015e585d62fbd41e4fb08@bitbucket.org> --- you can reply above this line --- New issue 227: yield and funcarg don't mix https://bitbucket.org/hpk42/pytest/issue/227/yield-and-funcarg-dont-mix James Laska: This appears to be similar in spirit to the problem reported in issue #16 pytest doesn't yield properly when called within a function/method that uses generated func_args. For example, the following test: ``` #!python def pytest_funcarg__bar(request): return "bar" def test_good(): pass def test_bad(bar): yield 'bad-func-yield', True class Testitem(object): def test_foo(self, bar): yield 'bad-method-yield', True ``` Fails to yield as expected ... ``` #!python ============================================================================================= test session starts ============================================================================================= platform linux2 -- Python 2.7.3 -- pytest-2.3.3 plugins: xdist, mozwebqa collected 1 items / 2 errors ../../../../tmp/test_yield.py . =================================================================================================== ERRORS ==================================================================================================== _______________________________________________________________________________ ERROR collecting ../../../../tmp/test_yield.py ________________________________________________________________________________ /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/runner.py:121: in __init__ > self.result = func() /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/main.py:366: in _memocollect > return self._memoizedcall('_collected', lambda: list(self.collect())) /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/main.py:287: in _memoizedcall > res = function() /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/main.py:366: in > return self._memoizedcall('_collected', lambda: list(self.collect())) /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/python.py:494: in collect > for i, x in enumerate(self.obj()): E TypeError: test_bad() takes exactly 1 argument (0 given) _______________________________________________________________________________ ERROR collecting ../../../../tmp/test_yield.py ________________________________________________________________________________ /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/runner.py:121: in __init__ > self.result = func() /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/main.py:366: in _memocollect > return self._memoizedcall('_collected', lambda: list(self.collect())) /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/main.py:287: in _memoizedcall > res = function() /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/main.py:366: in > return self._memoizedcall('_collected', lambda: list(self.collect())) /home/devel/jlaska/.python/lib/python2.7/site-packages/_pytest/python.py:494: in collect > for i, x in enumerate(self.obj()): E TypeError: test_foo() takes exactly 2 arguments (1 given) ====================================================================================== 1 passed, 2 error in 3.58 seconds ====================================================================================== ``` -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From commits-noreply at bitbucket.org Fri Nov 16 10:05:39 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 16 Nov 2012 09:05:39 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20121116090539.19277.4450@bitbucket02.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/6c27237aa4e5/ changeset: 6c27237aa4e5 user: hpk42 date: 2012-11-14 10:02:47 summary: add a note about yield tests at least in the CHANGELOG affected #: 1 file diff -r 7aabd6e854e29c5846f0061258d338feac119c42 -r 6c27237aa4e5af72a1319555a8a5267932eed615 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,10 @@ Changes between 2.3.3 and 2.3.4.dev ----------------------------------- +- NOTE: the pre-2.0 way of yielding tests is not compatible + with autouse fixtures. If you need generative tests, use + @pytest.mark.parametrize or pytest_generate_tests, see the + many examples at http://pytest.org/latest/example/parametrize.html - fix issue224 - invocations with >256 char arguments now work - fix issue91 - add/discuss package/directory level setups in example - allow to dynamically define markers via https://bitbucket.org/hpk42/pytest/changeset/e7a5763577a2/ changeset: e7a5763577a2 user: hpk42 date: 2012-11-16 10:03:51 summary: fix issue226 - LIFO ordering for fixture-added teardowns affected #: 5 files diff -r 6c27237aa4e5af72a1319555a8a5267932eed615 -r e7a5763577a2b443125cbc9da8ef30a9f7bcb97a CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ with autouse fixtures. If you need generative tests, use @pytest.mark.parametrize or pytest_generate_tests, see the many examples at http://pytest.org/latest/example/parametrize.html +- fix issue226 - LIFO ordering for fixture teardowns - fix issue224 - invocations with >256 char arguments now work - fix issue91 - add/discuss package/directory level setups in example - allow to dynamically define markers via diff -r 6c27237aa4e5af72a1319555a8a5267932eed615 -r e7a5763577a2b443125cbc9da8ef30a9f7bcb97a _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.4.dev4' +__version__ = '2.3.4.dev5' diff -r 6c27237aa4e5af72a1319555a8a5267932eed615 -r e7a5763577a2b443125cbc9da8ef30a9f7bcb97a _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1224,6 +1224,7 @@ if paramscopenum != scopenum_subfunction: scope = scopes[paramscopenum] + # check if a higher-level scoped fixture accesses a lower level one if scope is not None: __tracebackhide__ = True if scopemismatch(self.scope, scope): @@ -1236,15 +1237,18 @@ __tracebackhide__ = False mp.setattr(self, "scope", scope) + # route request.addfinalizer to fixturedef + mp.setattr(self, "addfinalizer", fixturedef.addfinalizer) + + # perform the fixture call + val = fixturedef.execute(request=self) + # prepare finalization according to scope # (XXX analyse exact finalizing mechanics / cleanup) self.session._setupstate.addfinalizer(fixturedef.finish, self.node) self._fixturemanager.addargfinalizer(fixturedef.finish, argname) for subargname in fixturedef.argnames: # XXX all deps? self._fixturemanager.addargfinalizer(fixturedef.finish, subargname) - mp.setattr(self, "addfinalizer", fixturedef.addfinalizer) - # finally perform the fixture call - val = fixturedef.execute(request=self) mp.undo() return val @@ -1503,6 +1507,8 @@ items[:] = parametrize_sorted(items, set(), {}, 0) def pytest_runtest_teardown(self, item, nextitem): + # XXX teardown needs to be normalized for parametrized and + # no-parametrized functions try: cs1 = item.callspec except AttributeError: @@ -1524,7 +1530,7 @@ keylist.sort() for (scopenum, name, param) in keylist: item.session._setupstate._callfinalizers((name, param)) - l = self._arg2finish.get(name) + l = self._arg2finish.pop(name, None) if l is not None: for fin in reversed(l): fin() diff -r 6c27237aa4e5af72a1319555a8a5267932eed615 -r e7a5763577a2b443125cbc9da8ef30a9f7bcb97a setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.4.dev4', + version='2.3.4.dev5', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 6c27237aa4e5af72a1319555a8a5267932eed615 -r e7a5763577a2b443125cbc9da8ef30a9f7bcb97a testing/python/fixture.py --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -1105,7 +1105,7 @@ reprec = testdir.inline_run() reprec.assertoutcome(passed=5) - def test_setup_funcarg_order(self, testdir): + def test_ordering_autouse_before_explicit(self, testdir): testdir.makepyfile(""" import pytest @@ -1122,6 +1122,30 @@ reprec = testdir.inline_run() reprec.assertoutcome(passed=1) + @pytest.mark.issue226 + @pytest.mark.parametrize("param1", ["", "params=[1]"]) + @pytest.mark.parametrize("param2", ["", "params=[1]"]) + def test_ordering_dependencies_torndown_first(self, testdir, param1, param2): + testdir.makepyfile(""" + import pytest + l = [] + @pytest.fixture(%(param1)s) + def arg1(request): + request.addfinalizer(lambda: l.append("fin1")) + l.append("new1") + @pytest.fixture(%(param2)s) + def arg2(request, arg1): + request.addfinalizer(lambda: l.append("fin2")) + l.append("new2") + + def test_arg(arg2): + pass + def test_check(): + assert l == ["new1", "new2", "fin2", "fin1"] + """ % locals()) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(passed=2) + class TestFixtureMarker: def test_parametrize(self, testdir): testdir.makepyfile(""" Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From issues-reply at bitbucket.org Fri Nov 16 17:29:45 2012 From: issues-reply at bitbucket.org (Danilo Bellini) Date: Fri, 16 Nov 2012 16:29:45 -0000 Subject: [py-svn] [hpk42/pytest] Recwarn empty (issue #228) Message-ID: --- you can reply above this line --- New issue 228: Recwarn empty https://bitbucket.org Danilo Bellini: Problem: Test if a function "creates" warnings or if it don't create any. Solution: 1. For now, I'm not using "recwarn", since it didn't work in my code. 2. Call the warning creator routine inside a warnings.catch_warnings context manager. 3. Call warnings.simplefilter("always") before the context manager (somehow, it don't work when "inside" the context manager). The code is in: https://github.com/danilobellini/audiolazy/blob/0fe2586bb81d9bc266998ce478a267a2659d4076/audiolazy/test/test_stream.py#L235 However, I think I should be using the recwarn funcarg. I tryed this: class TestThub(object): @p("copies", range(5)) @p("used_copies", range(5)) def test_stream_tee_hub_memory_leak_warning_and_index_error( self, copies, used_copies, recwarn): data = Stream(.5, 8, 7 + 2j) data = thub(data, copies) assert isinstance(data, StreamTeeHub) if copies < used_copies: with pytest.raises(IndexError): [data * n for n in xrange(used_copies)] else: [data * n for n in xrange(used_copies)] data.__del__() if copies != used_copies: w = recwarn.pop() assert issubclass(w.category, MemoryLeakWarning) assert str(copies - used_copies) in str(w.message) assert recwarn.list == [] That did't work: the test in the link works, the test above "misses"/filters some warn() calls, and an error is given when "recwarn.pop()" is called with an empty recwarn. But only when used_copies > 0 (i.e., it works when used_copies == 0 and copies > 0). Also, the recwarn.list isn't documented anywhere. I wanted to assert "there's no warning" and found no documented way with recwarn. Perhaps I can use the pop() method in a try block, but I think the list comparison is simpler. -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From issues-reply at bitbucket.org Mon Nov 19 11:06:53 2012 From: issues-reply at bitbucket.org (Ronny Pfannschmidt) Date: Mon, 19 Nov 2012 10:06:53 -0000 Subject: [py-svn] [hpk42/pytest] implement something like the nose importer to avoid altering sys.path (issue #229) Message-ID: <8cdb06106cfb33b31c6b973b898b9f39@bitbucket.org> --- you can reply above this line --- New issue 229: implement something like the nose importer to avoid altering sys.path https://bitbucket.org Ronny Pfannschmidt: https://github.com/nose-devs/nose/blob/master/nose/importer.py it handles importing while avoiding modification of sys.path, which allows for tes modules with the same name -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From commits-noreply at bitbucket.org Mon Nov 19 12:42:19 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Mon, 19 Nov 2012 11:42:19 -0000 Subject: [py-svn] commit/pytest: hpk42: getting rid of redundant "active" attribute Message-ID: <20121119114219.14974.50743@bitbucket05.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/eec537f128e1/ changeset: eec537f128e1 user: hpk42 date: 2012-11-19 12:42:10 summary: getting rid of redundant "active" attribute affected #: 1 file diff -r e7a5763577a2b443125cbc9da8ef30a9f7bcb97a -r eec537f128e1a1e9c80e373051486c290fc24e46 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1197,8 +1197,10 @@ self._fixturestack.pop() def _getfuncargvalue(self, fixturedef): - if fixturedef.active: - return fixturedef.cached_result + try: + return fixturedef.cached_result # set by fixturedef.execute() + except AttributeError: + pass # prepare request fixturename and param attributes before # calling into fixture function @@ -1619,7 +1621,6 @@ startindex = unittest and 1 or None self.argnames = getfuncargnames(func, startindex=startindex) self.unittest = unittest - self.active = False self._finalizer = [] def addfinalizer(self, finalizer): @@ -1631,9 +1632,11 @@ func() # check neccesity of next commented call self._fixturemanager.removefinalizer(self.finish) - self.active = False #print "finished", self - #del self.cached_result + try: + del self.cached_result + except AttributeError: + pass def execute(self, request): kwargs = {} @@ -1655,7 +1658,7 @@ except AttributeError: pass result = fixturefunc(**kwargs) - self.active = True + assert not hasattr(self, "cached_result") self.cached_result = result return result Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 20 11:38:17 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Nov 2012 10:38:17 -0000 Subject: [py-svn] commit/pytest: 4 new changesets Message-ID: <20121120103817.8975.80595@bitbucket22.managed.contegix.com> 4 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/6e95f36c5689/ changeset: 6e95f36c5689 user: hpk42 date: 2012-11-19 14:07:14 summary: modernize tmpdir fixture (use request.node in tmpdir fixture, use @pytest.fixture) affected #: 2 files diff -r eec537f128e1a1e9c80e373051486c290fc24e46 -r 6e95f36c56897a3e93ac4e3d39a97d90db676a0f _pytest/tmpdir.py --- a/_pytest/tmpdir.py +++ b/_pytest/tmpdir.py @@ -54,15 +54,15 @@ mp.setattr(config, '_tmpdirhandler', t, raising=False) mp.setattr(pytest, 'ensuretemp', t.ensuretemp, raising=False) -def pytest_funcarg__tmpdir(request): + at pytest.fixture +def tmpdir(request): """return a temporary directory path object which is unique to each test function invocation, created as a sub directory of the base temporary directory. The returned object is a `py.path.local`_ path object. """ - name = request._pyfuncitem.name + name = request.node.name name = py.std.re.sub("[\W]", "_", name) x = request.config._tmpdirhandler.mktemp(name, numbered=True) return x - diff -r eec537f128e1a1e9c80e373051486c290fc24e46 -r 6e95f36c56897a3e93ac4e3d39a97d90db676a0f testing/test_tmpdir.py --- a/testing/test_tmpdir.py +++ b/testing/test_tmpdir.py @@ -1,7 +1,7 @@ import py, pytest import os -from _pytest.tmpdir import pytest_funcarg__tmpdir, TempdirHandler +from _pytest.tmpdir import tmpdir, TempdirHandler def test_funcarg(testdir): testdir.makepyfile(""" @@ -16,12 +16,12 @@ # pytest_unconfigure has deleted the TempdirHandler already config = item.config config._tmpdirhandler = TempdirHandler(config) - p = pytest_funcarg__tmpdir(item) + p = tmpdir(item._request) assert p.check() bn = p.basename.strip("0123456789") assert bn.endswith("test_func_a_") item.name = "qwe/\\abc" - p = pytest_funcarg__tmpdir(item) + p = tmpdir(item._request) assert p.check() bn = p.basename.strip("0123456789") assert bn == "qwe__abc" https://bitbucket.org/hpk42/pytest/changeset/992d5d6b38e1/ changeset: 992d5d6b38e1 user: hpk42 date: 2012-11-19 22:17:55 summary: fix autouse invocation (off-by-one error), relates to issue in moinmoin test suite affected #: 5 files diff -r 6e95f36c56897a3e93ac4e3d39a97d90db676a0f -r 992d5d6b38e127cde032300b02383a88ac1e83b7 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,8 @@ with autouse fixtures. If you need generative tests, use @pytest.mark.parametrize or pytest_generate_tests, see the many examples at http://pytest.org/latest/example/parametrize.html +- fix autouse-issue where autouse-fixtures would not be discovered + if defined in a a/conftest.py file and tests in a/tests/test_some.py - fix issue226 - LIFO ordering for fixture teardowns - fix issue224 - invocations with >256 char arguments now work - fix issue91 - add/discuss package/directory level setups in example diff -r 6e95f36c56897a3e93ac4e3d39a97d90db676a0f -r 992d5d6b38e127cde032300b02383a88ac1e83b7 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.4.dev5' +__version__ = '2.3.4.dev6' diff -r 6e95f36c56897a3e93ac4e3d39a97d90db676a0f -r 992d5d6b38e127cde032300b02383a88ac1e83b7 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -1455,7 +1455,7 @@ for baseid, basenames in self._nodeid_and_autousenames: if nodeid.startswith(baseid): if baseid: - i = len(baseid) + 1 + i = len(baseid) nextchar = nodeid[i:i+1] if nextchar and nextchar not in ":/": continue diff -r 6e95f36c56897a3e93ac4e3d39a97d90db676a0f -r 992d5d6b38e127cde032300b02383a88ac1e83b7 setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.4.dev5', + version='2.3.4.dev6', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 6e95f36c56897a3e93ac4e3d39a97d90db676a0f -r 992d5d6b38e127cde032300b02383a88ac1e83b7 testing/python/fixture.py --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -948,7 +948,26 @@ reprec = testdir.inline_run() reprec.assertoutcome(passed=3) + class TestAutouseManagement: + def test_autouse_conftest_mid_directory(self, testdir): + pkgdir = testdir.mkpydir("xyz123") + pkgdir.join("conftest.py").write(py.code.Source(""" + import pytest + @pytest.fixture(autouse=True) + def app(): + import sys + sys._myapp = "hello" + """)) + t = pkgdir.ensure("tests", "test_app.py") + t.write(py.code.Source(""" + import sys + def test_app(): + assert sys._myapp == "hello" + """)) + reprec = testdir.inline_run("-s") + reprec.assertoutcome(passed=1) + def test_funcarg_and_setup(self, testdir): testdir.makepyfile(""" import pytest https://bitbucket.org/hpk42/pytest/changeset/a4ce00a86c9d/ changeset: a4ce00a86c9d user: hpk42 date: 2012-11-19 22:17:59 summary: make yielded tests participate in the autouse protocol affected #: 3 files diff -r 992d5d6b38e127cde032300b02383a88ac1e83b7 -r a4ce00a86c9daabc16ee91c306e3baf892e8b759 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Changes between 2.3.3 and 2.3.4.dev ----------------------------------- +- yielded tests will activate autouse-fixtures - NOTE: the pre-2.0 way of yielding tests is not compatible with autouse fixtures. If you need generative tests, use @pytest.mark.parametrize or pytest_generate_tests, see the diff -r 992d5d6b38e127cde032300b02383a88ac1e83b7 -r a4ce00a86c9daabc16ee91c306e3baf892e8b759 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -528,7 +528,7 @@ def fillfixtures(function): """ fill missing funcargs for a test function. """ - if getattr(function, "_args", None) is None: # not a yielded function + if 1 or getattr(function, "_args", None) is None: # not a yielded function try: request = function._request except AttributeError: @@ -906,12 +906,15 @@ self.keywords[name] = val fm = self.session._fixturemanager - self._fixtureinfo = fi = fm.getfixtureinfo(self.parent, - self.obj, self.cls) + isyield = self._isyieldedfunction() + self._fixtureinfo = fi = fm.getfixtureinfo(self.parent, self.obj, + self.cls, + funcargs=not isyield) self.fixturenames = fi.names_closure - if self._isyieldedfunction(): + if isyield: assert not callspec, ( "yielded functions (deprecated) cannot have funcargs") + self.funcargs = {} else: if callspec is not None: self.callspec = callspec @@ -921,8 +924,7 @@ self.param = callspec.param else: self.funcargs = {} - self._request = req = FixtureRequest(self) - #req._discoverfactories() + self._request = req = FixtureRequest(self) @property def function(self): @@ -1398,13 +1400,13 @@ self._nodename2fixtureinfo = {} - def getfixtureinfo(self, node, func, cls): + def getfixtureinfo(self, node, func, cls, funcargs=True): key = (node, func.__name__) try: return self._nodename2fixtureinfo[key] except KeyError: pass - if not hasattr(node, "nofuncargs"): + if funcargs and not hasattr(node, "nofuncargs"): if cls is not None: startindex = 1 else: diff -r 992d5d6b38e127cde032300b02383a88ac1e83b7 -r a4ce00a86c9daabc16ee91c306e3baf892e8b759 testing/python/fixture.py --- a/testing/python/fixture.py +++ b/testing/python/fixture.py @@ -968,6 +968,24 @@ reprec = testdir.inline_run("-s") 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() + reprec.assertoutcome(passed=2) + + + def test_funcarg_and_setup(self, testdir): testdir.makepyfile(""" import pytest https://bitbucket.org/hpk42/pytest/changeset/7433673d86bb/ changeset: 7433673d86bb user: hpk42 date: 2012-11-19 22:20:37 summary: adapt changelog entry about autouse fixtures and yield affected #: 1 file diff -r a4ce00a86c9daabc16ee91c306e3baf892e8b759 -r 7433673d86bb5a96cb5d6aa6f109ba03a868bb9f CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -2,10 +2,9 @@ ----------------------------------- - yielded tests will activate autouse-fixtures -- NOTE: the pre-2.0 way of yielding tests is not compatible - with autouse fixtures. If you need generative tests, use - @pytest.mark.parametrize or pytest_generate_tests, see the - many examples at http://pytest.org/latest/example/parametrize.html +- NOTE: yielded tests cannot use fixtures - if you need this + you may want to use the post-2.0 parametrize features, see + http://pytest.org/latest/example/parametrize.html - fix autouse-issue where autouse-fixtures would not be discovered if defined in a a/conftest.py file and tests in a/tests/test_some.py - fix issue226 - LIFO ordering for fixture teardowns Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 20 11:52:40 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Nov 2012 10:52:40 -0000 Subject: [py-svn] commit/pytest: hpk42: don't run long-args test on windows because it can't work Message-ID: <20121120105240.5913.35347@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/9f461741482e/ changeset: 9f461741482e user: hpk42 date: 2012-11-20 11:52:06 summary: don't run long-args test on windows because it can't work affected #: 1 file diff -r 7433673d86bb5a96cb5d6aa6f109ba03a868bb9f -r 9f461741482eec7b4ab41c06cf50b07008d70169 testing/test_config.py --- a/testing/test_config.py +++ b/testing/test_config.py @@ -316,6 +316,7 @@ ]) + at pytest.mark.skipif("sys.platform == 'win32'") def test_toolongargs_issue224(testdir): result = testdir.runpytest("-m", "hello" * 500) assert result.ret == 0 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 20 13:42:12 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Nov 2012 12:42:12 -0000 Subject: [py-svn] commit/pytest: hpk42: bump version, add announcement, regen docs Message-ID: <20121120124212.31975.97648@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/048679527ddc/ changeset: 048679527ddc user: hpk42 date: 2012-11-20 13:42:00 summary: bump version, add announcement, regen docs affected #: 22 files diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,9 @@ -Changes between 2.3.3 and 2.3.4.dev +Changes between 2.3.3 and 2.3.4 ----------------------------------- -- yielded tests will activate autouse-fixtures -- NOTE: yielded tests cannot use fixtures - if you need this - you may want to use the post-2.0 parametrize features, see +- yielded test functions will now have autouse-fixtures active but + cannot accept fixtures as funcargs - it's anyway recommended to + rather use the post-2.0 parametrize features instead of yield, see: http://pytest.org/latest/example/parametrize.html - fix autouse-issue where autouse-fixtures would not be discovered if defined in a a/conftest.py file and tests in a/tests/test_some.py diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.4.dev6' +__version__ = '2.4.6' diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/announce/index.txt --- a/doc/en/announce/index.txt +++ b/doc/en/announce/index.txt @@ -5,6 +5,7 @@ .. toctree:: :maxdepth: 2 + release-2.3.4 release-2.3.3 release-2.3.2 release-2.3.1 diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/announce/release-2.3.4.txt --- /dev/null +++ b/doc/en/announce/release-2.3.4.txt @@ -0,0 +1,39 @@ +pytest-2.3.4: stabilization, more flexible selection via "-k expr" +=========================================================================== + +pytest-2.3.4 is a small stabilization release of the py.test tool +which offers uebersimple assertions, scalable fixture mechanisms +and deep customization for testing with Python. The Particularly, +this release provides: + +- make "-k" option accept an expressions the same as with "-m" so that one + can write: -k "name1 or name2" etc. This is a slight usage incompatibility + if you used special syntax like "TestClass.test_method" which you now + need to write as -k "TestClass and test_method" to match a certain + method in a certain test class. +- allow to dynamically define markers via + item.keywords[...]=assignment integrating with "-m" option +- yielded test functions will now have autouse-fixtures active but + cannot accept fixtures as funcargs - it's anyway recommended to + rather use the post-2.0 parametrize features instead of yield, see: + http://pytest.org/latest/example/parametrize.html +- fix autouse-issue where autouse-fixtures would not be discovered + if defined in a a/conftest.py file and tests in a/tests/test_some.py +- fix issue226 - LIFO ordering for fixture teardowns +- fix issue224 - invocations with >256 char arguments now work +- fix issue91 - add/discuss package/directory level setups in example +- fixes related to autouse discovery and calling + +Thanks to Thomas Waldmann in particular for spotting autouse issues. + +See + + http://pytest.org/ + +for general information. To install or upgrade pytest: + + pip install -U pytest # or + easy_install -U pytest + +best, +holger krekel diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/assert.txt --- a/doc/en/assert.txt +++ b/doc/en/assert.txt @@ -26,7 +26,7 @@ $ py.test test_assert1.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items test_assert1.py F @@ -110,7 +110,7 @@ $ py.test test_assert2.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items test_assert2.py F diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/capture.txt --- a/doc/en/capture.txt +++ b/doc/en/capture.txt @@ -64,7 +64,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items test_module.py .F @@ -78,7 +78,7 @@ test_module.py:9: AssertionError ----------------------------- Captured stdout ------------------------------ - setting up + setting up ==================== 1 failed, 1 passed in 0.01 seconds ==================== Accessing captured output from a test function diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/conf.py --- a/doc/en/conf.py +++ b/doc/en/conf.py @@ -17,7 +17,7 @@ # # The full version, including alpha/beta/rc tags. # The short X.Y version. -version = release = "2.3.3.3" +version = release = "2.3.4" import sys, os diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/doctest.txt --- a/doc/en/doctest.txt +++ b/doc/en/doctest.txt @@ -44,9 +44,9 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items mymodule.py . - ========================= 1 passed in 0.11 seconds ========================= + ========================= 1 passed in 0.02 seconds ========================= diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -28,9 +28,7 @@ $ py.test -v -m webtest =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python - cachedir: /tmp/doc-exec-196/.cache - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED @@ -42,16 +40,14 @@ $ py.test -v -m "not webtest" =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python - cachedir: /tmp/doc-exec-196/.cache - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:6: test_something_quick PASSED test_server.py:8: test_another PASSED ================= 1 tests deselected by "-m 'not webtest'" ================= - ================== 2 passed, 1 deselected in 0.02 seconds ================== + ================== 2 passed, 1 deselected in 0.01 seconds ================== Using ``-k expr`` to select tests based on their name ------------------------------------------------------- @@ -65,23 +61,19 @@ $ py.test -v -k http # running with the above defined example module =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python - cachedir: /tmp/doc-exec-196/.cache - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED - =================== 2 tests deselected by '-ksend_http' ==================== + ====================== 2 tests deselected by '-khttp' ====================== ================== 1 passed, 2 deselected in 0.01 seconds ================== And you can also run all tests except the ones that match the keyword:: $ py.test -k "not send_http" -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python - cachedir: /tmp/doc-exec-196/.cache - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:6: test_something_quick PASSED @@ -94,9 +86,7 @@ $ py.test -k "http or quick" -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 -- /home/hpk/venv/1/bin/python - cachedir: /tmp/doc-exec-196/.cache - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED @@ -242,8 +232,7 @@ $ py.test -E stage2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items test_someenv.py s @@ -254,8 +243,7 @@ $ py.test -E stage1 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items test_someenv.py . @@ -372,28 +360,26 @@ $ py.test -rs # this option reports skip reasons =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 4 items test_plat.py s.s. ========================= short test summary info ========================== - SKIP [2] /tmp/doc-exec-196/conftest.py:12: cannot run on platform linux2 + SKIP [2] /tmp/doc-exec-69/conftest.py:12: cannot run on platform linux2 - =================== 2 passed, 2 skipped in 0.02 seconds ==================== + =================== 2 passed, 2 skipped in 0.01 seconds ==================== Note that if you specify a platform via the marker-command line option like this:: $ py.test -m linux2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 4 items test_plat.py . =================== 3 tests deselected by "-m 'linux2'" ==================== - ================== 1 passed, 3 deselected in 0.02 seconds ================== + ================== 1 passed, 3 deselected in 0.01 seconds ================== then the unmarked-tests will not be run. It is thus a way to restrict the run to the specific tests. @@ -438,8 +424,7 @@ $ py.test -m interface --tb=short =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 4 items test_module.py FF @@ -454,14 +439,13 @@ > assert 0 E assert 0 ================== 2 tests deselected by "-m 'interface'" ================== - ================== 2 failed, 2 deselected in 0.02 seconds ================== + ================== 2 failed, 2 deselected in 0.01 seconds ================== or to select both "event" and "interface" tests:: $ py.test -m "interface or event" --tb=short =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.4.dev3 - plugins: pep8, cache, xdist + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 4 items test_module.py FFF @@ -480,4 +464,4 @@ > assert 0 E assert 0 ============= 1 tests deselected by "-m 'interface or event'" ============== - ================== 3 failed, 1 deselected in 0.02 seconds ================== + ================== 3 failed, 1 deselected in 0.01 seconds ================== diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/example/nonpython.txt --- a/doc/en/example/nonpython.txt +++ b/doc/en/example/nonpython.txt @@ -27,7 +27,7 @@ nonpython $ py.test test_simple.yml =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items test_simple.yml .F @@ -37,7 +37,7 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.05 seconds ==================== + ==================== 1 failed, 1 passed in 0.10 seconds ==================== You get one dot for the passing ``sub1: sub1`` check and one failure. Obviously in the above ``conftest.py`` you'll want to implement a more @@ -56,7 +56,7 @@ nonpython $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_simple.yml:1: usecase: ok PASSED @@ -67,14 +67,14 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.05 seconds ==================== + ==================== 1 failed, 1 passed in 0.04 seconds ==================== While developing your custom test collection and execution it's also interesting to just look at the collection tree:: nonpython $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/example/parametrize.txt --- a/doc/en/example/parametrize.txt +++ b/doc/en/example/parametrize.txt @@ -104,7 +104,7 @@ $ py.test test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 4 items test_scenarios.py .... @@ -116,7 +116,7 @@ $ py.test --collectonly test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 4 items @@ -180,7 +180,7 @@ $ py.test test_backends.py --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items @@ -195,7 +195,7 @@ ================================= FAILURES ================================= _________________________ test_db_initialized[d2] __________________________ - db = + db = def test_db_initialized(db): # a dummy test @@ -250,7 +250,7 @@ ================================= FAILURES ================================= ________________________ TestClass.test_equals[1-2] ________________________ - self = , a = 1, b = 2 + self = , a = 1, b = 2 def test_equals(self, a, b): > assert a == b diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/example/pythoncollection.txt --- a/doc/en/example/pythoncollection.txt +++ b/doc/en/example/pythoncollection.txt @@ -43,7 +43,7 @@ $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items @@ -82,7 +82,7 @@ . $ py.test --collectonly pythoncollection.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 3 items @@ -91,7 +91,7 @@ - ============================= in 0.01 seconds ============================= + ============================= in 0.00 seconds ============================= customizing test collection to find all .py files --------------------------------------------------------- @@ -135,7 +135,7 @@ $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/example/reportingdemo.txt --- a/doc/en/example/reportingdemo.txt +++ b/doc/en/example/reportingdemo.txt @@ -13,7 +13,7 @@ assertion $ py.test failure_demo.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 39 items failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF @@ -30,7 +30,7 @@ failure_demo.py:15: AssertionError _________________________ TestFailing.test_simple __________________________ - self = + self = def test_simple(self): def f(): @@ -40,13 +40,13 @@ > assert f() == g() E assert 42 == 43 - E + where 42 = () - E + and 43 = () + E + where 42 = () + E + and 43 = () failure_demo.py:28: AssertionError ____________________ TestFailing.test_simple_multiline _____________________ - self = + self = def test_simple_multiline(self): otherfunc_multi( @@ -66,19 +66,19 @@ failure_demo.py:11: AssertionError ___________________________ TestFailing.test_not ___________________________ - self = + self = def test_not(self): def f(): return 42 > assert not f() E assert not 42 - E + where 42 = () + E + where 42 = () failure_demo.py:38: AssertionError _________________ TestSpecialisedExplanations.test_eq_text _________________ - self = + self = def test_eq_text(self): > assert 'spam' == 'eggs' @@ -89,7 +89,7 @@ failure_demo.py:42: AssertionError _____________ TestSpecialisedExplanations.test_eq_similar_text _____________ - self = + self = def test_eq_similar_text(self): > assert 'foo 1 bar' == 'foo 2 bar' @@ -102,7 +102,7 @@ failure_demo.py:45: AssertionError ____________ TestSpecialisedExplanations.test_eq_multiline_text ____________ - self = + self = def test_eq_multiline_text(self): > assert 'foo\nspam\nbar' == 'foo\neggs\nbar' @@ -115,7 +115,7 @@ failure_demo.py:48: AssertionError ______________ TestSpecialisedExplanations.test_eq_long_text _______________ - self = + self = def test_eq_long_text(self): a = '1'*100 + 'a' + '2'*100 @@ -132,7 +132,7 @@ failure_demo.py:53: AssertionError _________ TestSpecialisedExplanations.test_eq_long_text_multiline __________ - self = + self = def test_eq_long_text_multiline(self): a = '1\n'*100 + 'a' + '2\n'*100 @@ -156,7 +156,7 @@ failure_demo.py:58: AssertionError _________________ TestSpecialisedExplanations.test_eq_list _________________ - self = + self = def test_eq_list(self): > assert [0, 1, 2] == [0, 1, 3] @@ -166,7 +166,7 @@ failure_demo.py:61: AssertionError ______________ TestSpecialisedExplanations.test_eq_list_long _______________ - self = + self = def test_eq_list_long(self): a = [0]*100 + [1] + [3]*100 @@ -178,7 +178,7 @@ failure_demo.py:66: AssertionError _________________ TestSpecialisedExplanations.test_eq_dict _________________ - self = + self = def test_eq_dict(self): > assert {'a': 0, 'b': 1} == {'a': 0, 'b': 2} @@ -191,7 +191,7 @@ failure_demo.py:69: AssertionError _________________ TestSpecialisedExplanations.test_eq_set __________________ - self = + self = def test_eq_set(self): > assert set([0, 10, 11, 12]) == set([0, 20, 21]) @@ -207,7 +207,7 @@ failure_demo.py:72: AssertionError _____________ TestSpecialisedExplanations.test_eq_longer_list ______________ - self = + self = def test_eq_longer_list(self): > assert [1,2] == [1,2,3] @@ -217,7 +217,7 @@ failure_demo.py:75: AssertionError _________________ TestSpecialisedExplanations.test_in_list _________________ - self = + self = def test_in_list(self): > assert 1 in [0, 2, 3, 4, 5] @@ -226,7 +226,7 @@ failure_demo.py:78: AssertionError __________ TestSpecialisedExplanations.test_not_in_text_multiline __________ - self = + self = def test_not_in_text_multiline(self): text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail' @@ -244,7 +244,7 @@ failure_demo.py:82: AssertionError ___________ TestSpecialisedExplanations.test_not_in_text_single ____________ - self = + self = def test_not_in_text_single(self): text = 'single foo line' @@ -257,7 +257,7 @@ failure_demo.py:86: AssertionError _________ TestSpecialisedExplanations.test_not_in_text_single_long _________ - self = + self = def test_not_in_text_single_long(self): text = 'head ' * 50 + 'foo ' + 'tail ' * 20 @@ -270,7 +270,7 @@ failure_demo.py:90: AssertionError ______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______ - self = + self = def test_not_in_text_single_long_term(self): text = 'head ' * 50 + 'f'*70 + 'tail ' * 20 @@ -289,7 +289,7 @@ i = Foo() > assert i.b == 2 E assert 1 == 2 - E + where 1 = .b + E + where 1 = .b failure_demo.py:101: AssertionError _________________________ test_attribute_instance __________________________ @@ -299,8 +299,8 @@ b = 1 > assert Foo().b == 2 E assert 1 == 2 - E + where 1 = .b - E + where = () + E + where 1 = .b + E + where = () failure_demo.py:107: AssertionError __________________________ test_attribute_failure __________________________ @@ -316,7 +316,7 @@ failure_demo.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - self = + self = def _get_b(self): > raise Exception('Failed to get attrib') @@ -332,15 +332,15 @@ b = 2 > assert Foo().b == Bar().b E assert 1 == 2 - E + where 1 = .b - E + where = () - E + and 2 = .b - E + where = () + E + where 1 = .b + E + where = () + E + and 2 = .b + E + where = () failure_demo.py:124: AssertionError __________________________ TestRaises.test_raises __________________________ - self = + self = def test_raises(self): s = 'qwe' @@ -355,7 +355,7 @@ <0-codegen /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:851>:1: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ - self = + self = def test_raises_doesnt(self): > raises(IOError, "int('3')") @@ -364,7 +364,7 @@ failure_demo.py:136: Failed __________________________ TestRaises.test_raise ___________________________ - self = + self = def test_raise(self): > raise ValueError("demo error") @@ -373,7 +373,7 @@ failure_demo.py:139: ValueError ________________________ TestRaises.test_tupleerror ________________________ - self = + self = def test_tupleerror(self): > a,b = [1] @@ -382,7 +382,7 @@ failure_demo.py:142: ValueError ______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______ - self = + self = def test_reinterpret_fails_with_print_for_the_fun_of_it(self): l = [1,2,3] @@ -395,7 +395,7 @@ l is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ - self = + self = def test_some_error(self): > if namenotexi: @@ -423,7 +423,7 @@ <2-codegen 'abc-123' /home/hpk/p/pytest/doc/en/example/assertion/failure_demo.py:162>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ - self = + self = def test_complex_error(self): def f(): @@ -452,7 +452,7 @@ failure_demo.py:5: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ - self = + self = def test_z1_unpack_error(self): l = [] @@ -462,7 +462,7 @@ failure_demo.py:179: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ - self = + self = def test_z2_type_error(self): l = 3 @@ -472,19 +472,19 @@ failure_demo.py:183: TypeError ______________________ TestMoreErrors.test_startswith ______________________ - self = + self = def test_startswith(self): s = "123" g = "456" > assert s.startswith(g) - E assert ('456') - E + where = '123'.startswith + E assert ('456') + E + where = '123'.startswith failure_demo.py:188: AssertionError __________________ TestMoreErrors.test_startswith_nested ___________________ - self = + self = def test_startswith_nested(self): def f(): @@ -492,15 +492,15 @@ def g(): return "456" > assert f().startswith(g()) - E assert ('456') - E + where = '123'.startswith - E + where '123' = () - E + and '456' = () + E assert ('456') + E + where = '123'.startswith + E + where '123' = () + E + and '456' = () failure_demo.py:195: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ - self = + self = def test_global_func(self): > assert isinstance(globf(42), float) @@ -510,18 +510,18 @@ failure_demo.py:198: AssertionError _______________________ TestMoreErrors.test_instance _______________________ - self = + self = def test_instance(self): self.x = 6*7 > assert self.x != 42 E assert 42 != 42 - E + where 42 = .x + E + where 42 = .x failure_demo.py:202: AssertionError _______________________ TestMoreErrors.test_compare ________________________ - self = + self = def test_compare(self): > assert globf(10) < 5 @@ -531,7 +531,7 @@ failure_demo.py:205: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ - self = + self = def test_try_finally(self): x = 1 diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -106,7 +106,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 0 items ============================= in 0.00 seconds ============================= @@ -150,12 +150,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-4/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-74/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -163,7 +163,7 @@ $ py.test --runslow =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items test_module.py .. @@ -253,7 +253,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 project deps: mylib-1.1 collected 0 items @@ -276,7 +276,7 @@ $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/venv/regen/bin/python2.7 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python info1: did you know that ... did you? collecting ... collected 0 items @@ -287,7 +287,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 0 items ============================= in 0.00 seconds ============================= @@ -319,7 +319,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 3 items test_some_are_slow.py ... @@ -380,7 +380,7 @@ $ py.test -rx =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 4 items test_step.py .Fx. @@ -388,7 +388,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -398,7 +398,7 @@ ========================= short test summary info ========================== XFAIL test_step.py::TestUserHandling::()::test_deletion reason: previous test failed (test_modification) - ============== 1 failed, 2 passed, 1 xfailed in 0.02 seconds =============== + ============== 1 failed, 2 passed, 1 xfailed in 0.01 seconds =============== We'll see that ``test_deletion`` was not executed because ``test_modification`` failed. It is reported as an "expected failure". @@ -450,7 +450,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 7 items test_step.py .Fx. @@ -460,17 +460,17 @@ ================================== ERRORS ================================== _______________________ ERROR at setup of test_root ________________________ - file /tmp/doc-exec-4/b/test_error.py, line 1 + file /tmp/doc-exec-74/b/test_error.py, line 1 def test_root(db): # no db here, will error out fixture 'db' not found available fixtures: pytestconfig, recwarn, monkeypatch, capfd, capsys, tmpdir use 'py.test --fixtures [testpath]' for help on them. - /tmp/doc-exec-4/b/test_error.py:1 + /tmp/doc-exec-74/b/test_error.py:1 ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -479,20 +479,20 @@ test_step.py:9: AssertionError _________________________________ test_a1 __________________________________ - db = + db = def test_a1(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db.py:2: AssertionError _________________________________ test_a2 __________________________________ - db = + db = def test_a2(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db2.py:2: AssertionError ========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.03 seconds ========== @@ -550,7 +550,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items test_module.py FF @@ -558,7 +558,7 @@ ================================= FAILURES ================================= ________________________________ test_fail1 ________________________________ - tmpdir = local('/tmp/pytest-6/test_fail10') + tmpdir = local('/tmp/pytest-376/test_fail10') def test_fail1(tmpdir): > assert 0 @@ -572,12 +572,12 @@ E assert 0 test_module.py:4: AssertionError - ========================= 2 failed in 0.01 seconds ========================= + ========================= 2 failed in 0.02 seconds ========================= you will have a "failures" file which contains the failing test ids:: $ cat failures - test_module.py::test_fail1 (/tmp/pytest-6/test_fail10) + test_module.py::test_fail1 (/tmp/pytest-376/test_fail10) test_module.py::test_fail2 Making test result information available in fixtures @@ -640,7 +640,7 @@ $ py.test -s test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 3 items test_module.py EFF @@ -675,7 +675,6 @@ setting up a test failed! test_module.py::test_setup_fails executing test failed test_module.py::test_call_fails - You'll see that the fixture finalizers could use the precise reporting information. diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -71,7 +71,7 @@ $ py.test test_smtpsimple.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items test_smtpsimple.py F @@ -79,7 +79,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response, msg = smtp.ehlo() @@ -89,7 +89,7 @@ E assert 0 test_smtpsimple.py:12: AssertionError - ========================= 1 failed in 0.26 seconds ========================= + ========================= 1 failed in 0.23 seconds ========================= In the failure traceback we see that the test function was called with a ``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture @@ -189,7 +189,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items test_module.py FF @@ -197,7 +197,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -209,7 +209,7 @@ test_module.py:6: AssertionError ________________________________ test_noop _________________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -218,7 +218,7 @@ E assert 0 test_module.py:11: AssertionError - ========================= 2 failed in 0.22 seconds ========================= + ========================= 2 failed in 0.19 seconds ========================= You see the two ``assert 0`` failing and more importantly you can also see that the same (module-scoped) ``smtp`` object was passed into the two @@ -271,7 +271,7 @@ $ py.test -s -q --tb=no FF - finalizing + finalizing We see that the ``smtp`` instance is finalized after the two tests using it tests executed. If we had specified ``scope='function'`` @@ -342,7 +342,7 @@ ================================= FAILURES ================================= __________________________ test_ehlo[merlinux.eu] __________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -354,7 +354,7 @@ test_module.py:6: AssertionError __________________________ test_noop[merlinux.eu] __________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -365,7 +365,7 @@ test_module.py:11: AssertionError ________________________ test_ehlo[mail.python.org] ________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -376,7 +376,7 @@ test_module.py:5: AssertionError ________________________ test_noop[mail.python.org] ________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -424,13 +424,13 @@ $ py.test -v test_appsetup.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_appsetup.py:12: test_smtp_exists[merlinux.eu] PASSED test_appsetup.py:12: test_smtp_exists[mail.python.org] PASSED - ========================= 2 passed in 6.43 seconds ========================= + ========================= 2 passed in 5.82 seconds ========================= Due to the parametrization of ``smtp`` the test will run twice with two different ``App`` instances and respective smtp servers. There is no @@ -489,7 +489,7 @@ $ py.test -v -s test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 8 items test_module.py:16: test_0[1] PASSED diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/getting-started.txt --- a/doc/en/getting-started.txt +++ b/doc/en/getting-started.txt @@ -23,7 +23,7 @@ To check your installation has installed the correct version:: $ py.test --version - This is py.test version 2.3.3, imported from /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/pytest.pyc + This is py.test version 2.4.6, imported from /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/pytest.pyc If you get an error checkout :ref:`installation issues`. @@ -45,7 +45,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items test_sample.py F @@ -122,7 +122,7 @@ ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - self = + self = def test_two(self): x = "hello" @@ -157,7 +157,7 @@ ================================= FAILURES ================================= _____________________________ test_needsfiles ______________________________ - tmpdir = local('/tmp/pytest-780/test_needsfiles0') + tmpdir = local('/tmp/pytest-372/test_needsfiles0') def test_needsfiles(tmpdir): print tmpdir @@ -166,7 +166,7 @@ test_tmpdir.py:3: AssertionError ----------------------------- Captured stdout ------------------------------ - /tmp/pytest-780/test_needsfiles0 + /tmp/pytest-372/test_needsfiles0 Before the test runs, a unique-per-test-invocation temporary directory was created. More info at :ref:`tmpdir handling`. diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/parametrize.txt --- a/doc/en/parametrize.txt +++ b/doc/en/parametrize.txt @@ -53,7 +53,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 3 items test_expectation.py ..F @@ -135,8 +135,8 @@ def test_valid_string(stringinput): > assert stringinput.isalpha() - E assert () - E + where = '!'.isalpha + E assert () + E + where = '!'.isalpha test_strings.py:3: AssertionError @@ -149,7 +149,7 @@ $ py.test -q -rs test_strings.py s ========================= short test summary info ========================== - SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:960: got empty parameter set, function test_valid_string at /tmp/doc-exec-103/test_strings.py:1 + SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:962: got empty parameter set, function test_valid_string at /tmp/doc-exec-36/test_strings.py:1 For further examples, you might want to look at :ref:`more parametrization examples `. diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -132,7 +132,7 @@ example $ py.test -rx xfail_demo.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 6 items xfail_demo.py xxxxxx diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/tmpdir.txt --- a/doc/en/tmpdir.txt +++ b/doc/en/tmpdir.txt @@ -29,7 +29,7 @@ $ py.test test_tmpdir.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 1 items test_tmpdir.py F @@ -37,7 +37,7 @@ ================================= FAILURES ================================= _____________________________ test_create_file _____________________________ - tmpdir = local('/tmp/pytest-781/test_create_file0') + tmpdir = local('/tmp/pytest-373/test_create_file0') def test_create_file(tmpdir): p = tmpdir.mkdir("sub").join("hello.txt") @@ -48,7 +48,7 @@ E assert 0 test_tmpdir.py:7: AssertionError - ========================= 1 failed in 0.04 seconds ========================= + ========================= 1 failed in 0.02 seconds ========================= .. _`base temporary directory`: diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 doc/en/unittest.txt --- a/doc/en/unittest.txt +++ b/doc/en/unittest.txt @@ -88,7 +88,7 @@ $ py.test test_unittest_db.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.3.3 + platform linux2 -- Python 2.7.3 -- pytest-2.4.6 collected 2 items test_unittest_db.py FF @@ -101,7 +101,7 @@ def test_method1(self): assert hasattr(self, "db") > assert 0, self.db # fail for demo purposes - E AssertionError: + E AssertionError: test_unittest_db.py:9: AssertionError ___________________________ MyTest.test_method2 ____________________________ @@ -110,7 +110,7 @@ def test_method2(self): > assert 0, self.db # fail for demo purposes - E AssertionError: + E AssertionError: test_unittest_db.py:12: AssertionError ========================= 2 failed in 0.02 seconds ========================= diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.4.dev6', + version='2.4.6', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 9f461741482eec7b4ab41c06cf50b07008d70169 -r 048679527ddceceae072f7df48a170b40a3ba918 tox.ini --- a/tox.ini +++ b/tox.ini @@ -68,7 +68,7 @@ :pypi:PyYAML commands= rm -rf /tmp/doc-exec* - pip install pytest==2.3.3 + #pip install pytest==2.3.4 make regen [testenv:py31] Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 20 14:08:24 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Nov 2012 13:08:24 -0000 Subject: [py-svn] commit/pytest: hpk42: fix version number, final fixes Message-ID: <20121120130824.6995.71692@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/ef299e57f242/ changeset: ef299e57f242 user: hpk42 date: 2012-11-20 14:01:31 summary: fix version number, final fixes affected #: 19 files diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.6' +__version__ = '2.3.4' diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/Makefile --- a/doc/en/Makefile +++ b/doc/en/Makefile @@ -12,7 +12,7 @@ PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -SITETARGET=dev +SITETARGET=latest .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/announce/release-2.3.4.txt --- a/doc/en/announce/release-2.3.4.txt +++ b/doc/en/announce/release-2.3.4.txt @@ -3,8 +3,8 @@ pytest-2.3.4 is a small stabilization release of the py.test tool which offers uebersimple assertions, scalable fixture mechanisms -and deep customization for testing with Python. The Particularly, -this release provides: +and deep customization for testing with Python. This release +comes with the following fixes and features: - make "-k" option accept an expressions the same as with "-m" so that one can write: -k "name1 or name2" etc. This is a slight usage incompatibility @@ -24,7 +24,7 @@ - fix issue91 - add/discuss package/directory level setups in example - fixes related to autouse discovery and calling -Thanks to Thomas Waldmann in particular for spotting autouse issues. +Thanks in particular to Thomas Waldmann for spotting and reporting issues. See diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/assert.txt --- a/doc/en/assert.txt +++ b/doc/en/assert.txt @@ -26,7 +26,7 @@ $ py.test test_assert1.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items test_assert1.py F @@ -110,7 +110,7 @@ $ py.test test_assert2.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items test_assert2.py F diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/capture.txt --- a/doc/en/capture.txt +++ b/doc/en/capture.txt @@ -64,7 +64,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items test_module.py .F @@ -78,7 +78,7 @@ test_module.py:9: AssertionError ----------------------------- Captured stdout ------------------------------ - setting up + setting up ==================== 1 failed, 1 passed in 0.01 seconds ==================== Accessing captured output from a test function diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/doctest.txt --- a/doc/en/doctest.txt +++ b/doc/en/doctest.txt @@ -44,7 +44,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items mymodule.py . diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/example/markers.txt --- a/doc/en/example/markers.txt +++ b/doc/en/example/markers.txt @@ -28,7 +28,7 @@ $ py.test -v -m webtest =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED @@ -40,7 +40,7 @@ $ py.test -v -m "not webtest" =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:6: test_something_quick PASSED @@ -61,7 +61,7 @@ $ py.test -v -k http # running with the above defined example module =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED @@ -73,7 +73,7 @@ $ py.test -k "not send_http" -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:6: test_something_quick PASSED @@ -86,7 +86,7 @@ $ py.test -k "http or quick" -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 3 items test_server.py:3: test_send_http PASSED @@ -232,7 +232,7 @@ $ py.test -E stage2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items test_someenv.py s @@ -243,7 +243,7 @@ $ py.test -E stage1 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items test_someenv.py . @@ -360,12 +360,12 @@ $ py.test -rs # this option reports skip reasons =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 4 items test_plat.py s.s. ========================= short test summary info ========================== - SKIP [2] /tmp/doc-exec-69/conftest.py:12: cannot run on platform linux2 + SKIP [2] /tmp/doc-exec-133/conftest.py:12: cannot run on platform linux2 =================== 2 passed, 2 skipped in 0.01 seconds ==================== @@ -373,7 +373,7 @@ $ py.test -m linux2 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 4 items test_plat.py . @@ -424,7 +424,7 @@ $ py.test -m interface --tb=short =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 4 items test_module.py FF @@ -445,7 +445,7 @@ $ py.test -m "interface or event" --tb=short =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 4 items test_module.py FFF @@ -464,4 +464,4 @@ > assert 0 E assert 0 ============= 1 tests deselected by "-m 'interface or event'" ============== - ================== 3 failed, 1 deselected in 0.01 seconds ================== + ================== 3 failed, 1 deselected in 0.02 seconds ================== diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/example/nonpython.txt --- a/doc/en/example/nonpython.txt +++ b/doc/en/example/nonpython.txt @@ -27,7 +27,7 @@ nonpython $ py.test test_simple.yml =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items test_simple.yml .F @@ -37,7 +37,7 @@ usecase execution failed spec failed: 'some': 'other' no further details known at this point. - ==================== 1 failed, 1 passed in 0.10 seconds ==================== + ==================== 1 failed, 1 passed in 0.09 seconds ==================== You get one dot for the passing ``sub1: sub1`` check and one failure. Obviously in the above ``conftest.py`` you'll want to implement a more @@ -56,7 +56,7 @@ nonpython $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_simple.yml:1: usecase: ok PASSED @@ -74,7 +74,7 @@ nonpython $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/example/parametrize.txt --- a/doc/en/example/parametrize.txt +++ b/doc/en/example/parametrize.txt @@ -104,7 +104,7 @@ $ py.test test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 4 items test_scenarios.py .... @@ -116,7 +116,7 @@ $ py.test --collectonly test_scenarios.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 4 items @@ -180,7 +180,7 @@ $ py.test test_backends.py --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items @@ -195,7 +195,7 @@ ================================= FAILURES ================================= _________________________ test_db_initialized[d2] __________________________ - db = + db = def test_db_initialized(db): # a dummy test @@ -250,7 +250,7 @@ ================================= FAILURES ================================= ________________________ TestClass.test_equals[1-2] ________________________ - self = , a = 1, b = 2 + self = , a = 1, b = 2 def test_equals(self, a, b): > assert a == b diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/example/pythoncollection.txt --- a/doc/en/example/pythoncollection.txt +++ b/doc/en/example/pythoncollection.txt @@ -43,7 +43,7 @@ $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items @@ -82,7 +82,7 @@ . $ py.test --collectonly pythoncollection.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 3 items @@ -91,7 +91,7 @@ - ============================= in 0.00 seconds ============================= + ============================= in 0.01 seconds ============================= customizing test collection to find all .py files --------------------------------------------------------- @@ -135,7 +135,7 @@ $ py.test --collectonly =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/example/reportingdemo.txt --- a/doc/en/example/reportingdemo.txt +++ b/doc/en/example/reportingdemo.txt @@ -13,7 +13,7 @@ assertion $ py.test failure_demo.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 39 items failure_demo.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF @@ -30,7 +30,7 @@ failure_demo.py:15: AssertionError _________________________ TestFailing.test_simple __________________________ - self = + self = def test_simple(self): def f(): @@ -40,13 +40,13 @@ > assert f() == g() E assert 42 == 43 - E + where 42 = () - E + and 43 = () + E + where 42 = () + E + and 43 = () failure_demo.py:28: AssertionError ____________________ TestFailing.test_simple_multiline _____________________ - self = + self = def test_simple_multiline(self): otherfunc_multi( @@ -66,19 +66,19 @@ failure_demo.py:11: AssertionError ___________________________ TestFailing.test_not ___________________________ - self = + self = def test_not(self): def f(): return 42 > assert not f() E assert not 42 - E + where 42 = () + E + where 42 = () failure_demo.py:38: AssertionError _________________ TestSpecialisedExplanations.test_eq_text _________________ - self = + self = def test_eq_text(self): > assert 'spam' == 'eggs' @@ -89,7 +89,7 @@ failure_demo.py:42: AssertionError _____________ TestSpecialisedExplanations.test_eq_similar_text _____________ - self = + self = def test_eq_similar_text(self): > assert 'foo 1 bar' == 'foo 2 bar' @@ -102,7 +102,7 @@ failure_demo.py:45: AssertionError ____________ TestSpecialisedExplanations.test_eq_multiline_text ____________ - self = + self = def test_eq_multiline_text(self): > assert 'foo\nspam\nbar' == 'foo\neggs\nbar' @@ -115,7 +115,7 @@ failure_demo.py:48: AssertionError ______________ TestSpecialisedExplanations.test_eq_long_text _______________ - self = + self = def test_eq_long_text(self): a = '1'*100 + 'a' + '2'*100 @@ -132,7 +132,7 @@ failure_demo.py:53: AssertionError _________ TestSpecialisedExplanations.test_eq_long_text_multiline __________ - self = + self = def test_eq_long_text_multiline(self): a = '1\n'*100 + 'a' + '2\n'*100 @@ -156,7 +156,7 @@ failure_demo.py:58: AssertionError _________________ TestSpecialisedExplanations.test_eq_list _________________ - self = + self = def test_eq_list(self): > assert [0, 1, 2] == [0, 1, 3] @@ -166,7 +166,7 @@ failure_demo.py:61: AssertionError ______________ TestSpecialisedExplanations.test_eq_list_long _______________ - self = + self = def test_eq_list_long(self): a = [0]*100 + [1] + [3]*100 @@ -178,7 +178,7 @@ failure_demo.py:66: AssertionError _________________ TestSpecialisedExplanations.test_eq_dict _________________ - self = + self = def test_eq_dict(self): > assert {'a': 0, 'b': 1} == {'a': 0, 'b': 2} @@ -191,7 +191,7 @@ failure_demo.py:69: AssertionError _________________ TestSpecialisedExplanations.test_eq_set __________________ - self = + self = def test_eq_set(self): > assert set([0, 10, 11, 12]) == set([0, 20, 21]) @@ -207,7 +207,7 @@ failure_demo.py:72: AssertionError _____________ TestSpecialisedExplanations.test_eq_longer_list ______________ - self = + self = def test_eq_longer_list(self): > assert [1,2] == [1,2,3] @@ -217,7 +217,7 @@ failure_demo.py:75: AssertionError _________________ TestSpecialisedExplanations.test_in_list _________________ - self = + self = def test_in_list(self): > assert 1 in [0, 2, 3, 4, 5] @@ -226,7 +226,7 @@ failure_demo.py:78: AssertionError __________ TestSpecialisedExplanations.test_not_in_text_multiline __________ - self = + self = def test_not_in_text_multiline(self): text = 'some multiline\ntext\nwhich\nincludes foo\nand a\ntail' @@ -244,7 +244,7 @@ failure_demo.py:82: AssertionError ___________ TestSpecialisedExplanations.test_not_in_text_single ____________ - self = + self = def test_not_in_text_single(self): text = 'single foo line' @@ -257,7 +257,7 @@ failure_demo.py:86: AssertionError _________ TestSpecialisedExplanations.test_not_in_text_single_long _________ - self = + self = def test_not_in_text_single_long(self): text = 'head ' * 50 + 'foo ' + 'tail ' * 20 @@ -270,7 +270,7 @@ failure_demo.py:90: AssertionError ______ TestSpecialisedExplanations.test_not_in_text_single_long_term _______ - self = + self = def test_not_in_text_single_long_term(self): text = 'head ' * 50 + 'f'*70 + 'tail ' * 20 @@ -289,7 +289,7 @@ i = Foo() > assert i.b == 2 E assert 1 == 2 - E + where 1 = .b + E + where 1 = .b failure_demo.py:101: AssertionError _________________________ test_attribute_instance __________________________ @@ -299,8 +299,8 @@ b = 1 > assert Foo().b == 2 E assert 1 == 2 - E + where 1 = .b - E + where = () + E + where 1 = .b + E + where = () failure_demo.py:107: AssertionError __________________________ test_attribute_failure __________________________ @@ -316,7 +316,7 @@ failure_demo.py:116: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - self = + self = def _get_b(self): > raise Exception('Failed to get attrib') @@ -332,15 +332,15 @@ b = 2 > assert Foo().b == Bar().b E assert 1 == 2 - E + where 1 = .b - E + where = () - E + and 2 = .b - E + where = () + E + where 1 = .b + E + where = () + E + and 2 = .b + E + where = () failure_demo.py:124: AssertionError __________________________ TestRaises.test_raises __________________________ - self = + self = def test_raises(self): s = 'qwe' @@ -355,7 +355,7 @@ <0-codegen /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:851>:1: ValueError ______________________ TestRaises.test_raises_doesnt _______________________ - self = + self = def test_raises_doesnt(self): > raises(IOError, "int('3')") @@ -364,7 +364,7 @@ failure_demo.py:136: Failed __________________________ TestRaises.test_raise ___________________________ - self = + self = def test_raise(self): > raise ValueError("demo error") @@ -373,7 +373,7 @@ failure_demo.py:139: ValueError ________________________ TestRaises.test_tupleerror ________________________ - self = + self = def test_tupleerror(self): > a,b = [1] @@ -382,7 +382,7 @@ failure_demo.py:142: ValueError ______ TestRaises.test_reinterpret_fails_with_print_for_the_fun_of_it ______ - self = + self = def test_reinterpret_fails_with_print_for_the_fun_of_it(self): l = [1,2,3] @@ -395,7 +395,7 @@ l is [1, 2, 3] ________________________ TestRaises.test_some_error ________________________ - self = + self = def test_some_error(self): > if namenotexi: @@ -423,7 +423,7 @@ <2-codegen 'abc-123' /home/hpk/p/pytest/doc/en/example/assertion/failure_demo.py:162>:2: AssertionError ____________________ TestMoreErrors.test_complex_error _____________________ - self = + self = def test_complex_error(self): def f(): @@ -452,7 +452,7 @@ failure_demo.py:5: AssertionError ___________________ TestMoreErrors.test_z1_unpack_error ____________________ - self = + self = def test_z1_unpack_error(self): l = [] @@ -462,7 +462,7 @@ failure_demo.py:179: ValueError ____________________ TestMoreErrors.test_z2_type_error _____________________ - self = + self = def test_z2_type_error(self): l = 3 @@ -472,19 +472,19 @@ failure_demo.py:183: TypeError ______________________ TestMoreErrors.test_startswith ______________________ - self = + self = def test_startswith(self): s = "123" g = "456" > assert s.startswith(g) - E assert ('456') - E + where = '123'.startswith + E assert ('456') + E + where = '123'.startswith failure_demo.py:188: AssertionError __________________ TestMoreErrors.test_startswith_nested ___________________ - self = + self = def test_startswith_nested(self): def f(): @@ -492,15 +492,15 @@ def g(): return "456" > assert f().startswith(g()) - E assert ('456') - E + where = '123'.startswith - E + where '123' = () - E + and '456' = () + E assert ('456') + E + where = '123'.startswith + E + where '123' = () + E + and '456' = () failure_demo.py:195: AssertionError _____________________ TestMoreErrors.test_global_func ______________________ - self = + self = def test_global_func(self): > assert isinstance(globf(42), float) @@ -510,18 +510,18 @@ failure_demo.py:198: AssertionError _______________________ TestMoreErrors.test_instance _______________________ - self = + self = def test_instance(self): self.x = 6*7 > assert self.x != 42 E assert 42 != 42 - E + where 42 = .x + E + where 42 = .x failure_demo.py:202: AssertionError _______________________ TestMoreErrors.test_compare ________________________ - self = + self = def test_compare(self): > assert globf(10) < 5 @@ -531,7 +531,7 @@ failure_demo.py:205: AssertionError _____________________ TestMoreErrors.test_try_finally ______________________ - self = + self = def test_try_finally(self): x = 1 @@ -540,4 +540,4 @@ E assert 1 == 0 failure_demo.py:210: AssertionError - ======================== 39 failed in 0.23 seconds ========================= + ======================== 39 failed in 0.25 seconds ========================= diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/example/simple.txt --- a/doc/en/example/simple.txt +++ b/doc/en/example/simple.txt @@ -106,7 +106,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 0 items ============================= in 0.00 seconds ============================= @@ -150,12 +150,12 @@ $ py.test -rs # "-rs" means report details on the little 's' =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items test_module.py .s ========================= short test summary info ========================== - SKIP [1] /tmp/doc-exec-74/conftest.py:9: need --runslow option to run + SKIP [1] /tmp/doc-exec-138/conftest.py:9: need --runslow option to run =================== 1 passed, 1 skipped in 0.01 seconds ==================== @@ -163,7 +163,7 @@ $ py.test --runslow =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items test_module.py .. @@ -253,7 +253,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 project deps: mylib-1.1 collected 0 items @@ -276,7 +276,7 @@ $ py.test -v =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python info1: did you know that ... did you? collecting ... collected 0 items @@ -287,7 +287,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 0 items ============================= in 0.00 seconds ============================= @@ -319,7 +319,7 @@ $ py.test --durations=3 =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 3 items test_some_are_slow.py ... @@ -380,7 +380,7 @@ $ py.test -rx =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 4 items test_step.py .Fx. @@ -388,7 +388,7 @@ ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -398,7 +398,7 @@ ========================= short test summary info ========================== XFAIL test_step.py::TestUserHandling::()::test_deletion reason: previous test failed (test_modification) - ============== 1 failed, 2 passed, 1 xfailed in 0.01 seconds =============== + ============== 1 failed, 2 passed, 1 xfailed in 0.02 seconds =============== We'll see that ``test_deletion`` was not executed because ``test_modification`` failed. It is reported as an "expected failure". @@ -450,7 +450,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 7 items test_step.py .Fx. @@ -460,17 +460,17 @@ ================================== ERRORS ================================== _______________________ ERROR at setup of test_root ________________________ - file /tmp/doc-exec-74/b/test_error.py, line 1 + file /tmp/doc-exec-138/b/test_error.py, line 1 def test_root(db): # no db here, will error out fixture 'db' not found available fixtures: pytestconfig, recwarn, monkeypatch, capfd, capsys, tmpdir use 'py.test --fixtures [testpath]' for help on them. - /tmp/doc-exec-74/b/test_error.py:1 + /tmp/doc-exec-138/b/test_error.py:1 ================================= FAILURES ================================= ____________________ TestUserHandling.test_modification ____________________ - self = + self = def test_modification(self): > assert 0 @@ -479,23 +479,23 @@ test_step.py:9: AssertionError _________________________________ test_a1 __________________________________ - db = + db = def test_a1(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db.py:2: AssertionError _________________________________ test_a2 __________________________________ - db = + db = def test_a2(db): > assert 0, db # to show value - E AssertionError: + E AssertionError: a/test_db2.py:2: AssertionError - ========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.03 seconds ========== + ========== 3 failed, 2 passed, 1 xfailed, 1 error in 0.04 seconds ========== The two test modules in the ``a`` directory see the same ``db`` fixture instance while the one test in the sister-directory ``b`` doesn't see it. We could of course @@ -550,7 +550,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items test_module.py FF @@ -558,7 +558,7 @@ ================================= FAILURES ================================= ________________________________ test_fail1 ________________________________ - tmpdir = local('/tmp/pytest-376/test_fail10') + tmpdir = local('/tmp/pytest-543/test_fail10') def test_fail1(tmpdir): > assert 0 @@ -577,7 +577,7 @@ you will have a "failures" file which contains the failing test ids:: $ cat failures - test_module.py::test_fail1 (/tmp/pytest-376/test_fail10) + test_module.py::test_fail1 (/tmp/pytest-543/test_fail10) test_module.py::test_fail2 Making test result information available in fixtures @@ -640,7 +640,7 @@ $ py.test -s test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 3 items test_module.py EFF diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/fixture.txt --- a/doc/en/fixture.txt +++ b/doc/en/fixture.txt @@ -71,7 +71,7 @@ $ py.test test_smtpsimple.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items test_smtpsimple.py F @@ -79,7 +79,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response, msg = smtp.ehlo() @@ -89,7 +89,7 @@ E assert 0 test_smtpsimple.py:12: AssertionError - ========================= 1 failed in 0.23 seconds ========================= + ========================= 1 failed in 0.17 seconds ========================= In the failure traceback we see that the test function was called with a ``smtp`` argument, the ``smtplib.SMTP()`` instance created by the fixture @@ -189,7 +189,7 @@ $ py.test test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items test_module.py FF @@ -197,7 +197,7 @@ ================================= FAILURES ================================= ________________________________ test_ehlo _________________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -209,7 +209,7 @@ test_module.py:6: AssertionError ________________________________ test_noop _________________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -218,7 +218,7 @@ E assert 0 test_module.py:11: AssertionError - ========================= 2 failed in 0.19 seconds ========================= + ========================= 2 failed in 0.23 seconds ========================= You see the two ``assert 0`` failing and more importantly you can also see that the same (module-scoped) ``smtp`` object was passed into the two @@ -271,7 +271,7 @@ $ py.test -s -q --tb=no FF - finalizing + finalizing We see that the ``smtp`` instance is finalized after the two tests using it tests executed. If we had specified ``scope='function'`` @@ -342,7 +342,7 @@ ================================= FAILURES ================================= __________________________ test_ehlo[merlinux.eu] __________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -354,7 +354,7 @@ test_module.py:6: AssertionError __________________________ test_noop[merlinux.eu] __________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -365,7 +365,7 @@ test_module.py:11: AssertionError ________________________ test_ehlo[mail.python.org] ________________________ - smtp = + smtp = def test_ehlo(smtp): response = smtp.ehlo() @@ -376,7 +376,7 @@ test_module.py:5: AssertionError ________________________ test_noop[mail.python.org] ________________________ - smtp = + smtp = def test_noop(smtp): response = smtp.noop() @@ -424,13 +424,13 @@ $ py.test -v test_appsetup.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 2 items test_appsetup.py:12: test_smtp_exists[merlinux.eu] PASSED test_appsetup.py:12: test_smtp_exists[mail.python.org] PASSED - ========================= 2 passed in 5.82 seconds ========================= + ========================= 2 passed in 5.95 seconds ========================= Due to the parametrization of ``smtp`` the test will run twice with two different ``App`` instances and respective smtp servers. There is no @@ -489,7 +489,7 @@ $ py.test -v -s test_module.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 -- /home/hpk/p/pytest/.tox/regen/bin/python + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 -- /home/hpk/p/pytest/.tox/regen/bin/python collecting ... collected 8 items test_module.py:16: test_0[1] PASSED diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/getting-started.txt --- a/doc/en/getting-started.txt +++ b/doc/en/getting-started.txt @@ -23,7 +23,7 @@ To check your installation has installed the correct version:: $ py.test --version - This is py.test version 2.4.6, imported from /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/pytest.pyc + This is py.test version 2.3.4, imported from /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/pytest.pyc If you get an error checkout :ref:`installation issues`. @@ -45,7 +45,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items test_sample.py F @@ -122,7 +122,7 @@ ================================= FAILURES ================================= ____________________________ TestClass.test_two ____________________________ - self = + self = def test_two(self): x = "hello" @@ -157,7 +157,7 @@ ================================= FAILURES ================================= _____________________________ test_needsfiles ______________________________ - tmpdir = local('/tmp/pytest-372/test_needsfiles0') + tmpdir = local('/tmp/pytest-539/test_needsfiles0') def test_needsfiles(tmpdir): print tmpdir @@ -166,7 +166,7 @@ test_tmpdir.py:3: AssertionError ----------------------------- Captured stdout ------------------------------ - /tmp/pytest-372/test_needsfiles0 + /tmp/pytest-539/test_needsfiles0 Before the test runs, a unique-per-test-invocation temporary directory was created. More info at :ref:`tmpdir handling`. diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/parametrize.txt --- a/doc/en/parametrize.txt +++ b/doc/en/parametrize.txt @@ -53,7 +53,7 @@ $ py.test =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 3 items test_expectation.py ..F @@ -135,8 +135,8 @@ def test_valid_string(stringinput): > assert stringinput.isalpha() - E assert () - E + where = '!'.isalpha + E assert () + E + where = '!'.isalpha test_strings.py:3: AssertionError @@ -149,7 +149,7 @@ $ py.test -q -rs test_strings.py s ========================= short test summary info ========================== - SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:962: got empty parameter set, function test_valid_string at /tmp/doc-exec-36/test_strings.py:1 + SKIP [1] /home/hpk/p/pytest/.tox/regen/lib/python2.7/site-packages/_pytest/python.py:962: got empty parameter set, function test_valid_string at /tmp/doc-exec-101/test_strings.py:1 For further examples, you might want to look at :ref:`more parametrization examples `. diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/skipping.txt --- a/doc/en/skipping.txt +++ b/doc/en/skipping.txt @@ -132,7 +132,7 @@ example $ py.test -rx xfail_demo.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 6 items xfail_demo.py xxxxxx diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/tmpdir.txt --- a/doc/en/tmpdir.txt +++ b/doc/en/tmpdir.txt @@ -29,7 +29,7 @@ $ py.test test_tmpdir.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 1 items test_tmpdir.py F @@ -37,7 +37,7 @@ ================================= FAILURES ================================= _____________________________ test_create_file _____________________________ - tmpdir = local('/tmp/pytest-373/test_create_file0') + tmpdir = local('/tmp/pytest-540/test_create_file0') def test_create_file(tmpdir): p = tmpdir.mkdir("sub").join("hello.txt") diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 doc/en/unittest.txt --- a/doc/en/unittest.txt +++ b/doc/en/unittest.txt @@ -88,7 +88,7 @@ $ py.test test_unittest_db.py =========================== test session starts ============================ - platform linux2 -- Python 2.7.3 -- pytest-2.4.6 + platform linux2 -- Python 2.7.3 -- pytest-2.3.4 collected 2 items test_unittest_db.py FF @@ -101,7 +101,7 @@ def test_method1(self): assert hasattr(self, "db") > assert 0, self.db # fail for demo purposes - E AssertionError: + E AssertionError: test_unittest_db.py:9: AssertionError ___________________________ MyTest.test_method2 ____________________________ @@ -110,7 +110,7 @@ def test_method2(self): > assert 0, self.db # fail for demo purposes - E AssertionError: + E AssertionError: test_unittest_db.py:12: AssertionError ========================= 2 failed in 0.02 seconds ========================= diff -r 048679527ddceceae072f7df48a170b40a3ba918 -r ef299e57f24218dbdd949498d7e660723636bcc3 setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.6', + version='2.3.4', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 20 14:10:07 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Nov 2012 13:10:07 -0000 Subject: [py-svn] commit/pytest: hpk42: Added tag 2.3.4 for changeset ef299e57f242 Message-ID: <20121120131007.23694.2489@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/eb7dd60840e6/ changeset: eb7dd60840e6 user: hpk42 date: 2012-11-20 14:09:40 summary: Added tag 2.3.4 for changeset ef299e57f242 affected #: 1 file diff -r ef299e57f24218dbdd949498d7e660723636bcc3 -r eb7dd60840e636067bf34f62570c6c71c051ceeb .hgtags --- a/.hgtags +++ b/.hgtags @@ -53,3 +53,4 @@ acf0e1477fb19a1d35a4e40242b77fa6af32eb17 2.3.1 8738b828dec53937765db71951ef955cca4c51f6 2.3.2 7fe44182c434f8ac89149a3c340479872a5d5ccb 2.3.3 +ef299e57f24218dbdd949498d7e660723636bcc3 2.3.4 Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 20 14:20:46 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Nov 2012 13:20:46 -0000 Subject: [py-svn] commit/pytest: hpk42: bump version, fix -k option help Message-ID: <20121120132046.18428.97712@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/b8bca3fce019/ changeset: b8bca3fce019 user: hpk42 date: 2012-11-20 14:20:39 summary: bump version, fix -k option help affected #: 4 files diff -r eb7dd60840e636067bf34f62570c6c71c051ceeb -r b8bca3fce01919379092e7aa12ec5c3bee3cf8cd CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +Changes between 2.3.4 and 2.3.5dev +----------------------------------- + +- fix option help for "-k" + Changes between 2.3.3 and 2.3.4 ----------------------------------- diff -r eb7dd60840e636067bf34f62570c6c71c051ceeb -r b8bca3fce01919379092e7aa12ec5c3bee3cf8cd _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.3.4' +__version__ = '2.4.5dev1' diff -r eb7dd60840e636067bf34f62570c6c71c051ceeb -r b8bca3fce01919379092e7aa12ec5c3bee3cf8cd _pytest/mark.py --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -8,11 +8,12 @@ group = parser.getgroup("general") group._addoption('-k', action="store", dest="keyword", default='', metavar="KEYWORDEXPR", - help="only run tests which match given keyword expression. " - "An expression consists of space-separated terms. " - "Each term must match. Precede a term with '-' to negate. " - "Terminate expression with ':' to make the first match match " - "all subsequent tests (usually file-order). ") + help="only run tests which match the given expression. " + "An expression is a python evaluatable expression " + "where all names are substring-matched against test names " + "and keywords. Example: -k 'test_method or test_other' " + "matches all test functions whose name contains " + "'test_method' or 'test_other'.") group._addoption("-m", action="store", dest="markexpr", default="", metavar="MARKEXPR", diff -r eb7dd60840e636067bf34f62570c6c71c051ceeb -r b8bca3fce01919379092e7aa12ec5c3bee3cf8cd setup.py --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.3.4', + version='2.4.5dev1', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 20 14:35:01 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Nov 2012 13:35:01 -0000 Subject: [py-svn] commit/pytest: hpk42: move long description into README Message-ID: <20121120133501.4857.46522@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/6ff0c6ed3b70/ changeset: 6ff0c6ed3b70 user: hpk42 date: 2012-11-20 14:24:26 summary: move long description into README affected #: 3 files diff -r b8bca3fce01919379092e7aa12ec5c3bee3cf8cd -r 6ff0c6ed3b700ec8039c77e184f30f1870164b7c CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,8 @@ - fix option help for "-k" +- move long description of distribution into README + Changes between 2.3.3 and 2.3.4 ----------------------------------- diff -r b8bca3fce01919379092e7aa12ec5c3bee3cf8cd -r 6ff0c6ed3b700ec8039c77e184f30f1870164b7c README.txt --- a/README.txt +++ b/README.txt @@ -1,4 +1,36 @@ -py.test is a simple and popular testing tool for Python. -See http://pytest.org for more documentation. +The ``py.test`` testing tool makes it easy to write small tests, yet +scales to support complex functional testing. It provides +- `auto-discovery + `_ + of test modules and functions, +- detailed info on failing `assert statements `_ (no need to remember ``self.assert*`` names) +- `modular fixtures `_ for + managing small or parametrized long-lived test resources. +- multi-paradigm support: you can use ``py.test`` to run test suites based + on `unittest `_ (or trial), + `nose `_ +- single-source compatibility to Python2.4 all the way up to Python3.3, + PyPy-1.9 and Jython-2.5.1. + +- many `external plugins `_. + +A simple example for a test:: + + # content of test_module.py + def test_function(): + i = 4 + assert i == 3 + +which can be run with ``py.test test_module.py``. See `getting-started `_ for more examples. + +For much more info, including PDF docs, see + + http://pytest.org + +and report bugs at: + + http://bitbucket.org/hpk42/pytest/issues/ + +Copyright Holger Krekel and others, 2004-2012 diff -r b8bca3fce01919379092e7aa12ec5c3bee3cf8cd -r 6ff0c6ed3b700ec8039c77e184f30f1870164b7c setup.py --- a/setup.py +++ b/setup.py @@ -6,43 +6,7 @@ use_setuptools() from setuptools import setup, Command -long_description = """ -The `py.test`` testing tool makes it easy to write small tests, yet -scales to support complex functional testing. It provides - -- `auto-discovery - `_ - of test modules and functions, -- detailed info on failing `assert statements `_ (no need to remember ``self.assert*`` names) -- `modular fixtures `_ for - managing small or parametrized long-lived test resources. -- multi-paradigm support: you can use ``py.test`` to run test suites based - on `unittest `_ (or trial), - `nose `_ -- single-source compatibility to Python2.4 all the way up to Python3.3, - PyPy-1.9 and Jython-2.5.1. - -- many `external plugins `_. - -A simple example for a test:: - - # content of test_module.py - def test_function(): - i = 4 - assert i == 3 - -which can be run with ``py.test test_module.py``. See `getting-started `_ for more examples. - -For much more info, including PDF docs, see - - http://pytest.org - -and report bugs at: - - http://bitbucket.org/hpk42/pytest/issues/ - -(c) Holger Krekel and others, 2004-2012 -""" +long_description = open("README.txt").read() def main(): setup( name='pytest', Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Tue Nov 20 14:38:09 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Tue, 20 Nov 2012 13:38:09 -0000 Subject: [py-svn] commit/pytest: hpk42: reanme README.txt to README.rst Message-ID: <20121120133809.17840.6919@bitbucket22.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/7a6433e9620f/ changeset: 7a6433e9620f user: hpk42 date: 2012-11-20 14:37:39 summary: reanme README.txt to README.rst affected #: 5 files diff -r 6ff0c6ed3b700ec8039c77e184f30f1870164b7c -r 7a6433e9620f4305bd65dfb191c30d0e56871ae3 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,7 +3,7 @@ - fix option help for "-k" -- move long description of distribution into README +- move long description of distribution into README.rst Changes between 2.3.3 and 2.3.4 ----------------------------------- diff -r 6ff0c6ed3b700ec8039c77e184f30f1870164b7c -r 7a6433e9620f4305bd65dfb191c30d0e56871ae3 MANIFEST.in --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,5 @@ include CHANGELOG -include README.txt +include README.rst include setup.py include distribute_setup.py include tox.ini diff -r 6ff0c6ed3b700ec8039c77e184f30f1870164b7c -r 7a6433e9620f4305bd65dfb191c30d0e56871ae3 README.rst --- /dev/null +++ b/README.rst @@ -0,0 +1,36 @@ + +The ``py.test`` testing tool makes it easy to write small tests, yet +scales to support complex functional testing. It provides + +- `auto-discovery + `_ + of test modules and functions, +- detailed info on failing `assert statements `_ (no need to remember ``self.assert*`` names) +- `modular fixtures `_ for + managing small or parametrized long-lived test resources. +- multi-paradigm support: you can use ``py.test`` to run test suites based + on `unittest `_ (or trial), + `nose `_ +- single-source compatibility to Python2.4 all the way up to Python3.3, + PyPy-1.9 and Jython-2.5.1. + +- many `external plugins `_. + +A simple example for a test:: + + # content of test_module.py + def test_function(): + i = 4 + assert i == 3 + +which can be run with ``py.test test_module.py``. See `getting-started `_ for more examples. + +For much more info, including PDF docs, see + + http://pytest.org + +and report bugs at: + + http://bitbucket.org/hpk42/pytest/issues/ + +Copyright Holger Krekel and others, 2004-2012 diff -r 6ff0c6ed3b700ec8039c77e184f30f1870164b7c -r 7a6433e9620f4305bd65dfb191c30d0e56871ae3 README.txt --- a/README.txt +++ /dev/null @@ -1,36 +0,0 @@ - -The ``py.test`` testing tool makes it easy to write small tests, yet -scales to support complex functional testing. It provides - -- `auto-discovery - `_ - of test modules and functions, -- detailed info on failing `assert statements `_ (no need to remember ``self.assert*`` names) -- `modular fixtures `_ for - managing small or parametrized long-lived test resources. -- multi-paradigm support: you can use ``py.test`` to run test suites based - on `unittest `_ (or trial), - `nose `_ -- single-source compatibility to Python2.4 all the way up to Python3.3, - PyPy-1.9 and Jython-2.5.1. - -- many `external plugins `_. - -A simple example for a test:: - - # content of test_module.py - def test_function(): - i = 4 - assert i == 3 - -which can be run with ``py.test test_module.py``. See `getting-started `_ for more examples. - -For much more info, including PDF docs, see - - http://pytest.org - -and report bugs at: - - http://bitbucket.org/hpk42/pytest/issues/ - -Copyright Holger Krekel and others, 2004-2012 diff -r 6ff0c6ed3b700ec8039c77e184f30f1870164b7c -r 7a6433e9620f4305bd65dfb191c30d0e56871ae3 setup.py --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ use_setuptools() from setuptools import setup, Command -long_description = open("README.txt").read() +long_description = open("README.rst").read() def main(): setup( name='pytest', Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From issues-reply at bitbucket.org Wed Nov 21 00:08:35 2012 From: issues-reply at bitbucket.org (Pedro Rodriguez) Date: Tue, 20 Nov 2012 23:08:35 -0000 Subject: [py-svn] [hpk42/pytest] Make getting test results from fixtures easier (issue #230) Message-ID: --- you can reply above this line --- New issue 230: Make getting test results from fixtures easier https://bitbucket.org/hpk42/pytest/issue/230/make-getting-test-results-from-fixtures Pedro Rodriguez: The current way is too complex for how simple this should be. Responsible: hpk42 -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From commits-noreply at bitbucket.org Wed Nov 21 20:43:50 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 21 Nov 2012 19:43:50 -0000 Subject: [py-svn] commit/pytest: 2 new changesets Message-ID: <20121121194350.27847.9344@bitbucket05.managed.contegix.com> 2 new commits in pytest: https://bitbucket.org/hpk42/pytest/changeset/84a341ad118a/ changeset: 84a341ad118a user: hpk42 date: 2012-11-21 10:13:44 summary: improve docstring for metafunc.parametrize() affected #: 2 files diff -r 7a6433e9620f4305bd65dfb191c30d0e56871ae3 -r 84a341ad118a2651e40f79a096563fc6d5e85a89 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,8 @@ - move long description of distribution into README.rst +- improve docstring for metafunc.parametrize() + Changes between 2.3.3 and 2.3.4 ----------------------------------- diff -r 7a6433e9620f4305bd65dfb191c30d0e56871ae3 -r 84a341ad118a2651e40f79a096563fc6d5e85a89 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -643,8 +643,11 @@ :arg argnames: an argument name or a list of argument names - :arg argvalues: a list of values for the argname or a list of tuples of - values for the list of argument names. + :arg argvalues: The list of argvalues determines how often a test is invoked + with different argument values. If only one argname was specified argvalues + is a list of simple values. If N argnames were specified, argvalues must + be a list of N-tuples, where each tuple-element specifies a value for its + respective argname. :arg indirect: if True each argvalue corresponding to an argname will be passed as request.param to its respective argname fixture https://bitbucket.org/hpk42/pytest/changeset/a97f5b9d7e34/ changeset: a97f5b9d7e34 user: hpk42 date: 2012-11-21 20:43:31 summary: fix bug where using capsys with pytest.set_trace() in a test function would break when looking at capsys.readouterr() affected #: 5 files diff -r 84a341ad118a2651e40f79a096563fc6d5e85a89 -r a97f5b9d7e34976d40f96165293fc375e53380a4 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,9 @@ - improve docstring for metafunc.parametrize() +- fix bug where using capsys with pytest.set_trace() in a test + function would break when looking at capsys.readouterr() + Changes between 2.3.3 and 2.3.4 ----------------------------------- diff -r 84a341ad118a2651e40f79a096563fc6d5e85a89 -r a97f5b9d7e34976d40f96165293fc375e53380a4 _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.5dev1' +__version__ = '2.4.5dev2' diff -r 84a341ad118a2651e40f79a096563fc6d5e85a89 -r a97f5b9d7e34976d40f96165293fc375e53380a4 _pytest/capture.py --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -211,12 +211,15 @@ def _finalize(self): if hasattr(self, 'capture'): - outerr = self.capture.reset() + outerr = self._outerr = self.capture.reset() del self.capture return outerr def readouterr(self): - return self.capture.readouterr() + try: + return self.capture.readouterr() + except AttributeError: + return self._outerr def close(self): self._finalize() diff -r 84a341ad118a2651e40f79a096563fc6d5e85a89 -r a97f5b9d7e34976d40f96165293fc375e53380a4 setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.5dev1', + version='2.4.5dev2', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], diff -r 84a341ad118a2651e40f79a096563fc6d5e85a89 -r a97f5b9d7e34976d40f96165293fc375e53380a4 testing/test_pdb.py --- a/testing/test_pdb.py +++ b/testing/test_pdb.py @@ -106,6 +106,22 @@ if child.isalive(): child.wait() + def test_pdb_and_capsys(self, testdir): + p1 = testdir.makepyfile(""" + import pytest + def test_1(capsys): + print ("hello1") + pytest.set_trace() + """) + child = testdir.spawn_pytest(str(p1)) + child.expect("test_1") + child.send("capsys.readouterr()\n") + child.expect("hello1") + child.sendeof() + rest = child.read() + if child.isalive(): + child.wait() + def test_pdb_interaction_doctest(self, testdir): p1 = testdir.makepyfile(""" import pytest Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Nov 21 20:47:02 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 21 Nov 2012 19:47:02 -0000 Subject: [py-svn] commit/pytest-cache: 3 new changesets Message-ID: <20121121194702.31150.36656@bitbucket24.managed.contegix.com> 3 new commits in pytest-cache: https://bitbucket.org/hpk42/pytest-cache/changeset/e5eef3cca436/ changeset: e5eef3cca436 user: jriches date: 2012-11-21 14:43:58 summary: Add --failedfirst option to run previously failed tests at the start of the run Includes unit test affected #: 2 files diff -r 0694bcab3d0c2f066b8c656dce20e8bb519192b6 -r e5eef3cca4365ad59c36427cfe226355a0018900 pytest_cache.py --- a/pytest_cache.py +++ b/pytest_cache.py @@ -7,12 +7,16 @@ group = parser.getgroup("general") group.addoption('--lf', action='store_true', dest="lf", help="rerun tests that failed at the last run") + group.addoption('--failedfirst', action='store_true', dest="failedfirst", + help="run tests that failed at the last run at the start of this run") group.addoption('--cache', action='store_true', dest="showcache", help="show cache contents, don't perform collection or tests") group.addoption('--clearcache', action='store_true', dest="clearcache", help="remove all cache contents at start of test run.") def pytest_cmdline_main(config): + if config.option.failedfirst and not config.option.lf: + raise pytest.UsageError("--failedfirst must be used with --lf") if config.option.showcache: from _pytest.main import wrap_session return wrap_session(config, showcache) @@ -123,7 +127,9 @@ if not self.lastfailed: mode = "run all (no recorded failures)" else: - mode = "rerun last %d failures" % len(self.lastfailed) + mode = "rerun last %d failures%s" % ( + len(self.lastfailed), + " first" if self.config.getvalue("failedfirst") else "") return "run-last-failure: %s" % mode def pytest_runtest_logreport(self, report): @@ -137,15 +143,18 @@ def pytest_collection_modifyitems(self, session, config, items): if self.config.getvalue("lf") and self.lastfailed: - newitems = [] - deselected = [] + previously_failed = [] + previously_passed = [] for item in items: if item.nodeid in self.lastfailed: - newitems.append(item) + previously_failed.append(item) else: - deselected.append(item) - items[:] = newitems - config.hook.pytest_deselected(items=deselected) + previously_passed.append(item) + if self.config.getvalue("failedfirst"): + items[:] = previously_failed + previously_passed + else: + items[:] = previously_failed + config.hook.pytest_deselected(items=previously_failed) def pytest_sessionfinish(self, session): config = self.config diff -r 0694bcab3d0c2f066b8c656dce20e8bb519192b6 -r e5eef3cca4365ad59c36427cfe226355a0018900 test_cache.py --- a/test_cache.py +++ b/test_cache.py @@ -161,6 +161,28 @@ "*2 failed*", ]) + def test_lastfailed_order(self, testdir): + always_pass = testdir.tmpdir.join('test_a.py').write(py.code.Source(""" + def test_always_passes(): + assert 1 + """)) + always_fail = testdir.tmpdir.join('test_b.py').write(py.code.Source(""" + def test_always_fails(): + assert 0 + """)) + result = testdir.runpytest() + # Test order will be collection order; alphabetical + result.stdout.fnmatch_lines([ + "test_a.py*", + "test_b.py*", + ]) + result = testdir.runpytest("--lf", "--failedfirst") + # Test order will be failing tests firs + result.stdout.fnmatch_lines([ + "test_b.py*", + "test_a.py*", + ]) + @pytest.mark.skipif("sys.version_info < (2,6)") def test_lastfailed_failure_to_skip_is_passsed(self, testdir, monkeypatch): monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) https://bitbucket.org/hpk42/pytest-cache/changeset/1f81c9f64ece/ changeset: 1f81c9f64ece user: jriches date: 2012-11-21 15:58:40 summary: Provide short argument -ff for Failed First. Fix bug with wrong tests being deselected affected #: 2 files diff -r e5eef3cca4365ad59c36427cfe226355a0018900 -r 1f81c9f64ece05b1c630a5b7348a94261270658f pytest_cache.py --- a/pytest_cache.py +++ b/pytest_cache.py @@ -7,16 +7,15 @@ group = parser.getgroup("general") group.addoption('--lf', action='store_true', dest="lf", help="rerun tests that failed at the last run") - group.addoption('--failedfirst', action='store_true', dest="failedfirst", - help="run tests that failed at the last run at the start of this run") + group.addoption('--ff', action='store_true', dest="failedfirst", + help="run tests that failed at the last run at the start of this run. " + "re-orders tests - may lead to repeated fixture setup/teardown") group.addoption('--cache', action='store_true', dest="showcache", help="show cache contents, don't perform collection or tests") group.addoption('--clearcache', action='store_true', dest="clearcache", help="remove all cache contents at start of test run.") def pytest_cmdline_main(config): - if config.option.failedfirst and not config.option.lf: - raise pytest.UsageError("--failedfirst must be used with --lf") if config.option.showcache: from _pytest.main import wrap_session return wrap_session(config, showcache) @@ -117,13 +116,14 @@ """ Plugin which implements the --lf (run last-failing) option """ def __init__(self, config): self.config = config - if config.getvalue("lf"): + self.active = config.getvalue("lf") or config.getvalue("failedfirst") + if self.active: self.lastfailed = config.cache.get("cache/lastfailed", set()) else: self.lastfailed = set() def pytest_report_header(self): - if self.config.getvalue("lf"): + if self.active: if not self.lastfailed: mode = "run all (no recorded failures)" else: @@ -142,7 +142,7 @@ self.lastfailed.discard(report.nodeid) def pytest_collection_modifyitems(self, session, config, items): - if self.config.getvalue("lf") and self.lastfailed: + if self.active and self.lastfailed: previously_failed = [] previously_passed = [] for item in items: @@ -154,7 +154,7 @@ items[:] = previously_failed + previously_passed else: items[:] = previously_failed - config.hook.pytest_deselected(items=previously_failed) + config.hook.pytest_deselected(items=previously_passed) def pytest_sessionfinish(self, session): config = self.config diff -r e5eef3cca4365ad59c36427cfe226355a0018900 -r 1f81c9f64ece05b1c630a5b7348a94261270658f test_cache.py --- a/test_cache.py +++ b/test_cache.py @@ -176,7 +176,7 @@ "test_a.py*", "test_b.py*", ]) - result = testdir.runpytest("--lf", "--failedfirst") + result = testdir.runpytest("--lf", "--ff") # Test order will be failing tests firs result.stdout.fnmatch_lines([ "test_b.py*", https://bitbucket.org/hpk42/pytest-cache/changeset/83120fec0698/ changeset: 83120fec0698 user: jriches date: 2012-11-21 20:41:07 summary: Rename test to test_failedfirst_order affected #: 1 file diff -r 1f81c9f64ece05b1c630a5b7348a94261270658f -r 83120fec0698330dd3169661e9ec2fe545666a55 test_cache.py --- a/test_cache.py +++ b/test_cache.py @@ -161,7 +161,7 @@ "*2 failed*", ]) - def test_lastfailed_order(self, testdir): + def test_failedfirst_order(self, testdir): always_pass = testdir.tmpdir.join('test_a.py').write(py.code.Source(""" def test_always_passes(): assert 1 Repository URL: https://bitbucket.org/hpk42/pytest-cache/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Nov 21 20:55:40 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 21 Nov 2012 19:55:40 -0000 Subject: [py-svn] commit/pytest-cache: 6 new changesets Message-ID: <20121121195540.14219.88071@bitbucket02.managed.contegix.com> 6 new commits in pytest-cache: https://bitbucket.org/hpk42/pytest-cache/changeset/d868f54da012/ changeset: d868f54da012 user: hpk42 date: 2012-06-20 16:42:04 summary: fix lastfail-handling for xpassing tests affected #: 2 files diff -r 27cda0c4b038562cbe7d281e2323539cf7487710 -r d868f54da01204844fe686eb3ebb2fc03ca15384 pytest_cache.py --- a/pytest_cache.py +++ b/pytest_cache.py @@ -127,9 +127,9 @@ return "run-last-failure: %s" % mode def pytest_runtest_logreport(self, report): - if report.failed: + if report.failed and "xfail" not in report.keywords: self.lastfailed.add(report.nodeid) - else: + elif not report.failed: if report.when == "call": try: self.lastfailed.remove(report.nodeid) diff -r 27cda0c4b038562cbe7d281e2323539cf7487710 -r d868f54da01204844fe686eb3ebb2fc03ca15384 test_cache.py --- a/test_cache.py +++ b/test_cache.py @@ -160,3 +160,14 @@ result.stdout.fnmatch_lines([ "*2 failed*", ]) + + def test_lastfailed_xpass(self, testdir): + rep = testdir.inline_runsource1(""" + import pytest + @pytest.mark.xfail + def test_hello(): + assert 1 + """) + config = testdir.parseconfigure() + lastfailed = config.cache.get("cache/lastfailed", -1) + assert not lastfailed https://bitbucket.org/hpk42/pytest-cache/changeset/0fd652833a08/ changeset: 0fd652833a08 user: hpk42 date: 2012-06-20 22:21:42 summary: now that execnet is released, use pypi again affected #: 1 file diff -r d868f54da01204844fe686eb3ebb2fc03ca15384 -r 0fd652833a0849ab1b32763dc63fe823c21b52ed tox.ini --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,13 @@ [tox] envlist=py25,py27,py32,py-xdist indexserver = - default = http://pypi.testrun.org + default = http://pypi.python.org/simple testrun = http://pypi.testrun.org pypi = http://pypi.python.org/simple [testenv] deps=:pypi:pep8 - pytest-pep8 + :testrun:pytest-pep8 commands = py.test --pep8 --junitxml={envlogdir}/junit-{envname}.xml {posargs} https://bitbucket.org/hpk42/pytest-cache/changeset/3e65896bdd82/ changeset: 3e65896bdd82 user: hpk42 date: 2012-06-20 22:29:37 summary: Added tag 0.9 for changeset 0fd652833a08 affected #: 1 file diff -r 0fd652833a0849ab1b32763dc63fe823c21b52ed -r 3e65896bdd82b2525c2242ccb25f9b68c5e610dd .hgtags --- a/.hgtags +++ b/.hgtags @@ -4,3 +4,4 @@ 14359fa2c9eb31e5cdf7414603a14b943327bc07 0.7 04e2de41d527876325038b22a1721b9290b0db8d 0.7 1160e1328095d879238cdda32173476ecc5a5072 0.9.1 +0fd652833a0849ab1b32763dc63fe823c21b52ed 0.9 https://bitbucket.org/hpk42/pytest-cache/changeset/17f063c42184/ changeset: 17f063c42184 user: hpk42 date: 2012-11-20 13:45:30 summary: add a test, don't depend on dict-ordering in another affected #: 2 files diff -r 3e65896bdd82b2525c2242ccb25f9b68c5e610dd -r 17f063c42184fa85313a88b157d491bc58b9ea84 README.txt --- a/README.txt +++ b/README.txt @@ -21,8 +21,8 @@ The cache plugin introduces the ``--lf`` option to py.test which alows to rerun all test failures of a previous test run. -If not tests failed, all tests will be run as normal. It is -thus perfectly fine to always pass ``--lf``. +If no tests failed previously, all tests will be run as normal. +It is thus usually fine to always pass ``--lf``. As an example, let's create 50 test invocation of which only 2 fail:: diff -r 3e65896bdd82b2525c2242ccb25f9b68c5e610dd -r 17f063c42184fa85313a88b157d491bc58b9ea84 test_cache.py --- a/test_cache.py +++ b/test_cache.py @@ -36,7 +36,7 @@ result = testdir.runpytest() assert result.ret == 0 result = testdir.runpytest("--cache") - result.stdout.fnmatch_lines([ + result.stdout.fnmatch_lines_random([ "*cachedir:*", "-*cache values*-", "*my/name contains:", @@ -137,6 +137,42 @@ ]) @pytest.mark.skipif("sys.version_info < (2,6)") + def test_lastfailed_difference_invocations(self, testdir, monkeypatch): + monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) + testdir.makepyfile(test_a=""" + def test_a1(): + assert 0 + def test_a2(): + assert 1 + """, test_b=""" + def test_b1(): + assert 0 + """) + p = testdir.tmpdir.join("test_a.py") + p2 = testdir.tmpdir.join("test_b.py") + + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "*2 failed*", + ]) + result = testdir.runpytest("--lf", p2) + result.stdout.fnmatch_lines([ + "*1 failed*", + ]) + p2.write(py.code.Source(""" + def test_b1(): + assert 1 + """)) + result = testdir.runpytest("--lf", p2) + result.stdout.fnmatch_lines([ + "*1 passed*", + ]) + result = testdir.runpytest("--lf", p) + result.stdout.fnmatch_lines([ + "*1 failed*1 desel*", + ]) + + @pytest.mark.skipif("sys.version_info < (2,6)") def test_lastfailed_usecase_splice(self, testdir, monkeypatch): monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) p1 = testdir.makepyfile(""" https://bitbucket.org/hpk42/pytest-cache/changeset/08bcb2cfbb9f/ changeset: 08bcb2cfbb9f user: hpk42 date: 2012-11-21 20:54:00 summary: merge affected #: 3 files diff -r 17f063c42184fa85313a88b157d491bc58b9ea84 -r 08bcb2cfbb9f5bc17fb66be8f1bcb0ef32c56611 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ + +- fix issue 4: consider setup time skip of a previous failure + as no longer failing +- ensure --cache output is sorted + 0.9 ---------------------------------------------- https://bitbucket.org/hpk42/pytest-cache/changeset/784b46ee1606/ changeset: 784b46ee1606 user: hpk42 date: 2012-11-21 20:51:14 summary: merged "--ff" (failedfirst) option to run all tests but run the last-failed ones first. Thanks Jack Riches. affected #: 4 files diff -r 08bcb2cfbb9f5bc17fb66be8f1bcb0ef32c56611 -r 784b46ee16060fa34c69df28bf03e3ff3e6df633 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,12 @@ as no longer failing - ensure --cache output is sorted +1.0.dev +---------------------------------------------- + +- merged "--ff" (failedfirst) option to run all tests but + run the last-failed ones first. Thanks Jack Riches. + 0.9 ---------------------------------------------- diff -r 08bcb2cfbb9f5bc17fb66be8f1bcb0ef32c56611 -r 784b46ee16060fa34c69df28bf03e3ff3e6df633 pytest_cache.py --- a/pytest_cache.py +++ b/pytest_cache.py @@ -1,7 +1,7 @@ import py import pytest -__version__ = '0.9' +__version__ = '1.0dev' def pytest_addoption(parser): group = parser.getgroup("general") diff -r 08bcb2cfbb9f5bc17fb66be8f1bcb0ef32c56611 -r 784b46ee16060fa34c69df28bf03e3ff3e6df633 setup.py --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ name='pytest-cache', description='pytest plugin with mechanisms for caching across test runs', long_description=open("README.txt").read(), - version='0.9', + version='1.0dev', author='Holger Krekel', author_email='holger.krekel at gmail.com', url='http://bitbucket.org/hpk42/pytest-cache/', diff -r 08bcb2cfbb9f5bc17fb66be8f1bcb0ef32c56611 -r 784b46ee16060fa34c69df28bf03e3ff3e6df633 tox.ini --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,13 @@ [tox] -envlist=py25,py27,py32,py-xdist +envlist=py25,py27,py32,py33,py-xdist indexserver = - default = http://pypi.python.org/simple + #default = http://pypi.python.org/simple testrun = http://pypi.testrun.org pypi = http://pypi.python.org/simple [testenv] deps=:pypi:pep8 - :testrun:pytest-pep8 + :pypi:pytest-pep8 commands = py.test --pep8 --junitxml={envlogdir}/junit-{envname}.xml {posargs} Repository URL: https://bitbucket.org/hpk42/pytest-cache/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Nov 21 20:57:21 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 21 Nov 2012 19:57:21 -0000 Subject: [py-svn] commit/pytest-cache: hpk42: fix CHANGELOG, bump version Message-ID: <20121121195721.14219.96119@bitbucket02.managed.contegix.com> 1 new commit in pytest-cache: https://bitbucket.org/hpk42/pytest-cache/changeset/0b1ed1d22c50/ changeset: 0b1ed1d22c50 user: hpk42 date: 2012-11-21 20:56:20 summary: fix CHANGELOG, bump version affected #: 3 files diff -r 784b46ee16060fa34c69df28bf03e3ff3e6df633 -r 0b1ed1d22c50ab3d6019d5ddefd7c0a254d407a8 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,11 +1,11 @@ +1.0.dev +---------------------------------------------- - fix issue 4: consider setup time skip of a previous failure as no longer failing + - ensure --cache output is sorted -1.0.dev ----------------------------------------------- - - merged "--ff" (failedfirst) option to run all tests but run the last-failed ones first. Thanks Jack Riches. diff -r 784b46ee16060fa34c69df28bf03e3ff3e6df633 -r 0b1ed1d22c50ab3d6019d5ddefd7c0a254d407a8 pytest_cache.py --- a/pytest_cache.py +++ b/pytest_cache.py @@ -1,7 +1,7 @@ import py import pytest -__version__ = '1.0dev' +__version__ = '1.0dev2' def pytest_addoption(parser): group = parser.getgroup("general") diff -r 784b46ee16060fa34c69df28bf03e3ff3e6df633 -r 0b1ed1d22c50ab3d6019d5ddefd7c0a254d407a8 setup.py --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ name='pytest-cache', description='pytest plugin with mechanisms for caching across test runs', long_description=open("README.txt").read(), - version='1.0dev', + version='1.0dev2', author='Holger Krekel', author_email='holger.krekel at gmail.com', url='http://bitbucket.org/hpk42/pytest-cache/', Repository URL: https://bitbucket.org/hpk42/pytest-cache/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From issues-reply at bitbucket.org Thu Nov 22 12:13:56 2012 From: issues-reply at bitbucket.org (Stefan Scherfke) Date: Thu, 22 Nov 2012 11:13:56 -0000 Subject: [py-svn] [hpk42/pytest] Duplicate function "pytest_pyfunc_call" (issue #231) Message-ID: --- you can reply above this line --- New issue 231: Duplicate function "pytest_pyfunc_call" https://bitbucket.org/hpk42/pytest/issue/231/duplicate-function-pytest_pyfunc_call Stefan Scherfke: _pytest.python.pytest_pyfunc_call is implemented twice: https://bitbucket.org/hpk42/pytest/src/8d87ff808393/_pytest/python.py?at=default#cl-132 https://bitbucket.org/hpk42/pytest/src/8d87ff808393/_pytest/python.py?at=default#cl-148 -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From commits-noreply at bitbucket.org Thu Nov 22 14:32:45 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 22 Nov 2012 13:32:45 -0000 Subject: [py-svn] commit/py: cfbolz: fix docstring of py.process.cmdexec Message-ID: <20121122133245.28749.66863@bitbucket02.managed.contegix.com> 1 new commit in py: https://bitbucket.org/hpk42/py/changeset/c8c1a8255e77/ changeset: c8c1a8255e77 user: cfbolz date: 2012-11-22 13:59:11 summary: fix docstring of py.process.cmdexec affected #: 1 file diff -r 462a333b9d4b64c28288bf1f18210750a58256b4 -r c8c1a8255e7786800eae6d2d020ba6b966637427 py/_process/cmdexec.py --- a/py/_process/cmdexec.py +++ b/py/_process/cmdexec.py @@ -10,7 +10,7 @@ def cmdexec(cmd): """ return unicode output of executing 'cmd' in a separate process. - raise cmdexec.ExecutionFailed exeception if the command failed. + raise cmdexec.Error exeception if the command failed. the exception will provide an 'err' attribute containing the error-output from the command. if the subprocess module does not provide a proper encoding/unicode strings Repository URL: https://bitbucket.org/hpk42/py/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Nov 22 20:29:56 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 22 Nov 2012 19:29:56 -0000 Subject: [py-svn] commit/pytest: mineo: Fix a broken link to pytest-twisted Message-ID: <20121122192956.3820.17897@bitbucket15.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/2296406d6160/ changeset: 2296406d6160 user: mineo date: 2012-11-22 19:59:15 summary: Fix a broken link to pytest-twisted affected #: 1 file diff -r a97f5b9d7e34976d40f96165293fc375e53380a4 -r 2296406d61603c56d54541cf38cee8d1e373ab8a doc/en/faq.txt --- a/doc/en/faq.txt +++ b/doc/en/faq.txt @@ -29,7 +29,7 @@ If you are using trial's unittest.TestCase chances are that you can just run your tests even if you return Deferreds. In addition, there also is a dedicated `pytest-twisted -`_ plugin which allows to return deferreds from pytest-style tests, allowing to use :ref:`fixtures` and other features. Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From issues-reply at bitbucket.org Mon Nov 26 22:43:41 2012 From: issues-reply at bitbucket.org (Brian O'Neill) Date: Mon, 26 Nov 2012 21:43:41 -0000 Subject: [py-svn] [hpk42/pytest] pytest 2.3.4 throws InternalError when not using new keyword syntax (issue #232) Message-ID: <1b88065d142fa16985fb9baa688eea81@bitbucket.org> --- you can reply above this line --- New issue 232: pytest 2.3.4 throws InternalError when not using new keyword syntax https://bitbucket.org/hpk42/pytest/issue/232/pytest-234-throws-internalerror-when-not Brian O'Neill: Before version 2.3.4 I would run tests like this: py.test -k "smoke -unstable" It would look for the tests marked as smoke and ones aren't marked as unstable. It assumed the "and" between them I saw that the update to 2.3.4 added new keyword syntax so we should be running tests like this: py.test -k "smoke and -unstable" When running the old way it shows a really nasty error: ``` #!python INTERNALERROR> Traceback (most recent call last): INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/main.py", line 81, in wrap_session INTERNALERROR> doit(config, session) INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/main.py", line 112, in _main INTERNALERROR> config.hook.pytest_collection(session=session) INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/core.py", line 422, in __call__ INTERNALERROR> return self._docall(methods, kwargs) INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/core.py", line 433, in _docall INTERNALERROR> res = mc.execute() INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/core.py", line 351, in execute INTERNALERROR> res = method(**kwargs) INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/main.py", line 116, in pytest_collection INTERNALERROR> return session.perform_collect() INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/main.py", line 467, in perform_collect INTERNALERROR> config=self.config, items=items) INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/core.py", line 422, in __call__ INTERNALERROR> return self._docall(methods, kwargs) INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/core.py", line 433, in _docall INTERNALERROR> res = mc.execute() INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/core.py", line 351, in execute INTERNALERROR> res = method(**kwargs) INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/mark.py", line 54, in pytest_collection_modifyitems INTERNALERROR> if keywordexpr and not matchkeyword(colitem, keywordexpr): INTERNALERROR> File "/home/vagrant/python_venv/eb/lib/python2.6/site-packages/_pytest/mark.py", line 89, in matchkeyword INTERNALERROR> return eval(keywordexpr, {}, SubstringDict(colitem.keywords)) INTERNALERROR> File "", line 1 INTERNALERROR> smoke not unstable INTERNALERROR> ^ INTERNALERROR> SyntaxError: unexpected EOF while parsing ``` I think the old way of marking tests should still be supported with the new pytest versions and just automatically assume "and" between the keywords. If this isn't possible it would be useful to get a better error message as it was very confusing trying to figure out what was wrong. Responsible: hpk42 -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From commits-noreply at bitbucket.org Wed Nov 28 09:18:24 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 28 Nov 2012 08:18:24 -0000 Subject: [py-svn] commit/pytest: Graham Horler: Remove check for "_" prefix on python functions (use python_functions) Message-ID: <20121128081824.30321.60782@bitbucket24.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/54a6130223e4/ changeset: 54a6130223e4 user: Graham Horler date: 2012-11-27 17:58:08 summary: Remove check for "_" prefix on python functions (use python_functions) (See IRC hpk 2012-11-27 14:56: after the python_functions customization was introduced, it makes sense to disregard the preliminary "_" check) affected #: 2 files diff -r 2296406d61603c56d54541cf38cee8d1e373ab8a -r 54a6130223e48a6c424dc74d1f72c6793d4ece18 _pytest/python.py --- a/_pytest/python.py +++ b/_pytest/python.py @@ -277,13 +277,12 @@ if name in seen: continue seen[name] = True - if name[0] != "_": - res = self.makeitem(name, obj) - if res is None: - continue - if not isinstance(res, list): - res = [res] - l.extend(res) + res = self.makeitem(name, obj) + if res is None: + continue + if not isinstance(res, list): + res = [res] + l.extend(res) l.sort(key=lambda item: item.reportinfo()[:2]) return l diff -r 2296406d61603c56d54541cf38cee8d1e373ab8a -r 54a6130223e48a6c424dc74d1f72c6793d4ece18 testing/python/collect.py --- a/testing/python/collect.py +++ b/testing/python/collect.py @@ -659,6 +659,28 @@ "*2 passed*", ]) + +def test_customized_python_discovery_functions(testdir): + testdir.makeini(""" + [pytest] + python_functions=_test + """) + p = testdir.makepyfile(""" + def _test_underscore(): + pass + """) + result = testdir.runpytest("--collectonly", "-s") + result.stdout.fnmatch_lines([ + "*_test_underscore*", + ]) + + result = testdir.runpytest() + assert result.ret == 0 + result.stdout.fnmatch_lines([ + "*1 passed*", + ]) + + def test_collector_attributes(testdir): testdir.makeconftest(""" import pytest Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Wed Nov 28 09:23:43 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Wed, 28 Nov 2012 08:23:43 -0000 Subject: [py-svn] commit/pytest: hpk42: allow to specify prefixes starting with "_" when Message-ID: <20121128082343.13784.28384@bitbucket02.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/16f68fdd8180/ changeset: 16f68fdd8180 user: hpk42 date: 2012-11-28 09:23:36 summary: allow to specify prefixes starting with "_" when customizing python_functions test discovery. (thanks Graham Horler) affected #: 4 files diff -r 54a6130223e48a6c424dc74d1f72c6793d4ece18 -r 16f68fdd818016a198a47d30a859030eec5c9a7f AUTHORS --- a/AUTHORS +++ b/AUTHORS @@ -23,3 +23,4 @@ Bob Ippolito Christian Tismer Daniel Nuri +Graham Horler diff -r 54a6130223e48a6c424dc74d1f72c6793d4ece18 -r 16f68fdd818016a198a47d30a859030eec5c9a7f CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,9 @@ - fix bug where using capsys with pytest.set_trace() in a test function would break when looking at capsys.readouterr() +- allow to specify prefixes starting with "_" when + customizing python_functions test discovery. (thanks Graham Horler) + Changes between 2.3.3 and 2.3.4 ----------------------------------- diff -r 54a6130223e48a6c424dc74d1f72c6793d4ece18 -r 16f68fdd818016a198a47d30a859030eec5c9a7f _pytest/__init__.py --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.4.5dev2' +__version__ = '2.4.5dev3' diff -r 54a6130223e48a6c424dc74d1f72c6793d4ece18 -r 16f68fdd818016a198a47d30a859030eec5c9a7f setup.py --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ name='pytest', description='py.test: simple powerful testing with Python', long_description = long_description, - version='2.4.5dev2', + version='2.4.5dev3', url='http://pytest.org', license='MIT license', platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'], Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From issues-reply at bitbucket.org Wed Nov 28 20:29:37 2012 From: issues-reply at bitbucket.org (Jeff Pittman) Date: Wed, 28 Nov 2012 19:29:37 -0000 Subject: [py-svn] [hpk42/pytest] Trailing blank on doctest boolean should be stripped, or include quotes in error report (issue #233) Message-ID: --- you can reply above this line --- New issue 233: Trailing blank on doctest boolean should be stripped, or include quotes in error report https://bitbucket.org/hpk42/pytest/issue/233/trailing-blank-on-doctest-boolean-should Jeff Pittman: In a browser test such as: >>> browser.open(testing.BASE_URL + '/software-collection/') >>> pos = browser.contents.index >>> pos("item one") > pos("item two") True if you have a trailing blank at the end of True, you will get an error like: Expected: True Got: True which is hard to see. -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From issues-reply at bitbucket.org Thu Nov 29 09:46:45 2012 From: issues-reply at bitbucket.org (Ronny Pfannschmidt) Date: Thu, 29 Nov 2012 08:46:45 -0000 Subject: [py-svn] [hpk42/pytest] failure of autouse fixture does not always cause test failure (issue #234) Message-ID: <5241aea0021864cf686b6da72cad47aa@bitbucket.org> --- you can reply above this line --- New issue 234: failure of autouse fixture does not always cause test failure https://bitbucket.org/hpk42/pytest/issue/234/failure-of-autouse-fixture-does-not-always Ronny Pfannschmidt: i did hit a complex case in the anyvc suite, i cant yet make a simple replica, the most simple inbovations work fine -- This is an issue notification from bitbucket.org. You are receiving this either because you are the owner of the issue, or you are following the issue. From commits-noreply at bitbucket.org Thu Nov 29 10:04:52 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 29 Nov 2012 09:04:52 -0000 Subject: [py-svn] commit/pytest: RonnyPfannschmidt: improve PYTEST_DEBUG tracing output Message-ID: <20121129090452.16330.45045@bitbucket25.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/8cc3505ca780/ changeset: 8cc3505ca780 user: RonnyPfannschmidt date: 2012-11-29 10:04:39 summary: improve PYTEST_DEBUG tracing output by putingextra data on a new lines with additional indent affected #: 3 files diff -r 16f68fdd818016a198a47d30a859030eec5c9a7f -r 8cc3505ca7801cfff4f9a688e824abeaf0f1b7fc CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -13,6 +13,9 @@ - allow to specify prefixes starting with "_" when customizing python_functions test discovery. (thanks Graham Horler) +- improve PYTEST_DEBUG tracing output by puting + extra data on a new lines with additional indent + Changes between 2.3.3 and 2.3.4 ----------------------------------- diff -r 16f68fdd818016a198a47d30a859030eec5c9a7f -r 8cc3505ca7801cfff4f9a688e824abeaf0f1b7fc _pytest/core.py --- a/_pytest/core.py +++ b/_pytest/core.py @@ -24,12 +24,28 @@ def get(self, name): return TagTracerSub(self, (name,)) + def format_message(self, tags, args): + if isinstance(args[-1], dict): + extra = args[-1] + args = args[:-1] + else: + extra = {} + + content = " ".join(map(str, args)) + indent = " " * self.indent + + lines = [ + "%s%s [%s]\n" %(indent, content, ":".join(tags)) + ] + + for name, value in extra.items(): + lines.append("%s %s: %s\n" % (indent, name, value)) + return lines + def processmessage(self, tags, args): - if self.writer is not None: - if args: - indent = " " * self.indent - content = " ".join(map(str, args)) - self.writer("%s%s [%s]\n" %(indent, content, ":".join(tags))) + if self.writer is not None and args: + lines = self.format_message(tags, args) + self.writer(''.join(lines)) try: self._tag2proc[tags](tags, args) except KeyError: diff -r 16f68fdd818016a198a47d30a859030eec5c9a7f -r 8cc3505ca7801cfff4f9a688e824abeaf0f1b7fc testing/test_core.py --- a/testing/test_core.py +++ b/testing/test_core.py @@ -612,6 +612,19 @@ assert names == ['hello', ' line1', ' line2', ' line3', ' line4', ' line5', 'last'] + def test_readable_output_dictargs(self): + from _pytest.core import TagTracer + rootlogger = TagTracer() + + out = rootlogger.format_message(['test'], [1]) + assert out == ['1 [test]\n'] + + out2= rootlogger.format_message(['test'], ['test', {'a':1}]) + assert out2 ==[ + 'test [test]\n', + ' a: 1\n' + ] + def test_setprocessor(self): from _pytest.core import TagTracer rootlogger = TagTracer() Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Nov 29 21:22:55 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 29 Nov 2012 20:22:55 -0000 Subject: [py-svn] commit/pytest-pep8: hpk42: fix issue2: make pep8 interoperate with --strict runs Message-ID: <20121129202255.27739.32462@bitbucket05.managed.contegix.com> 1 new commit in pytest-pep8: https://bitbucket.org/hpk42/pytest-pep8/changeset/93ebd08f41f9/ changeset: 93ebd08f41f9 user: hpk42 date: 2012-11-29 21:22:21 summary: fix issue2: make pep8 interoperate with --strict runs affected #: 4 files diff -r e7c446c820180183af8c9f5ecc54f4ee79e9a8a6 -r 93ebd08f41f93143242b7088a93673e751234a11 CHANGELOG --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +1.0.4 +--------------------------------- + +- fix issue2: make pep8 interoperate with --strict runs + 1.0.3 ---------------------------------------------- diff -r e7c446c820180183af8c9f5ecc54f4ee79e9a8a6 -r 93ebd08f41f93143242b7088a93673e751234a11 pytest_pep8.py --- a/pytest_pep8.py +++ b/pytest_pep8.py @@ -3,7 +3,7 @@ import pytest import pep8 -__version__ = '1.0.3' +__version__ = '1.0.4' HISTKEY = "pep8/mtimes" @@ -51,7 +51,7 @@ def __init__(self, path, parent, pep8ignore, max_line_length): super(Pep8Item, self).__init__(path, parent) - self.keywords["pep8"] = pytest.mark.pep8 + self.keywords["pep8"] = True self.pep8ignore = pep8ignore self.max_line_length = max_line_length diff -r e7c446c820180183af8c9f5ecc54f4ee79e9a8a6 -r 93ebd08f41f93143242b7088a93673e751234a11 setup.py --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ name='pytest-pep8', description='pytest plugin to check PEP8 requirements', long_description=open("README.txt").read(), - version='1.0.3', + version='1.0.4', author='Holger Krekel and Ronny Pfannschmidt', author_email='holger.krekel at gmail.com', url='http://bitbucket.org/hpk42/pytest-pep8/', diff -r e7c446c820180183af8c9f5ecc54f4ee79e9a8a6 -r 93ebd08f41f93143242b7088a93673e751234a11 test_pep8.py --- a/test_pep8.py +++ b/test_pep8.py @@ -134,3 +134,9 @@ f.close() result = testdir.runpytest("--pep8", x, "-s") result.stdout.fnmatch_lines("*non-ascii comment*") + + +def test_strict(testdir): + testdir.makepyfile("") + result = testdir.runpytest("--strict", "--pep8") + assert result.ret == 0 Repository URL: https://bitbucket.org/hpk42/pytest-pep8/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Thu Nov 29 21:24:28 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Thu, 29 Nov 2012 20:24:28 -0000 Subject: [py-svn] commit/pytest-pep8: hpk42: Added tag 1.0.4 for changeset 93ebd08f41f9 Message-ID: <20121129202428.6697.90588@bitbucket12.managed.contegix.com> 1 new commit in pytest-pep8: https://bitbucket.org/hpk42/pytest-pep8/changeset/8b4bca7937d3/ changeset: 8b4bca7937d3 user: hpk42 date: 2012-11-29 21:24:20 summary: Added tag 1.0.4 for changeset 93ebd08f41f9 affected #: 1 file diff -r 93ebd08f41f93143242b7088a93673e751234a11 -r 8b4bca7937d3bc1cfa80d502d65968da69ad6481 .hgtags --- a/.hgtags +++ b/.hgtags @@ -7,3 +7,4 @@ dc4ae3a75b4c285c81c7044232b0426a23c9a221 1.0.1 2e5abd094f9f1abe88d764f3070dbfdb0823213f 1.0.2 f8a92d028dcd09ecd737d46b62585ef89571aa4d 1.0.3 +93ebd08f41f93143242b7088a93673e751234a11 1.0.4 Repository URL: https://bitbucket.org/hpk42/pytest-pep8/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. From commits-noreply at bitbucket.org Fri Nov 30 12:20:01 2012 From: commits-noreply at bitbucket.org (Bitbucket) Date: Fri, 30 Nov 2012 11:20:01 -0000 Subject: [py-svn] commit/pytest: hpk42: when informations gets truncated, mention use of "-vv" to see it. Message-ID: <20121130112001.1929.83434@bitbucket24.managed.contegix.com> 1 new commit in pytest: https://bitbucket.org/hpk42/pytest/changeset/4cff6242f274/ changeset: 4cff6242f274 user: hpk42 date: 2012-11-30 12:18:12 summary: when informations gets truncated, mention use of "-vv" to see it. affected #: 2 files diff -r 8cc3505ca7801cfff4f9a688e824abeaf0f1b7fc -r 4cff6242f274afa4a47ede78139e63fdb726828b _pytest/assertion/__init__.py --- a/_pytest/assertion/__init__.py +++ b/_pytest/assertion/__init__.py @@ -78,7 +78,7 @@ if new_expl: # Don't include pageloads of data unless we are very verbose (-vv) if len(''.join(new_expl[1:])) > 80*8 and item.config.option.verbose < 2: - new_expl[1:] = ['Detailed information too verbose, truncated'] + new_expl[1:] = ['Detailed information truncated, use "-vv" to see'] res = '\n~'.join(new_expl) if item.config.getvalue("assertmode") == "rewrite": # The result will be fed back a python % formatting diff -r 8cc3505ca7801cfff4f9a688e824abeaf0f1b7fc -r 4cff6242f274afa4a47ede78139e63fdb726828b testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -164,7 +164,7 @@ result = testdir.runpytest() result.stdout.fnmatch_lines([ - "*too verbose, truncated*", + "*truncated*use*-vv*", ]) Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.