470 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			470 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
	
import py
 | 
						|
 | 
						|
class TestModule:
 | 
						|
    def test_module_file_not_found(self, testdir):
 | 
						|
        tmpdir = testdir.tmpdir
 | 
						|
        fn = tmpdir.join('nada','no')
 | 
						|
        col = py.test.collect.Module(fn, config=testdir.Config())
 | 
						|
        col.config = testdir.parseconfig(tmpdir)
 | 
						|
        py.test.raises(py.error.ENOENT, col.collect) 
 | 
						|
 | 
						|
    def test_failing_import(self, testdir):
 | 
						|
        modcol = testdir.getmodulecol("import alksdjalskdjalkjals")
 | 
						|
        py.test.raises(ImportError, modcol.collect)
 | 
						|
        py.test.raises(ImportError, modcol.collect)
 | 
						|
        py.test.raises(ImportError, modcol.run)
 | 
						|
 | 
						|
    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()
 | 
						|
        s = result.stdout.str()
 | 
						|
        assert 'mismatch' in s
 | 
						|
        assert 'test_whatever' in s
 | 
						|
 | 
						|
    def test_syntax_error_in_module(self, testdir):
 | 
						|
        modcol = testdir.getmodulecol("this is a syntax error") 
 | 
						|
        py.test.raises(SyntaxError, modcol.collect)
 | 
						|
        py.test.raises(SyntaxError, modcol.collect)
 | 
						|
        py.test.raises(SyntaxError, modcol.run)
 | 
						|
 | 
						|
    def test_module_considers_pluginmanager_at_import(self, testdir):
 | 
						|
        modcol = testdir.getmodulecol("pytest_plugins='xasdlkj',")
 | 
						|
        py.test.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
 | 
						|
 | 
						|
if py.std.sys.version_info > (3, 0):
 | 
						|
    _func_name_attr = "__name__"
 | 
						|
