Using Pykiso with Pytest

The pykiso-pytest plugin allows to run pykiso test suites with pytest without any migration effort. Simply run pytest my_test_configuration_file.yaml and enjoy!

Still, to benefit from all of pytest’s features, your existing test suites can be migrated from the pykiso (unittest) style to the pytest style.

Running Pykiso tests with pytest

Let us take as example the following test configuration file named example.yaml:

auxiliaries:
  aux1:
    connectors:
      com: chan1
    config: null
    type: pykiso.lib.auxiliaries.dut_auxiliary:DUTAuxiliary
  aux2:
    connectors:
      com: chan2
    type: pykiso.lib.auxiliaries.dut_auxiliary:DUTAuxiliary
connectors:
  chan1:
    config: null
    type: pykiso.lib.connectors.cc_example:CCExample
  chan2:
    type: pykiso.lib.connectors.cc_example:CCExample
test_suite_list:
- suite_dir: ./
  test_filter_pattern: 'test_suite.py'
  test_suite_id: 1

Along with the following test case as a python module named test_suite.py, located in the same folder as the test configuration file:

import pykiso
from pykiso.auxiliaries import aux1, aux2

@pykiso.define_test_parameters(suite_id=1, aux_list=[aux1, aux2])
class SuiteSetup(pykiso.BasicTestSuiteSetup):
    def test_suite_setUp(self):
        pass


@pykiso.define_test_parameters(suite_id=1, aux_list=[aux1, aux2])
class SuiteTearDown(pykiso.BasicTestSuiteTeardown):
    def test_suite_tearDown(self):
        pass


@pykiso.define_test_parameters(suite_id=1, case_id=1, aux_list=[aux1], tag={"variant": ["v2"]})
class MyTest1(pykiso.BasicTest):

    def setUp(self):
        self.side_effect = iter([False, True])

    @pykiso.retry_test_case(max_try=2)
    def test_run(self):
        # the retry feature is also available out of the box
        self.assertTrue(next(self.side_effect))


@pykiso.define_test_parameters(suite_id=1, case_id=2, aux_list=[aux2], tag={"variant": ["v1"]})
class MyTest2(pykiso.BasicTest):
    def test_run(self):
        self.assertTrue(aux2.is_instance)

Then, executing pytest example.yaml -v will produce the following output:

../_images/pykiso_pytest.png

Running pytest tests with pykiso test auxiliaries

One of Pytest’s main features are test fixtures. These allow you to create a context for your test cases, by specifying a test setup, teardown or more generally by initializing resources that are then provided to the test cases.

Pykiso’s pytest plugin uses fixtures to provide test auxiliaries to test cases. Similarly to the importable auxiliary aliases in pykiso, the plugin will create fixtures available under this alias.

For example, taking as reference the previous test configuration file and pykiso test suite, the pykiso test case MyTest2 could be rewritten to:

@pytest.mark.tags(variant=["var1"])
def test_mytest2(aux2):
    assert aux2.is_instance == True

Just like pykiso, an auxiliary will be started as soon as it is used for the first time. It will then keep running until the end of the test session. To change this behaviour, please refer to pytest_auxiliary_scope.

Note

When writing test cases with pytest, always use plain assert statements instead of e.g. assertTrue. Otherwise pytest does not provide assertion introspection.

Ported pykiso features

Filtering test cases

In order to select a subset of the tests to run, 2 options are available:

  • Use pytest’s builtin option -k. By modifying the previous command to e.g.
    pytest example.yaml -v -k MyTest1, only MyTest1 will be run.
  • Use pykiso’s test tags feature. By modifying the previous command to e.g.
    pytest example.yaml -v --tags variant=v1, only MyTest1 will be skipped
    as it is only meant for a variant tag v2. For more information regarding
    this pykiso feature, please refer to Filter the test cases to run with tags.

Adding test case information to JUnit reports

Assign test requirements to test cases is also supported by the pykiso pytest plugin:

@pykiso.define_test_parameters(test_ids={"Variant1": ["Requirement123"]})
class MyTest2(pykiso.BasicTest):
    def test_run(self):
        self.assertTrue(aux2.is_instance)


@pytest.mark.test_ids(Variant1=["Requirement123"])
def test_mytest2(aux2):
    assert aux2.is_instance == True

In order to generate a JUnit report for your test session, simply use pytest’s built-in option:

pytest ./example.yaml --junit-xml=./report.xml