Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacement for test case inheritance in pytest?

Background

In Python's unittest framework, it is a fairly common idiom to use inheritance on a base set of tests to apply an entire set of tests to a new problem, and occasionally to add additional tests. A trivial example would be:

from unittest import TestCase

class BaseTestCase(TestCase):
    VAR = 3

    def test_var_positive(self):
        self.assertGreaterEqual(self.VAR, 0)

class SubTestCase(BaseTestCase):
    VAR = 8

    def test_var_even(self):
        self.assertTrue(self.VAR % 2 == 0)

Which, when run, runs 3 tests:

$ python -m unittest -v
test_var_positive (test_unittest.BaseTestCase) ... ok
test_var_even (test_unittest.SubTestCase) ... ok
test_var_positive (test_unittest.SubTestCase) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.000s

This is particularly useful if you are testing a class hierarchy, where each subclass is a subtype of the parent classes, and should thus be able to pass the parent class's test suite in addition to its own.

Problem

I would like to switch over to using pytest, but I have a lot of tests that are structured this way. From what I can tell, pytest intends to replace most of the functionality of TestCase classes with fixtures, but is there a pytest idiom that allows test inheritance, and if so what is it?

I am aware that pytest can be used to run unittest-style tests, but the support is limited, and I would like to use some of the "will never be supported" features of pytest in my tests.

like image 592
Paul Avatar asked Aug 27 '18 17:08

Paul


People also ask

What is Autouse in pytest?

pytest is a very robust framework that comes with lots of features. One such feature is the autouse fixtures, a.k.a xUnit setup on steroids. They are a special type of fixture that gets invoked automatically, and its main use case is to act as a setup/teardown function.

What is Conftest py in pytest?

conftest.py is where you setup test configurations and store the testcases that are used by test functions. The configurations and the testcases are called fixture in pytest. The test_*. py files are where the actual test functions reside.

How do I skip Testcases in pytest?

The simplest way to skip a test is to mark it with the skip decorator which may be passed an optional reason . It is also possible to skip imperatively during test execution or setup by calling the pytest. skip(reason) function. This is useful when it is not possible to evaluate the skip condition during import time.

Can I use pytest and unittest together?

pytest supports running Python unittest -based tests out of the box. It's meant for leveraging existing unittest -based test suites to use pytest as a test runner and also allow to incrementally adapt the test suite to take full advantage of pytest's features.


1 Answers

Pytest allows you to group test cases in classes, so it naturally has support for test case inheritance.

When rewriting your unittest tests to pytest tests, remember to follow pytest's naming guidelines:

  • class names must begin with Test
  • function/method names must begin with test_

Failing to comply with this naming scheme will prevent your tests from being collected and executed.


Your tests rewritten for pytest would look like this:

class TestBase:
    VAR = 3

    def test_var_positive(self):
        assert self.VAR >= 0

class TestSub(TestBase):
    VAR = 8

    def test_var_even(self):
        assert self.VAR % 2 == 0
like image 167
Aran-Fey Avatar answered Oct 29 '22 03:10

Aran-Fey