[pytest-dev] Parametrized autouse fixtures

Thomas De Schampheleire patrickdepinguin at gmail.com
Mon Mar 12 16:47:45 EDT 2018


Hello,

The Kallithea project is a repository hosting and review system,
currently supporting git and hg. We currently have some test cases
that need to be run for these two version control systems.

Previously this was done with some Python magic, which was now
simplified and made more explicit in commit:
https://kallithea-scm.org/repos/kallithea/changeset/45a281a0f36ff59ffaa4aa0107fabfc1a6310251

but I assume it can be made more automatic with pytest fixtures. I was
thinking to use an autouse, parametrized fixture to set the backend to
'hg' and 'git' respectively. But I can't make it work.

Here is the change I did on top of the mentioned commit:

diff --git a/kallithea/tests/vcs/base.py b/kallithea/tests/vcs/base.py
--- a/kallithea/tests/vcs/base.py
+++ b/kallithea/tests/vcs/base.py
@@ -5,6 +5,7 @@ InMemoryChangeset class is working prope
 import os
 import time
 import datetime
+import pytest

 from kallithea.lib import vcs
 from kallithea.lib.vcs.nodes import FileNode
@@ -27,6 +28,11 @@ class _BackendTestMixin(object):
     """
     recreate_repo_per_test = True

+    @pytest.fixture(autouse=True,
+                    params=['hg', 'git'])
+    def set_backend_alias(cls, request):
+        cls.backend_alias = request.param
+
     @classmethod
     def get_backend(cls):
         return vcs.get_backend(cls.backend_alias)
diff --git a/kallithea/tests/vcs/test_archives.py
b/kallithea/tests/vcs/test_archives.py
--- a/kallithea/tests/vcs/test_archives.py
+++ b/kallithea/tests/vcs/test_archives.py
@@ -14,7 +14,7 @@ from kallithea.tests.vcs.base import _Ba
 from kallithea.tests.vcs.conf import TESTS_TMP_PATH


-class ArchivesTestCaseMixin(_BackendTestMixin):
+class TestArchivesTestCaseMixin(_BackendTestMixin):

     @classmethod
     def _get_commits(cls):
@@ -95,11 +95,3 @@ class ArchivesTestCaseMixin(_BackendTest
     def test_archive_prefix_with_leading_slash(self):
         with pytest.raises(VCSError):
             self.tip.fill_archive(prefix='/any')
-
-
-class TestGitArchive(ArchivesTestCaseMixin):
-    backend_alias = 'git'
-
-
-class TestHgArchive(ArchivesTestCaseMixin):
-    backend_alias = 'hg'



but when running this I get:

$  pytest kallithea/tests/vcs/test_archives.py
Test session starts (platform: linux2, Python 2.7.14, pytest 3.4.2,
pytest-sugar 0.9.1)
benchmark: 3.1.1 (defaults: timer=time.time disable_gc=False
min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10
warmup=False warmup_iterations=100000)
rootdir: /home/tdescham/repo/contrib/kallithea/kallithea-review,
inifile: pytest.ini
plugins: sugar-0.9.1, localserver-0.4.1, benchmark-3.1.1


――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
ERROR at setup of TestArchivesTestCaseMixin.test_archive_zip[hg]
―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/vcs/base.py:70: in setup_class
    Backend = cls.get_backend()
kallithea/tests/vcs/base.py:38: in get_backend
    return vcs.get_backend(cls.backend_alias)
E   AttributeError: type object 'TestArchivesTestCaseMixin' has no
attribute 'backend_alias'


                                                        7% ▊

――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
ERROR at setup of TestArchivesTestCaseMixin.test_archive_zip[git]
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
kallithea/tests/vcs/base.py:70: in setup_class
    Backend = cls.get_backend()
kallithea/tests/vcs/base.py:38: in get_backend
    return vcs.get_backend(cls.backend_alias)
E   AttributeError: type object 'TestArchivesTestCaseMixin' has no
attribute 'backend_alias'


                                                       14% █▌

[..]



So the parametrization seems to work because each test is run twice,
but I can't seem to find the right way to set the backend_alias, such
that a later call from a classmethod works correctly.

I found some possibly useful magic by nicoddemus but could not make
that work either:
https://github.com/pytest-dev/pytest/issues/2618#issuecomment-318519875

Is it possible to achieve what I want, without changing each test
method to take a fixture explicitly?

Thanks,
Thomas


More information about the pytest-dev mailing list