| import sys |
| |
| import _pytest |
| import pytest |
| import os |
| import shutil |
| |
| pytest_plugins = "pytester", |
| |
| class TestNewAPI: |
| def test_config_cache_makedir(self, testdir): |
| testdir.makeini("[pytest]") |
| config = testdir.parseconfigure() |
| with pytest.raises(ValueError): |
| config.cache.makedir("key/name") |
| |
| p = config.cache.makedir("name") |
| assert p.check() |
| |
| def test_config_cache_dataerror(self, testdir): |
| testdir.makeini("[pytest]") |
| config = testdir.parseconfigure() |
| cache = config.cache |
| pytest.raises(TypeError, lambda: cache.set("key/name", cache)) |
| config.cache.set("key/name", 0) |
| config.cache._getvaluepath("key/name").write("123invalid") |
| val = config.cache.get("key/name", -2) |
| assert val == -2 |
| |
| def test_cache_writefail_cachfile_silent(self, testdir): |
| testdir.makeini("[pytest]") |
| testdir.tmpdir.join('.cache').write('gone wrong') |
| config = testdir.parseconfigure() |
| cache = config.cache |
| cache.set('test/broken', []) |
| |
| @pytest.mark.skipif(sys.platform.startswith('win'), reason='no chmod on windows') |
| def test_cache_writefail_permissions(self, testdir): |
| testdir.makeini("[pytest]") |
| testdir.tmpdir.ensure_dir('.cache').chmod(0) |
| config = testdir.parseconfigure() |
| cache = config.cache |
| cache.set('test/broken', []) |
| |
| @pytest.mark.skipif(sys.platform.startswith('win'), reason='no chmod on windows') |
| def test_cache_failure_warns(self, testdir): |
| testdir.tmpdir.ensure_dir('.cache').chmod(0) |
| testdir.makepyfile(""" |
| def test_error(): |
| raise Exception |
| |
| """) |
| result = testdir.runpytest('-rw') |
| assert result.ret == 1 |
| result.stdout.fnmatch_lines([ |
| "*could not create cache path*", |
| "*1 pytest-warnings*", |
| ]) |
| |
| def test_config_cache(self, testdir): |
| testdir.makeconftest(""" |
| def pytest_configure(config): |
| # see that we get cache information early on |
| assert hasattr(config, "cache") |
| """) |
| testdir.makepyfile(""" |
| def test_session(pytestconfig): |
| assert hasattr(pytestconfig, "cache") |
| """) |
| result = testdir.runpytest() |
| assert result.ret == 0 |
| result.stdout.fnmatch_lines(["*1 passed*"]) |
| |
| def test_cachefuncarg(self, testdir): |
| testdir.makepyfile(""" |
| import pytest |
| def test_cachefuncarg(cache): |
| val = cache.get("some/thing", None) |
| assert val is None |
| cache.set("some/thing", [1]) |
| pytest.raises(TypeError, lambda: cache.get("some/thing")) |
| val = cache.get("some/thing", []) |
| assert val == [1] |
| """) |
| result = testdir.runpytest() |
| assert result.ret == 0 |
| result.stdout.fnmatch_lines(["*1 passed*"]) |
| |
| |
| |
| def test_cache_reportheader(testdir): |
| testdir.makepyfile(""" |
| def test_hello(): |
| pass |
| """) |
| result = testdir.runpytest("-v") |
| result.stdout.fnmatch_lines([ |
| "cachedir: .cache" |
| ]) |
| |
| |
| def test_cache_show(testdir): |
| result = testdir.runpytest("--cache-show") |
| assert result.ret == 0 |
| result.stdout.fnmatch_lines([ |
| "*cache is empty*" |
| ]) |
| testdir.makeconftest(""" |
| def pytest_configure(config): |
| config.cache.set("my/name", [1,2,3]) |
| config.cache.set("other/some", {1:2}) |
| dp = config.cache.makedir("mydb") |
| dp.ensure("hello") |
| dp.ensure("world") |
| """) |
| result = testdir.runpytest() |
| assert result.ret == 5 # no tests executed |
| result = testdir.runpytest("--cache-show") |
| result.stdout.fnmatch_lines_random([ |
| "*cachedir:*", |
| "-*cache values*-", |
| "*my/name contains:", |
| " [1, 2, 3]", |
| "*other/some contains*", |
| " {*1*: 2}", |
| "-*cache directories*-", |
| "*mydb/hello*length 0*", |
| "*mydb/world*length 0*", |
| ]) |
| |
| |
| class TestLastFailed: |
| |
| def test_lastfailed_usecase(self, testdir, monkeypatch): |
| monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) |
| p = testdir.makepyfile(""" |
| def test_1(): |
| assert 0 |
| def test_2(): |
| assert 0 |
| def test_3(): |
| assert 1 |
| """) |
| result = testdir.runpytest() |
| result.stdout.fnmatch_lines([ |
| "*2 failed*", |
| ]) |
| p.write(_pytest._code.Source(""" |
| def test_1(): |
| assert 1 |
| |
| def test_2(): |
| assert 1 |
| |
| def test_3(): |
| assert 0 |
| """)) |
| result = testdir.runpytest("--lf") |
| result.stdout.fnmatch_lines([ |
| "*2 passed*1 desel*", |
| ]) |
| result = testdir.runpytest("--lf") |
| result.stdout.fnmatch_lines([ |
| "*1 failed*2 passed*", |
| ]) |
| result = testdir.runpytest("--lf", "--cache-clear") |
| result.stdout.fnmatch_lines([ |
| "*1 failed*2 passed*", |
| ]) |
| |
| # Run this again to make sure clear-cache is robust |
| if os.path.isdir('.cache'): |
| shutil.rmtree('.cache') |
| result = testdir.runpytest("--lf", "--cache-clear") |
| result.stdout.fnmatch_lines([ |
| "*1 failed*2 passed*", |
| ]) |
| |
| def test_failedfirst_order(self, testdir): |
| testdir.tmpdir.join('test_a.py').write(_pytest._code.Source(""" |
| def test_always_passes(): |
| assert 1 |
| """)) |
| testdir.tmpdir.join('test_b.py').write(_pytest._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", "--ff") |
| # Test order will be failing tests firs |
| result.stdout.fnmatch_lines([ |
| "test_b.py*", |
| "test_a.py*", |
| ]) |
| |
| 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(_pytest._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*", |
| ]) |
| |
| def test_lastfailed_usecase_splice(self, testdir, monkeypatch): |
| monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", 1) |
| testdir.makepyfile(""" |
| def test_1(): |
| assert 0 |
| """) |
| p2 = testdir.tmpdir.join("test_something.py") |
| p2.write(_pytest._code.Source(""" |
| def test_2(): |
| assert 0 |
| """)) |
| result = testdir.runpytest() |
| result.stdout.fnmatch_lines([ |
| "*2 failed*", |
| ]) |
| result = testdir.runpytest("--lf", p2) |
| result.stdout.fnmatch_lines([ |
| "*1 failed*", |
| ]) |
| result = testdir.runpytest("--lf") |
| result.stdout.fnmatch_lines([ |
| "*2 failed*", |
| ]) |
| |
| def test_lastfailed_xpass(self, testdir): |
| testdir.inline_runsource(""" |
| import pytest |
| @pytest.mark.xfail |
| def test_hello(): |
| assert 1 |
| """) |
| config = testdir.parseconfigure() |
| lastfailed = config.cache.get("cache/lastfailed", -1) |
| assert lastfailed == -1 |
| |
| def test_non_serializable_parametrize(self, testdir): |
| """Test that failed parametrized tests with unmarshable parameters |
| don't break pytest-cache. |
| """ |
| testdir.makepyfile(r""" |
| import pytest |
| |
| @pytest.mark.parametrize('val', [ |
| b'\xac\x10\x02G', |
| ]) |
| def test_fail(val): |
| assert False |
| """) |
| result = testdir.runpytest() |
| result.stdout.fnmatch_lines('*1 failed in*') |
| |
| def test_lastfailed_collectfailure(self, testdir, monkeypatch): |
| |
| testdir.makepyfile(test_maybe=""" |
| import py |
| env = py.std.os.environ |
| if '1' == env['FAILIMPORT']: |
| raise ImportError('fail') |
| def test_hello(): |
| assert '0' == env['FAILTEST'] |
| """) |
| |
| def rlf(fail_import, fail_run): |
| monkeypatch.setenv('FAILIMPORT', fail_import) |
| monkeypatch.setenv('FAILTEST', fail_run) |
| |
| testdir.runpytest('-q') |
| config = testdir.parseconfigure() |
| lastfailed = config.cache.get("cache/lastfailed", -1) |
| return lastfailed |
| |
| lastfailed = rlf(fail_import=0, fail_run=0) |
| assert lastfailed == -1 |
| |
| lastfailed = rlf(fail_import=1, fail_run=0) |
| assert list(lastfailed) == ['test_maybe.py'] |
| |
| lastfailed = rlf(fail_import=0, fail_run=1) |
| assert list(lastfailed) == ['test_maybe.py::test_hello'] |
| |
| |
| def test_lastfailed_failure_subset(self, testdir, monkeypatch): |
| |
| testdir.makepyfile(test_maybe=""" |
| import py |
| env = py.std.os.environ |
| if '1' == env['FAILIMPORT']: |
| raise ImportError('fail') |
| def test_hello(): |
| assert '0' == env['FAILTEST'] |
| """) |
| |
| testdir.makepyfile(test_maybe2=""" |
| import py |
| env = py.std.os.environ |
| if '1' == env['FAILIMPORT']: |
| raise ImportError('fail') |
| def test_hello(): |
| assert '0' == env['FAILTEST'] |
| |
| def test_pass(): |
| pass |
| """) |
| |
| def rlf(fail_import, fail_run, args=()): |
| monkeypatch.setenv('FAILIMPORT', fail_import) |
| monkeypatch.setenv('FAILTEST', fail_run) |
| |
| result = testdir.runpytest('-q', '--lf', *args) |
| config = testdir.parseconfigure() |
| lastfailed = config.cache.get("cache/lastfailed", -1) |
| return result, lastfailed |
| |
| result, lastfailed = rlf(fail_import=0, fail_run=0) |
| assert lastfailed == -1 |
| result.stdout.fnmatch_lines([ |
| '*3 passed*', |
| ]) |
| |
| result, lastfailed = rlf(fail_import=1, fail_run=0) |
| assert sorted(list(lastfailed)) == ['test_maybe.py', 'test_maybe2.py'] |
| |
| |
| result, lastfailed = rlf(fail_import=0, fail_run=0, |
| args=('test_maybe2.py',)) |
| assert list(lastfailed) == ['test_maybe.py'] |
| |
| |
| # edge case of test selection - even if we remember failures |
| # from other tests we still need to run all tests if no test |
| # matches the failures |
| result, lastfailed = rlf(fail_import=0, fail_run=0, |
| args=('test_maybe2.py',)) |
| assert list(lastfailed) == ['test_maybe.py'] |
| result.stdout.fnmatch_lines([ |
| '*2 passed*', |
| ]) |
| |
| def test_lastfailed_creates_cache_when_needed(self, testdir): |
| # Issue #1342 |
| testdir.makepyfile(test_empty='') |
| testdir.runpytest('-q', '--lf') |
| assert not os.path.exists('.cache') |
| |
| testdir.makepyfile(test_successful='def test_success():\n assert True') |
| testdir.runpytest('-q', '--lf') |
| assert not os.path.exists('.cache') |
| |
| testdir.makepyfile(test_errored='def test_error():\n assert False') |
| testdir.runpytest('-q', '--lf') |
| assert os.path.exists('.cache') |