Implementation method of Pytest executing unittest TestSuite of test suite

  • 2021-11-24 02:21:49
  • OfStack

Preface

TestSuite1 is the flexibility and essence of unittest. Among the various test cases, you can choose and combine various use case sets at will, such as smoke用例集、 level1用例集、 webtest用例集、 bug回归用例集 Wait, of course, these TestSuite need to be defined in advance and loaded with use cases. Pytest takes a completely different way of organizing and running use cases. Use case operation is mainly based on name matching; The organization is based on use case directory, use case naming format and use case mark tag, which saves the trouble of defining TestSuite and loading use cases in advance, and dynamically matches the use cases to be executed through path/use case name format/different tag combination during execution, which is more flexible. However, when moving from the original unittest framework to the embrace of pytest, I still have to face such a problem: How to implement the TestSuite I originally defined?

Implementation method

Main ideas:

Iteratively traverse all case in TestSuite to get the path test_demo. TestDemo. test_a for each case

② Transform the case path into the running format supported by Pytest, test_demo. py:: TestDemo:: test_a, and form an case name list for Pytest to call.

Example use case: test_demo. py:


import unittest

class TestDemo(unittest.TestCase):
    def test_a(self):
        print("a")

    def test_b(self):
        print("b")

Sample test suite: demo. py:


import unittest
import pytest
from test_demo import TestDemo

suite = unittest.TestSuite()
suite.addTests([TestDemo('test_a'), TestDemo('test_b')])

#  Because suite Nesting may exist in ,  So we need to iterate out all the use cases :
def collect(suite): 
    cases = []  #  For storage Pytest Supported use case path strings 

    def _collect(tests):   #  Recursive, if the subordinate element is still TestSuite Then keep looking down 
        if isinstance(tests, unittest.TestSuite):
            [_collect(i) for i in tests if tests.countTestCases() != 0] 
        else:
            _path = tests.id().split(".")  # case.id() You can get the use case path ( String )
            _path[0] += ".py"
            cases.append("::".join(_path))  #  If the subordinate element is TestCase Is added to the TestSuite Medium 

    _collect(suite)
    return cases

if __name__ == '__main__':
    cases = collect(suite)
    pytest.main([*cases, "-v"])
    # pytest.main(cases)  #  The transformation without additional parameters can be executed directly cases

Related articles: