From e865f2a2358a8cbbf33018167a33c44598b9da55 Mon Sep 17 00:00:00 2001 From: feuillemorte Date: Fri, 23 Feb 2018 22:49:17 +0300 Subject: [PATCH] #3034 Fix comments --- _pytest/cacheprovider.py | 37 ++++++++++---------- changelog/3034.feature | 2 +- doc/en/cache.rst | 14 +++----- testing/test_cacheprovider.py | 64 ++++++++++++++++------------------- 4 files changed, 54 insertions(+), 63 deletions(-) diff --git a/_pytest/cacheprovider.py b/_pytest/cacheprovider.py index 04dacf83780..0ac1b81023c 100755 --- a/_pytest/cacheprovider.py +++ b/_pytest/cacheprovider.py @@ -5,8 +5,11 @@ ignores the external pytest-cache """ from __future__ import absolute_import, division, print_function + +from collections import OrderedDict + import py -from _pytest.python import Function +import six import pytest import json @@ -176,33 +179,31 @@ class NFPlugin(object): def __init__(self, config): self.config = config self.active = config.option.newfirst - self.all_items = config.cache.get("cache/allitems", {}) + self.cached_nodeids = config.cache.get("cache/nodeids", []) def pytest_collection_modifyitems(self, session, config, items): if self.active: - new_items = [] - other_items = [] + new_items = OrderedDict() + other_items = OrderedDict() for item in items: - mod_timestamp = os.path.getmtime(str(item.fspath)) - if self.all_items and item.nodeid not in self.all_items: - new_items.append((item, mod_timestamp)) + if item.nodeid not in self.cached_nodeids: + new_items[item.nodeid] = item else: - other_items.append((item, mod_timestamp)) + other_items[item.nodeid] = item - items[:] = self._get_increasing_order(new_items) + \ - self._get_increasing_order(other_items) - self.all_items = items + items[:] = self._get_increasing_order(six.itervalues(new_items)) + \ + self._get_increasing_order(six.itervalues(other_items)) + self.cached_nodeids = [x.nodeid for x in items if isinstance(x, pytest.Item)] - def _get_increasing_order(self, test_list): - test_list = sorted(test_list, key=lambda x: x[1], reverse=True) - return [test[0] for test in test_list] + def _get_increasing_order(self, items): + return sorted(items, key=lambda item: item.fspath.mtime(), reverse=True) def pytest_sessionfinish(self, session): config = self.config if config.getoption("cacheshow") or hasattr(config, "slaveinput"): return - config.cache.set("cache/allitems", - [item.nodeid for item in self.all_items if isinstance(item, Function)]) + + config.cache.set("cache/nodeids", self.cached_nodeids) def pytest_addoption(parser): @@ -218,8 +219,8 @@ def pytest_addoption(parser): "repeated fixture setup/teardown") group.addoption( '--nf', '--new-first', action='store_true', dest="newfirst", - help="run all tests but run new tests first, then tests from " - "last modified files, then other tests") + help="run tests from new files first, then the rest of the tests " + "sorted by file mtime") group.addoption( '--cache-show', action='store_true', dest="cacheshow", help="show cache contents, don't perform collection or tests") diff --git a/changelog/3034.feature b/changelog/3034.feature index 62c7ba78d35..12330cdd6a5 100644 --- a/changelog/3034.feature +++ b/changelog/3034.feature @@ -1 +1 @@ -Added new option `--nf`, `--new-first`. This option enables run tests in next order: first new tests, then last modified files with tests in descending order (default order inside file). +New ``--nf``, ``--new-first`` options: run new tests first followed by the rest of the tests, in both cases tests are also sorted by the file modified time, with more recent files coming first. diff --git a/doc/en/cache.rst b/doc/en/cache.rst index 138ff6dfb2c..db72249f9c0 100644 --- a/doc/en/cache.rst +++ b/doc/en/cache.rst @@ -152,6 +152,10 @@ of ``FF`` and dots):: .. _`config.cache`: +New ``--nf``, ``--new-first`` options: run new tests first followed by the rest +of the tests, in both cases tests are also sorted by the file modified time, +with more recent files coming first. + The new config.cache object -------------------------------- @@ -266,13 +270,3 @@ dumps/loads API of the json stdlib module .. automethod:: Cache.get .. automethod:: Cache.set .. automethod:: Cache.makedir - - -New tests first ------------------ - -The plugin provides command line options to run tests in another order: - -* ``--nf``, ``--new-first`` - to run tests in next order: first new tests, then - last modified files with tests in descending order (default order inside file). - diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index b03b02d3429..24dffa1dadd 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -607,22 +607,20 @@ def test_foo_4(): class TestNewFirst(object): def test_newfirst_usecase(self, testdir): - t1 = testdir.mkdir("test_1") - t2 = testdir.mkdir("test_2") - - t1.join("test_1.py").write( - "def test_1(): assert 1\n" - "def test_2(): assert 1\n" - "def test_3(): assert 1\n" - ) - t2.join("test_2.py").write( - "def test_1(): assert 1\n" - "def test_2(): assert 1\n" - "def test_3(): assert 1\n" - ) + testdir.makepyfile(**{ + 'test_1/test_1.py': ''' + def test_1(): assert 1 + def test_2(): assert 1 + def test_3(): assert 1 + ''', + 'test_2/test_2.py': ''' + def test_1(): assert 1 + def test_2(): assert 1 + def test_3(): assert 1 + ''' + }) - path_to_test_1 = str('{}/test_1/test_1.py'.format(testdir.tmpdir)) - os.utime(path_to_test_1, (1, 1)) + testdir.tmpdir.join('test_1/test_1.py').setmtime(1) result = testdir.runpytest("-v") result.stdout.fnmatch_lines([ @@ -645,13 +643,13 @@ def test_newfirst_usecase(self, testdir): "*test_1/test_1.py::test_3 PASSED*", ]) - t1.join("test_1.py").write( + testdir.tmpdir.join("test_1/test_1.py").write( "def test_1(): assert 1\n" "def test_2(): assert 1\n" "def test_3(): assert 1\n" "def test_4(): assert 1\n" ) - os.utime(path_to_test_1, (1, 1)) + testdir.tmpdir.join('test_1/test_1.py').setmtime(1) result = testdir.runpytest("-v", "--nf") @@ -666,22 +664,20 @@ def test_newfirst_usecase(self, testdir): ]) def test_newfirst_parametrize(self, testdir): - t1 = testdir.mkdir("test_1") - t2 = testdir.mkdir("test_2") - - t1.join("test_1.py").write( - "import pytest\n" - "@pytest.mark.parametrize('num', [1, 2])\n" - "def test_1(num): assert num\n" - ) - t2.join("test_2.py").write( - "import pytest\n" - "@pytest.mark.parametrize('num', [1, 2])\n" - "def test_1(num): assert num\n" - ) + testdir.makepyfile(**{ + 'test_1/test_1.py': ''' + import pytest + @pytest.mark.parametrize('num', [1, 2]) + def test_1(num): assert num + ''', + 'test_2/test_2.py': ''' + import pytest + @pytest.mark.parametrize('num', [1, 2]) + def test_1(num): assert num + ''' + }) - path_to_test_1 = str('{}/test_1/test_1.py'.format(testdir.tmpdir)) - os.utime(path_to_test_1, (1, 1)) + testdir.tmpdir.join('test_1/test_1.py').setmtime(1) result = testdir.runpytest("-v") result.stdout.fnmatch_lines([ @@ -700,12 +696,12 @@ def test_newfirst_parametrize(self, testdir): "*test_1/test_1.py::test_1[2*", ]) - t1.join("test_1.py").write( + testdir.tmpdir.join("test_1/test_1.py").write( "import pytest\n" "@pytest.mark.parametrize('num', [1, 2, 3])\n" "def test_1(num): assert num\n" ) - os.utime(path_to_test_1, (1, 1)) + testdir.tmpdir.join('test_1/test_1.py').setmtime(1) result = testdir.runpytest("-v", "--nf")