summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/tools/pytest/testing/acceptance_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/tools/pytest/testing/acceptance_test.py')
-rw-r--r--testing/web-platform/tests/tools/pytest/testing/acceptance_test.py695
1 files changed, 695 insertions, 0 deletions
diff --git a/testing/web-platform/tests/tools/pytest/testing/acceptance_test.py b/testing/web-platform/tests/tools/pytest/testing/acceptance_test.py
new file mode 100644
index 000000000..9bc3a191a
--- /dev/null
+++ b/testing/web-platform/tests/tools/pytest/testing/acceptance_test.py
@@ -0,0 +1,695 @@
+import sys
+
+import _pytest._code
+import py
+import pytest
+from _pytest.main import EXIT_NOTESTSCOLLECTED, EXIT_USAGEERROR
+
+
+class TestGeneralUsage:
+ def test_config_error(self, testdir):
+ testdir.makeconftest("""
+ def pytest_configure(config):
+ import pytest
+ raise pytest.UsageError("hello")
+ """)
+ result = testdir.runpytest(testdir.tmpdir)
+ assert result.ret != 0
+ result.stderr.fnmatch_lines([
+ '*ERROR: hello'
+ ])
+
+ def test_root_conftest_syntax_error(self, testdir):
+ testdir.makepyfile(conftest="raise SyntaxError\n")
+ result = testdir.runpytest()
+ result.stderr.fnmatch_lines(["*raise SyntaxError*"])
+ assert result.ret != 0
+
+ def test_early_hook_error_issue38_1(self, testdir):
+ testdir.makeconftest("""
+ def pytest_sessionstart():
+ 0 / 0
+ """)
+ result = testdir.runpytest(testdir.tmpdir)
+ assert result.ret != 0
+ # tracestyle is native by default for hook failures
+ result.stdout.fnmatch_lines([
+ '*INTERNALERROR*File*conftest.py*line 2*',
+ '*0 / 0*',
+ ])
+ result = testdir.runpytest(testdir.tmpdir, "--fulltrace")
+ assert result.ret != 0
+ # tracestyle is native by default for hook failures
+ result.stdout.fnmatch_lines([
+ '*INTERNALERROR*def pytest_sessionstart():*',
+ '*INTERNALERROR*0 / 0*',
+ ])
+
+ def test_early_hook_configure_error_issue38(self, testdir):
+ testdir.makeconftest("""
+ def pytest_configure():
+ 0 / 0
+ """)
+ result = testdir.runpytest(testdir.tmpdir)
+ assert result.ret != 0
+ # here we get it on stderr
+ result.stderr.fnmatch_lines([
+ '*INTERNALERROR*File*conftest.py*line 2*',
+ '*0 / 0*',
+ ])
+
+ def test_file_not_found(self, testdir):
+ result = testdir.runpytest("asd")
+ assert result.ret != 0
+ result.stderr.fnmatch_lines(["ERROR: file not found*asd"])
+
+ def test_file_not_found_unconfigure_issue143(self, testdir):
+ testdir.makeconftest("""
+ def pytest_configure():
+ print("---configure")
+ def pytest_unconfigure():
+ print("---unconfigure")
+ """)
+ result = testdir.runpytest("-s", "asd")
+ assert result.ret == 4 # EXIT_USAGEERROR
+ result.stderr.fnmatch_lines(["ERROR: file not found*asd"])
+ result.stdout.fnmatch_lines([
+ "*---configure",
+ "*---unconfigure",
+ ])
+
+
+ def test_config_preparse_plugin_option(self, testdir):
+ testdir.makepyfile(pytest_xyz="""
+ def pytest_addoption(parser):
+ parser.addoption("--xyz", dest="xyz", action="store")
+ """)
+ testdir.makepyfile(test_one="""
+ def test_option(pytestconfig):
+ assert pytestconfig.option.xyz == "123"
+ """)
+ result = testdir.runpytest("-p", "pytest_xyz", "--xyz=123", syspathinsert=True)
+ assert result.ret == 0
+ result.stdout.fnmatch_lines([
+ '*1 passed*',
+ ])
+
+ def test_assertion_magic(self, testdir):
+ p = testdir.makepyfile("""
+ def test_this():
+ x = 0
+ assert x
+ """)
+ result = testdir.runpytest(p)
+ result.stdout.fnmatch_lines([
+ "> assert x",
+ "E assert 0",
+ ])
+ assert result.ret == 1
+
+ def test_nested_import_error(self, testdir):
+ p = testdir.makepyfile("""
+ import import_fails
+ def test_this():
+ assert import_fails.a == 1
+ """)
+ testdir.makepyfile(import_fails="import does_not_work")
+ result = testdir.runpytest(p)
+ result.stdout.fnmatch_lines([
+ #XXX on jython this fails: "> import import_fails",
+ "E ImportError: No module named *does_not_work*",
+ ])
+ assert result.ret == 1
+
+ def test_not_collectable_arguments(self, testdir):
+ p1 = testdir.makepyfile("")
+ p2 = testdir.makefile(".pyc", "123")
+ result = testdir.runpytest(p1, p2)
+ assert result.ret
+ result.stderr.fnmatch_lines([
+ "*ERROR: not found:*%s" %(p2.basename,)
+ ])
+
+ def test_issue486_better_reporting_on_conftest_load_failure(self, testdir):
+ testdir.makepyfile("")
+ testdir.makeconftest("import qwerty")
+ result = testdir.runpytest("--help")
+ result.stdout.fnmatch_lines("""
+ *--version*
+ *warning*conftest.py*
+ """)
+ result = testdir.runpytest()
+ result.stderr.fnmatch_lines("""
+ *ERROR*could not load*conftest.py*
+ """)
+
+
+ def test_early_skip(self, testdir):
+ testdir.mkdir("xyz")
+ testdir.makeconftest("""
+ import pytest
+ def pytest_collect_directory():
+ pytest.skip("early")
+ """)
+ result = testdir.runpytest()
+ assert result.ret == EXIT_NOTESTSCOLLECTED
+ result.stdout.fnmatch_lines([
+ "*1 skip*"
+ ])
+
+ def test_issue88_initial_file_multinodes(self, testdir):
+ testdir.makeconftest("""
+ import pytest
+ class MyFile(pytest.File):
+ def collect(self):
+ return [MyItem("hello", parent=self)]
+ def pytest_collect_file(path, parent):
+ return MyFile(path, parent)
+ class MyItem(pytest.Item):
+ pass
+ """)
+ p = testdir.makepyfile("def test_hello(): pass")
+ result = testdir.runpytest(p, "--collect-only")
+ result.stdout.fnmatch_lines([
+ "*MyFile*test_issue88*",
+ "*Module*test_issue88*",
+ ])
+
+ def test_issue93_initialnode_importing_capturing(self, testdir):
+ testdir.makeconftest("""
+ import sys
+ print ("should not be seen")
+ sys.stderr.write("stder42\\n")
+ """)
+ result = testdir.runpytest()
+ assert result.ret == EXIT_NOTESTSCOLLECTED
+ assert "should not be seen" not in result.stdout.str()
+ assert "stderr42" not in result.stderr.str()
+
+ def test_conftest_printing_shows_if_error(self, testdir):
+ testdir.makeconftest("""
+ print ("should be seen")
+ assert 0
+ """)
+ result = testdir.runpytest()
+ assert result.ret != 0
+ assert "should be seen" in result.stdout.str()
+
+ @pytest.mark.skipif(not hasattr(py.path.local, 'mksymlinkto'),
+ reason="symlink not available on this platform")
+ def test_chdir(self, testdir):
+ testdir.tmpdir.join("py").mksymlinkto(py._pydir)
+ p = testdir.tmpdir.join("main.py")
+ p.write(_pytest._code.Source("""
+ import sys, os
+ sys.path.insert(0, '')
+ import py
+ print (py.__file__)
+ print (py.__path__)
+ os.chdir(os.path.dirname(os.getcwd()))
+ print (py.log)
+ """))
+ result = testdir.runpython(p)
+ assert not result.ret
+
+ def test_issue109_sibling_conftests_not_loaded(self, testdir):
+ sub1 = testdir.tmpdir.mkdir("sub1")
+ sub2 = testdir.tmpdir.mkdir("sub2")
+ sub1.join("conftest.py").write("assert 0")
+ result = testdir.runpytest(sub2)
+ assert result.ret == EXIT_NOTESTSCOLLECTED
+ sub2.ensure("__init__.py")
+ p = sub2.ensure("test_hello.py")
+ result = testdir.runpytest(p)
+ assert result.ret == EXIT_NOTESTSCOLLECTED
+ result = testdir.runpytest(sub1)
+ assert result.ret == EXIT_USAGEERROR
+
+ def test_directory_skipped(self, testdir):
+ testdir.makeconftest("""
+ import pytest
+ def pytest_ignore_collect():
+ pytest.skip("intentional")
+ """)
+ testdir.makepyfile("def test_hello(): pass")
+ result = testdir.runpytest()
+ assert result.ret == EXIT_NOTESTSCOLLECTED
+ result.stdout.fnmatch_lines([
+ "*1 skipped*"
+ ])
+
+ def test_multiple_items_per_collector_byid(self, testdir):
+ c = testdir.makeconftest("""
+ import pytest
+ class MyItem(pytest.Item):
+ def runtest(self):
+ pass
+ class MyCollector(pytest.File):
+ def collect(self):
+ return [MyItem(name="xyz", parent=self)]
+ def pytest_collect_file(path, parent):
+ if path.basename.startswith("conftest"):
+ return MyCollector(path, parent)
+ """)
+ result = testdir.runpytest(c.basename+"::"+"xyz")
+ assert result.ret == 0
+ result.stdout.fnmatch_lines([
+ "*1 pass*",
+ ])
+
+ def test_skip_on_generated_funcarg_id(self, testdir):
+ testdir.makeconftest("""
+ import pytest
+ def pytest_generate_tests(metafunc):
+ metafunc.addcall({'x': 3}, id='hello-123')
+ def pytest_runtest_setup(item):
+ print (item.keywords)
+ if 'hello-123' in item.keywords:
+ pytest.skip("hello")
+ assert 0
+ """)
+ p = testdir.makepyfile("""def test_func(x): pass""")
+ res = testdir.runpytest(p)
+ assert res.ret == 0
+ res.stdout.fnmatch_lines(["*1 skipped*"])
+
+ def test_direct_addressing_selects(self, testdir):
+ p = testdir.makepyfile("""
+ def pytest_generate_tests(metafunc):
+ metafunc.addcall({'i': 1}, id="1")
+ metafunc.addcall({'i': 2}, id="2")
+ def test_func(i):
+ pass
+ """)
+ res = testdir.runpytest(p.basename + "::" + "test_func[1]")
+ assert res.ret == 0
+ res.stdout.fnmatch_lines(["*1 passed*"])
+
+ def test_direct_addressing_notfound(self, testdir):
+ p = testdir.makepyfile("""
+ def test_func():
+ pass
+ """)
+ res = testdir.runpytest(p.basename + "::" + "test_notfound")
+ assert res.ret
+ res.stderr.fnmatch_lines(["*ERROR*not found*"])
+
+ def test_docstring_on_hookspec(self):
+ from _pytest import hookspec
+ for name, value in vars(hookspec).items():
+ if name.startswith("pytest_"):
+ assert value.__doc__, "no docstring for %s" % name
+
+ def test_initialization_error_issue49(self, testdir):
+ testdir.makeconftest("""
+ def pytest_configure():
+ x
+ """)
+ result = testdir.runpytest()
+ assert result.ret == 3 # internal error
+ result.stderr.fnmatch_lines([
+ "INTERNAL*pytest_configure*",
+ "INTERNAL*x*",
+ ])
+ assert 'sessionstarttime' not in result.stderr.str()
+
+ @pytest.mark.parametrize('lookfor', ['test_fun.py', 'test_fun.py::test_a'])
+ def test_issue134_report_syntaxerror_when_collecting_member(self, testdir, lookfor):
+ testdir.makepyfile(test_fun="""
+ def test_a():
+ pass
+ def""")
+ result = testdir.runpytest(lookfor)
+ result.stdout.fnmatch_lines(['*SyntaxError*'])
+ if '::' in lookfor:
+ result.stderr.fnmatch_lines([
+ '*ERROR*',
+ ])
+ assert result.ret == 4 # usage error only if item not found
+
+ def test_report_all_failed_collections_initargs(self, testdir):
+ testdir.makepyfile(test_a="def", test_b="def")
+ result = testdir.runpytest("test_a.py::a", "test_b.py::b")
+ result.stderr.fnmatch_lines([
+ "*ERROR*test_a.py::a*",
+ "*ERROR*test_b.py::b*",
+ ])
+
+ def test_namespace_import_doesnt_confuse_import_hook(self, testdir):
+ # Ref #383. Python 3.3's namespace package messed with our import hooks
+ # Importing a module that didn't exist, even if the ImportError was
+ # gracefully handled, would make our test crash.
+ testdir.mkdir('not_a_package')
+ p = testdir.makepyfile("""
+ try:
+ from not_a_package import doesnt_exist
+ except ImportError:
+ # We handle the import error gracefully here
+ pass
+
+ def test_whatever():
+ pass
+ """)
+ res = testdir.runpytest(p.basename)
+ assert res.ret == 0
+
+ def test_unknown_option(self, testdir):
+ result = testdir.runpytest("--qwlkej")
+ result.stderr.fnmatch_lines("""
+ *unrecognized*
+ """)
+
+ def test_getsourcelines_error_issue553(self, testdir, monkeypatch):
+ monkeypatch.setattr("inspect.getsourcelines", None)
+ p = testdir.makepyfile("""
+ def raise_error(obj):
+ raise IOError('source code not available')
+
+ import inspect
+ inspect.getsourcelines = raise_error
+
+ def test_foo(invalid_fixture):
+ pass
+ """)
+ res = testdir.runpytest(p)
+ res.stdout.fnmatch_lines([
+ "*source code not available*",
+ "*fixture 'invalid_fixture' not found",
+ ])
+
+ def test_plugins_given_as_strings(self, tmpdir, monkeypatch):
+ """test that str values passed to main() as `plugins` arg
+ are interpreted as module names to be imported and registered.
+ #855.
+ """
+ with pytest.raises(ImportError) as excinfo:
+ pytest.main([str(tmpdir)], plugins=['invalid.module'])
+ assert 'invalid' in str(excinfo.value)
+
+ p = tmpdir.join('test_test_plugins_given_as_strings.py')
+ p.write('def test_foo(): pass')
+ mod = py.std.types.ModuleType("myplugin")
+ monkeypatch.setitem(sys.modules, 'myplugin', mod)
+ assert pytest.main(args=[str(tmpdir)], plugins=['myplugin']) == 0
+
+ def test_parameterized_with_bytes_regex(self, testdir):
+ p = testdir.makepyfile("""
+ import re
+ import pytest
+ @pytest.mark.parametrize('r', [re.compile(b'foo')])
+ def test_stuff(r):
+ pass
+ """
+ )
+ res = testdir.runpytest(p)
+ res.stdout.fnmatch_lines([
+ '*1 passed*'
+ ])
+
+
+class TestInvocationVariants:
+ def test_earlyinit(self, testdir):
+ p = testdir.makepyfile("""
+ import pytest
+ assert hasattr(pytest, 'mark')
+ """)
+ result = testdir.runpython(p)
+ assert result.ret == 0
+
+ @pytest.mark.xfail("sys.platform.startswith('java')")
+ def test_pydoc(self, testdir):
+ for name in ('py.test', 'pytest'):
+ result = testdir.runpython_c("import %s;help(%s)" % (name, name))
+ assert result.ret == 0
+ s = result.stdout.str()
+ assert 'MarkGenerator' in s
+
+ def test_import_star_py_dot_test(self, testdir):
+ p = testdir.makepyfile("""
+ from py.test import *
+ #collect
+ #cmdline
+ #Item
+ #assert collect.Item is Item
+ #assert collect.Collector is Collector
+ main
+ skip
+ xfail
+ """)
+ result = testdir.runpython(p)
+ assert result.ret == 0
+
+ def test_import_star_pytest(self, testdir):
+ p = testdir.makepyfile("""
+ from pytest import *
+ #Item
+ #File
+ main
+ skip
+ xfail
+ """)
+ result = testdir.runpython(p)
+ assert result.ret == 0
+
+ def test_double_pytestcmdline(self, testdir):
+ p = testdir.makepyfile(run="""
+ import pytest
+ pytest.main()
+ pytest.main()
+ """)
+ testdir.makepyfile("""
+ def test_hello():
+ pass
+ """)
+ result = testdir.runpython(p)
+ result.stdout.fnmatch_lines([
+ "*1 passed*",
+ "*1 passed*",
+ ])
+
+ def test_python_minus_m_invocation_ok(self, testdir):
+ p1 = testdir.makepyfile("def test_hello(): pass")
+ res = testdir.run(py.std.sys.executable, "-m", "pytest", str(p1))
+ assert res.ret == 0
+
+ def test_python_minus_m_invocation_fail(self, testdir):
+ p1 = testdir.makepyfile("def test_fail(): 0/0")
+ res = testdir.run(py.std.sys.executable, "-m", "pytest", str(p1))
+ assert res.ret == 1
+
+ def test_python_pytest_package(self, testdir):
+ p1 = testdir.makepyfile("def test_pass(): pass")
+ res = testdir.run(py.std.sys.executable, "-m", "pytest", str(p1))
+ assert res.ret == 0
+ res.stdout.fnmatch_lines(["*1 passed*"])
+
+ def test_equivalence_pytest_pytest(self):
+ assert pytest.main == py.test.cmdline.main
+
+ def test_invoke_with_string(self, capsys):
+ retcode = pytest.main("-h")
+ assert not retcode
+ out, err = capsys.readouterr()
+ assert "--help" in out
+ pytest.raises(ValueError, lambda: pytest.main(0))
+
+ def test_invoke_with_path(self, tmpdir, capsys):
+ retcode = pytest.main(tmpdir)
+ assert retcode == EXIT_NOTESTSCOLLECTED
+ out, err = capsys.readouterr()
+
+ def test_invoke_plugin_api(self, testdir, capsys):
+ class MyPlugin:
+ def pytest_addoption(self, parser):
+ parser.addoption("--myopt")
+
+ pytest.main(["-h"], plugins=[MyPlugin()])
+ out, err = capsys.readouterr()
+ assert "--myopt" in out
+
+ def test_pyargs_importerror(self, testdir, monkeypatch):
+ monkeypatch.delenv('PYTHONDONTWRITEBYTECODE', False)
+ path = testdir.mkpydir("tpkg")
+ path.join("test_hello.py").write('raise ImportError')
+
+ result = testdir.runpytest("--pyargs", "tpkg.test_hello")
+ assert result.ret != 0
+ # FIXME: It would be more natural to match NOT
+ # "ERROR*file*or*package*not*found*".
+ result.stdout.fnmatch_lines([
+ "*collected 0 items*"
+ ])
+
+ def test_cmdline_python_package(self, testdir, monkeypatch):
+ monkeypatch.delenv('PYTHONDONTWRITEBYTECODE', False)
+ path = testdir.mkpydir("tpkg")
+ path.join("test_hello.py").write("def test_hello(): pass")
+ path.join("test_world.py").write("def test_world(): pass")
+ result = testdir.runpytest("--pyargs", "tpkg")
+ assert result.ret == 0
+ result.stdout.fnmatch_lines([
+ "*2 passed*"
+ ])
+ result = testdir.runpytest("--pyargs", "tpkg.test_hello")
+ assert result.ret == 0
+ result.stdout.fnmatch_lines([
+ "*1 passed*"
+ ])
+
+ def join_pythonpath(what):
+ cur = py.std.os.environ.get('PYTHONPATH')
+ if cur:
+ return str(what) + ':' + cur
+ return what
+ empty_package = testdir.mkpydir("empty_package")
+ monkeypatch.setenv('PYTHONPATH', join_pythonpath(empty_package))
+ result = testdir.runpytest("--pyargs", ".")
+ assert result.ret == 0
+ result.stdout.fnmatch_lines([
+ "*2 passed*"
+ ])
+
+ monkeypatch.setenv('PYTHONPATH', join_pythonpath(testdir))
+ path.join('test_hello.py').remove()
+ result = testdir.runpytest("--pyargs", "tpkg.test_hello")
+ assert result.ret != 0
+ result.stderr.fnmatch_lines([
+ "*not*found*test_hello*",
+ ])
+
+ def test_cmdline_python_package_not_exists(self, testdir):
+ result = testdir.runpytest("--pyargs", "tpkgwhatv")
+ assert result.ret
+ result.stderr.fnmatch_lines([
+ "ERROR*file*or*package*not*found*",
+ ])
+
+ @pytest.mark.xfail(reason="decide: feature or bug")
+ def test_noclass_discovery_if_not_testcase(self, testdir):
+ testpath = testdir.makepyfile("""
+ import unittest
+ class TestHello(object):
+ def test_hello(self):
+ assert self.attr
+
+ class RealTest(unittest.TestCase, TestHello):
+ attr = 42
+ """)
+ reprec = testdir.inline_run(testpath)
+ reprec.assertoutcome(passed=1)
+
+ def test_doctest_id(self, testdir):
+ testdir.makefile('.txt', """
+ >>> x=3
+ >>> x
+ 4
+ """)
+ result = testdir.runpytest("-rf")
+ lines = result.stdout.str().splitlines()
+ for line in lines:
+ if line.startswith("FAIL "):
+ testid = line[5:].strip()
+ break
+ result = testdir.runpytest(testid, '-rf')
+ result.stdout.fnmatch_lines([
+ line,
+ "*1 failed*",
+ ])
+
+ def test_core_backward_compatibility(self):
+ """Test backward compatibility for get_plugin_manager function. See #787."""
+ import _pytest.config
+ assert type(_pytest.config.get_plugin_manager()) is _pytest.config.PytestPluginManager
+
+
+ def test_has_plugin(self, request):
+ """Test hasplugin function of the plugin manager (#932)."""
+ assert request.config.pluginmanager.hasplugin('python')
+
+
+class TestDurations:
+ source = """
+ import time
+ frag = 0.002
+ def test_something():
+ pass
+ def test_2():
+ time.sleep(frag*5)
+ def test_1():
+ time.sleep(frag)
+ def test_3():
+ time.sleep(frag*10)
+ """
+
+ def test_calls(self, testdir):
+ testdir.makepyfile(self.source)
+ result = testdir.runpytest("--durations=10")
+ assert result.ret == 0
+ result.stdout.fnmatch_lines_random([
+ "*durations*",
+ "*call*test_3*",
+ "*call*test_2*",
+ "*call*test_1*",
+ ])
+
+ def test_calls_show_2(self, testdir):
+ testdir.makepyfile(self.source)
+ result = testdir.runpytest("--durations=2")
+ assert result.ret == 0
+ lines = result.stdout.get_lines_after("*slowest*durations*")
+ assert "4 passed" in lines[2]
+
+ def test_calls_showall(self, testdir):
+ testdir.makepyfile(self.source)
+ result = testdir.runpytest("--durations=0")
+ assert result.ret == 0
+ for x in "123":
+ for y in 'call',: #'setup', 'call', 'teardown':
+ for line in result.stdout.lines:
+ if ("test_%s" % x) in line and y in line:
+ break
+ else:
+ raise AssertionError("not found %s %s" % (x,y))
+
+ def test_with_deselected(self, testdir):
+ testdir.makepyfile(self.source)
+ result = testdir.runpytest("--durations=2", "-k test_1")
+ assert result.ret == 0
+ result.stdout.fnmatch_lines([
+ "*durations*",
+ "*call*test_1*",
+ ])
+
+ def test_with_failing_collection(self, testdir):
+ testdir.makepyfile(self.source)
+ testdir.makepyfile(test_collecterror="""xyz""")
+ result = testdir.runpytest("--durations=2", "-k test_1")
+ assert result.ret != 0
+ result.stdout.fnmatch_lines([
+ "*durations*",
+ "*call*test_1*",
+ ])
+
+
+class TestDurationWithFixture:
+ source = """
+ import time
+ frag = 0.001
+ def setup_function(func):
+ time.sleep(frag * 3)
+ def test_1():
+ time.sleep(frag*2)
+ def test_2():
+ time.sleep(frag)
+ """
+ def test_setup_function(self, testdir):
+ testdir.makepyfile(self.source)
+ result = testdir.runpytest("--durations=10")
+ assert result.ret == 0
+
+ result.stdout.fnmatch_lines_random("""
+ *durations*
+ * setup *test_1*
+ * call *test_1*
+ """)
+