38

I am trying to create test classes that aren't unittest based.

This method under this class

class ClassUnderTestTests:

    def test_something(self):

cannot be detected and run when you call py.test from the command line or when you run this test in PyCharm (it's on its own module).

This

def test_something(self):

same method outside of a class can be detected and run.

I'd like to group my tests under classes and unless I'm missing something I'm following the py.test spec to do that.

Environment: Windows 7, PyCharm with py.test set as the test runner.

Michael
  • 913
  • 3
  • 10
  • 18
  • You can customize pytest config to your needs with a pytest.ini at the root of your tests directory https://pytest.org/latest/customize.html – Khanh Hua Dec 30 '15 at 07:06

3 Answers3

59

By convention it searches for

Test prefixed test classes (without an init method)

eg.

# content of test_class.py
class TestClass:
    def test_one(self):
        x = "this"
        assert 'h' in x

    def test_two(self):
        x = "hello"
        assert hasattr(x, 'check')

    # this works too
    @staticmethod
    def test_three():
        pass

    # this doesn't work
    #@classmethod
    #def test_three(cls):
    #    pass

See the docs:

twil
  • 6,032
  • 1
  • 30
  • 28
  • 9
    I'd like to add, that these need to be regular methods, `@staticmethod` will not be found – DariusL Feb 01 '17 at 15:16
  • new [link to doc](https://docs.pytest.org/en/reorganize-docs/new-docs/user/naming_conventions.html) – bm13kk May 05 '21 at 09:38
15

The accepted answer is not incorrect, but it is incomplete. Also, the link it contains to the documentation no longer works, nor does the updated link in the a comment on that answer.

The current documentation can now be found here. The relevant bits of that doc are:

  • ...
  • In those directories, search for test_*.py or *_test.py files, imported by their test package name.
  • From those files, collect test items:
    • ...
    • test prefixed test functions or methods inside Test prefixed test classes (without an __init__ method)

The key bit that is missing in the accepted answer is that not only must the class name start with Test and not have an __init__ method, but also, the name of the file containing the class MUST be of one of the forms test_*.py or *_test.py.

Where I got tripped up here, and I assume many others will too, is that I generally name my Python source files containing only a class definition to directly mirror the name of the class. So if my class is named MyClass, I normally put its code in a file named MyClass.py. I then put test code for my class in a file named TestMyClass.py. This won't work with PyTest. To let PyTest do its thing with my test class, I need to name the file for this class test_MyClass.py or MyClass_test.py. I chose the last form so that I generally add a '_test' suffix to the file names I'd otherwise choose that need to be named so that PyTest will parse them looking for tests.

CryptoFool
  • 21,719
  • 5
  • 26
  • 44
1

pytest discovers all tests following its Conventions for Python test discovery, so it finds both test_ prefixed functions. There is no need to subclass anything, but make sure to prefix your class with Test otherwise the class will be skipped. We can simply run the module by passing its filename:

ArtAqua
  • 11
  • 1
  • This does not appear to add anything beyond what the existing answers say. Please don't repeat answers. – ChrisGPT was on strike Apr 30 '23 at 11:59
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/34304409) – Ξένη Γήινος May 04 '23 at 13:50