else:
 | 
						|
    _func_name_attr = "func_name"
 | 
						|
 | 
						|
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, py.test.collect.Generator)
 | 
						|
        gencolitems = gencol.collect()
 | 
						|
        assert len(gencolitems) == 2
 | 
						|
        assert isinstance(gencolitems[0], py.test.collect.Function)
 | 
						|
        assert isinstance(gencolitems[1], py.test.collect.Function)
 | 
						|
        assert gencolitems[0].name == '[0]'
 | 
						|
        assert getattr(gencolitems[0].obj, _func_name_attr) == '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, py.test.collect.Generator)
 | 
						|
        gencolitems = gencol.collect()
 | 
						|
        assert len(gencolitems) == 2
 | 
						|
        assert isinstance(gencolitems[0], py.test.collect.Function)
 | 
						|
        assert isinstance(gencolitems[1], py.test.collect.Function)
 | 
						|
        assert gencolitems[0].name == '[0]'
 | 
						|
        assert getattr(gencolitems[0].obj, _func_name_attr) == '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, py.test.collect.Generator)
 | 
						|
        gencolitems = gencol.collect()
 | 
						|
        assert len(gencolitems) == 2
 | 
						|
        assert isinstance(gencolitems[0], py.test.collect.Function)
 | 
						|
        assert isinstance(gencolitems[1], py.test.collect.Function)
 | 
						|
        assert gencolitems[0].name == "['seventeen']"
 | 
						|
        assert getattr(gencolitems[0].obj, _func_name_attr) == 'func1'
 | 
						|
        assert gencolitems[1].name == "['fortytwo']"
 | 
						|
        assert getattr(gencolitems[1].obj, _func_name_attr) == '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, py.test.collect.Generator)
 | 
						|
        py.test.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, py.test.collect.Generator)
 | 
						|
        gencolitems = gencol.collect()
 | 
						|
        assert len(gencolitems) == 2
 | 
						|
        assert isinstance(gencolitems[0], py.test.collect.Function)
 | 
						|
        assert isinstance(gencolitems[1], py.test.collect.Function)
 | 
						|
        assert gencolitems[0].name == "['m1']"
 | 
						|
        assert getattr(gencolitems[0].obj, _func_name_attr) == 'func1'
 | 
						|
        assert gencolitems[1].name == "['m2']"
 | 
						|
        assert getattr(gencolitems[1].obj, _func_name_attr) == 'func1'        
 | 
						|
 | 
						|
    def test_order_of_execution_generator_same_codeline(self, testdir, tmpdir):
 | 
						|
        o = testdir.makepyfile("""
 | 
						|
            def test_generative_order_of_execution():
 | 
						|
                import py
 | 
						|
                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
 | 
						|
                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 
 | 
						|
 | 
						|
class TestFunction:
 | 
						|
    def test_getmodulecollector(self, testdir):
 | 
						|
        item = testdir.getitem("def test_func(): pass")
 | 
						|
        modcol = item.getparent(py.test.collect.Module)
 | 
						|
        assert isinstance(modcol, py.test.collect.Module)
 | 
						|
        assert hasattr(modcol.obj, 'test_func')
 | 
						|
        
 | 
						|
    def test_function_equality(self, testdir, tmpdir):
 | 
						|
        config = testdir.reparseconfig()
 | 
						|
        f1 = py.test.collect.Function(name="name", config=config,
 | 
						|
                                      args=(1,), callobj=isinstance)
 | 
						|
        f2 = py.test.collect.Function(name="name",config=config, 
 | 
						|
                                      args=(1,), callobj=py.builtin.callable)
 | 
						|
        assert not f1 == f2
 | 
						|
        assert f1 != f2
 | 
						|
        f3 = py.test.collect.Function(name="name", config=config, 
 | 
						|
                                      args=(1,2), callobj=py.builtin.callable)
 | 
						|
        assert not f3 == f2
 | 
						|
        assert f3 != f2
 | 
						|
 | 
						|
        assert not f3 == f1
 | 
						|
        assert f3 != f1
 | 
						|
 | 
						|
        f1_b = py.test.collect.Function(name="name", config=config, 
 | 
						|
                                      args=(1,), callobj=isinstance)
 | 
						|
        assert f1 == f1_b
 | 
						|
        assert not f1 != f1_b
 | 
						|
 | 
						|
    def test_function_equality_with_callspec(self, testdir, tmpdir):
 | 
						|
        config = testdir.reparseconfig()
 | 
						|
        class callspec1:
 | 
						|
            param = 1
 | 
						|
            funcargs = {}
 | 
						|
            id = "hello"
 | 
						|
        class callspec2:
 | 
						|
            param = 1
 | 
						|
            funcargs = {}
 | 
						|
            id = "world"
 | 
						|
        f5 = py.test.collect.Function(name="name", config=config, 
 | 
						|
                                      callspec=callspec1, callobj=isinstance)
 | 
						|
        f5b = py.test.collect.Function(name="name", config=config, 
 | 
						|
                                      callspec=callspec2, callobj=isinstance)
 | 
						|
        assert f5 != f5b
 | 
						|
        assert not (f5 == f5b)
 | 
						|
 | 
						|
    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 = modcol.collect_by_name("test_pass")
 | 
						|
        assert isinstance(fn1, py.test.collect.Function)
 | 
						|
        fn2 = modcol.collect_by_name("test_pass")
 | 
						|
        assert isinstance(fn2, py.test.collect.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 = modcol.collect_by_name("test_fail")
 | 
						|
        assert isinstance(fn3, py.test.collect.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_makeitem(self, testdir):
 | 
						|
        testdir.makeconftest("""
 | 
						|
            import py
 | 
						|
            class MyFunction(py.test.collect.Function):
 | 
						|
                pass
 | 
						|
            def pytest_pycollect_makeitem(collector, name, obj):
 | 
						|
                if name == "some":
 | 
						|
                    return MyFunction(name, collector)
 | 
						|
        """)
 | 
						|
        testdir.makepyfile("def some(): pass")
 | 
						|
        result = testdir.runpytest("--collectonly")
 | 
						|
        result.stdout.fnmatch_lines([
 | 
						|
            "*MyFunction*some*",
 | 
						|
        ])
 | 
						|
        
 | 
						|
    def test_makeitem_non_underscore(self, testdir, monkeypatch):
 | 
						|
        modcol = testdir.getmodulecol("def _hello(): pass")
 | 
						|
        l = []
 | 
						|
        monkeypatch.setattr(py.test.collect.Module, 'makeitem', 
 | 
						|
            lambda self, name, obj: l.append(name))
 | 
						|
        l = modcol.collect()
 | 
						|
        assert '_hello' not in l
 | 
						|
 | 
						|
 | 
						|
class TestReportinfo:
 | 
						|
        
 | 
						|
    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 = modcol.collect_by_name("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 = modcol.collect_by_name("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_setup_only_available_in_subdir(testdir):
 | 
						|
    sub1 = testdir.mkpydir("sub1")
 | 
						|
    sub2 = testdir.mkpydir("sub2")
 | 
						|
    sub1.join("conftest.py").write(py.code.Source("""
 | 
						|
        import py
 | 
						|
        def pytest_runtest_setup(item):
 | 
						|
            assert item.fspath.purebasename == "test_in_sub1"
 | 
						|
        def pytest_runtest_call(item):
 | 
						|
            assert item.fspath.purebasename == "test_in_sub1"
 | 
						|
        def pytest_runtest_teardown(item):
 | 
						|
            assert item.fspath.purebasename == "test_in_sub1"
 | 
						|
    """))
 | 
						|
    sub2.join("conftest.py").write(py.code.Source("""
 | 
						|
        import py
 | 
						|
        def pytest_runtest_setup(item):
 | 
						|
            assert item.fspath.purebasename == "test_in_sub2"
 | 
						|
        def pytest_runtest_call(item):
 | 
						|
            assert item.fspath.purebasename == "test_in_sub2"
 | 
						|
        def pytest_runtest_teardown(item):
 | 
						|
            assert item.fspath.purebasename == "test_in_sub2"
 | 
						|
    """))
 | 
						|
    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")
 | 
						|
    result.stdout.fnmatch_lines([
 | 
						|
        "*2 passed*"
 | 
						|
    ])
 | 
						|
 | 
						|
def test_generate_tests_only_done_in_subdir(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_modulecol_roundtrip(testdir):
 | 
						|
    modcol = testdir.getmodulecol("pass", withinit=True)
 | 
						|
    trail = modcol.config._rootcol.totrail(modcol)
 | 
						|
    newcol = modcol.config._rootcol.fromtrail(trail)
 | 
						|
    assert modcol.name == newcol.name
 | 
						|
 | 
						|
 | 
						|
class TestTracebackCutting:
 | 
						|
    def test_skip_simple(self):
 | 
						|
        excinfo = py.test.raises(py.test.skip.Exception, 'py.test.skip("xxx")')
 | 
						|
        assert excinfo.traceback[-1].frame.code.name == "skip"
 | 
						|
        assert excinfo.traceback[-1].ishidden()
 | 
						|
 | 
						|
    def test_traceback_argsetup(self, testdir):
 | 
						|
        testdir.makeconftest("""
 | 
						|
            def pytest_funcarg__hello(request):
 | 
						|
                raise ValueError("xyz")
 | 
						|
        """)
 | 
						|
        p = testdir.makepyfile("def test(hello): pass")
 | 
						|
        result = testdir.runpytest(p)
 | 
						|
        assert result.ret != 0
 | 
						|
        out = result.stdout.str()
 | 
						|
        assert out.find("xyz") != -1
 | 
						|
        assert out.find("conftest.py:2: ValueError") != -1
 | 
						|
        numentries = out.count("_ _ _") # separator for traceback entries
 | 
						|
        assert numentries == 0
 | 
						|
 | 
						|
        result = testdir.runpytest("--fulltrace", p)
 | 
						|
        out = result.stdout.str()
 | 
						|
        assert out.find("conftest.py:2: ValueError") != -1
 | 
						|
        numentries = out.count("_ _ _ _") # separator for traceback entries
 | 
						|
        assert numentries >3
 |