Configure Pytest discovery to ignore class name

后端 未结 5 896
生来不讨喜
生来不讨喜 2021-01-11 14:16

Pytest\'s default discovery rules will import all Class starting with Test that do not have an __init__(). I have a situation where this causes an

相关标签:
5条回答
  • 2021-01-11 14:31

    Here is a simple solution that I use, but has some overhead.

    class DisablePyTestCollectionMixin(object):
      __test__ = False
    
    class TestimonialFactory(DisablePyTestCollectionMixin):
      pass
    

    Based on: https://github.com/pytest-dev/pytest/issues/1879

    0 讨论(0)
  • 2021-01-11 14:34

    This is an older question, but it seems to be the only relevant hit on stackoverflow, so I thought I'd leave an alternate answer here for posterity.

    Another workaround involves disabling all classname-based discovery and relying on subclass discovery only. In other words:

    In your config file: (setup.cfg or pytest.ini):

    [pytest]
    python_classes = 
    

    And in your test files:

    class TestWillNotBeRun(object):
      # Not a subclass of unittest.TestCase, so not collected regardless of name
    class TestWillBeRun(unittest.TestCase):
      # Still okay to use TestName convention for readability
      # It just doesn't actually do anything.
    class StillGoingToBeRun(unittest.TestCase): 
      # Relying on subclassing means *all* subclasses will be picked up, regardless of name
    

    One of the advantages of this is that it doesn't require changing your non-test class names. For a library where these classes are exposed to users, there can be good reasons for not renaming. Also, it doesn't require massive renaming of test classes (since they can now be literally anything). Finally, unlike name-based discovery, it's unlikely that non-test code will somehow be a subclass of unittest.TestCase. (I'm sure someone out there is an exception.)

    The drawback is that you must ensure that all your test classes must be subclasses of unittest.TestCase. For all of my code, that's already true, so there was no cost. That's not necessarily universally true, though.

    0 讨论(0)
  • 2021-01-11 14:41

    Put all tests into files starting with test_ and add this to your pytest.ini:

    [pytest]
    python_files=test_*.py
    

    This will instruct pytest to discover tests only in test_*.py files.

    0 讨论(0)
  • 2021-01-11 14:53

    The configuration options seem to only be prefixes or globs, so I don't think you can exclude a specific file name: https://pytest.org/latest/customize.html#confval-python_classes

    I think renaming your class (MyTestimonialFactory) or moving it outside of the discovery path would be the easy fix here.

    That said, I still think you could use one of the collection hooks to skip or remove that class during collection. Perhaps pytest_pycollect_makeitem, as described here: https://docs.pytest.org/en/latest/writing_plugins.html#collection-hooks

    0 讨论(0)
  • 2021-01-11 14:55

    You should use pytest.ini file with glob matching for class name.

    #pytest.ini file
    [pytest]
    python_classes = !Test
    

    This will make pytest ignore all test classes starting with Test.

    More info here: https://docs.pytest.org/en/latest/example/pythoncollection.html#changing-naming-conventions

    0 讨论(0)
提交回复
热议问题