diff --git a/_pytest/cacheprovider.py b/_pytest/cacheprovider.py index 7fc08fff368..cf28f657ef4 100755 --- a/_pytest/cacheprovider.py +++ b/_pytest/cacheprovider.py @@ -8,13 +8,14 @@ import py import pytest import json -from os.path import sep as _sep, altsep as _altsep +from os.path import sep as _sep, altsep as _altsep, \ + isabs as _isabs, expanduser as _expanduser class Cache(object): def __init__(self, config): self.config = config - self._cachedir = config.rootdir.join(".cache") + self._cachedir = Cache.cache_dir_from_config(config) self.trace = config.trace.root.get("cache") if config.getvalue("cacheclear"): self.trace("clearing cachedir") @@ -22,6 +23,13 @@ def __init__(self, config): self._cachedir.remove() self._cachedir.mkdir() + @staticmethod + def cache_dir_from_config(config): + cache_dir = config.getini("cache_dir") + if _isabs(_expanduser(cache_dir)): + raise ValueError("cache dirname must be relative path, not absolute") + return config.rootdir.join(cache_dir) + def makedir(self, name): """ return a directory path object with the given name. If the directory does not yet exist, it will be created. You can use it @@ -171,6 +179,9 @@ def pytest_addoption(parser): group.addoption( '--cache-clear', action='store_true', dest="cacheclear", help="remove all cache contents at start of test run.") + parser.addini( + "cache_dir", default='.cache', + help="directory name for cache content.") def pytest_cmdline_main(config): diff --git a/doc/en/cache.rst b/doc/en/cache.rst index 688b6dd0468..e4071a8f8ab 100644 --- a/doc/en/cache.rst +++ b/doc/en/cache.rst @@ -1,3 +1,5 @@ +.. _`cache_provider`: + Cache: working with cross-testrun state ======================================= diff --git a/doc/en/customize.rst b/doc/en/customize.rst index ce0a36c11a2..7b5148b09f1 100644 --- a/doc/en/customize.rst +++ b/doc/en/customize.rst @@ -262,3 +262,11 @@ Builtin configuration file options This tells pytest to ignore deprecation warnings and turn all other warnings into errors. For more information please refer to :ref:`warnings`. + +.. confval:: cache_dir + + .. versionadded:: 3.2 + + Sets a directory name where stores content of cache plugin. The directory is + created in rootdir. Default name is ``.cache``. For more information about + cache please refer to :ref:`cache_provider`. diff --git a/testing/test_cache.py b/testing/test_cache.py index 600b5e6d9fc..33afc4899db 100755 --- a/testing/test_cache.py +++ b/testing/test_cache.py @@ -87,7 +87,28 @@ def test_cachefuncarg(cache): assert result.ret == 0 result.stdout.fnmatch_lines(["*1 passed*"]) + def test_custom_cache_dirname(self, testdir): + cache_dir = 'custom_cache_dirname' + testdir.makeini(""" + [pytest] + cache_dir = {cache_dir} + """.format(cache_dir=cache_dir)) + testdir.makepyfile(test_errored='def test_error():\n assert False') + testdir.runpytest() + assert testdir.tmpdir.join(cache_dir).isdir() + @pytest.mark.parametrize('cache_dir', [ + os.path.abspath('tmp'), + pytest.param(os.path.join('~', 'tmp'), marks=pytest.mark.skipif(sys.platform == 'win32', + reason='test for linux pathes')), + ]) + def test_cache_dirname_fail_on_abs(self, testdir, cache_dir): + testdir.makeini(""" + [pytest] + cache_dir = {cache_dir} + """.format(cache_dir=cache_dir)) + pytest.raises(ValueError, "testdir.parseconfigure()", + message="cache dirname must be relative path, not absolute") def test_cache_reportheader(testdir): testdir.makepyfile("""