Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configure Pytest discovery to ignore class name

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 incorrect class to be imported.

I am testing a django project that uses Factory Boy. http://factoryboy.readthedocs.org/en/latest/ to build out a Django model named Testimonial.

like so:

class TestimonialFactory(factory.Factory):
    class Meta:
        model = models.Testimonial

This issue is that factory.Factory does not have an __init__(). So py.test sees Testimonials and tries to run. Which in turn tries to insert a record into the database within the pytest discovery phase (hilarity and failures ensue).

I have hacked a workaround by changing the pytest.ini to look for Test classes to start with Check instead of Test:

[pytest]
python_classes=Check

This is not really what I want. Is there any way to explicitly tell py.test to ignore a test of a certain name?

like image 419
jdennison Avatar asked Jul 07 '14 15:07

jdennison


2 Answers

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

like image 67
tday03 Avatar answered Oct 07 '22 12:10

tday03


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.

like image 21
rdadolf Avatar answered Oct 07 '22 11:10

rdadolf