简体   繁体   中英

Customize pytest collecting tests

I would like to avoid using the "test" prefix in classes and functions names and implement my own schema of the test parametrization. I did the next code test.py

import pytest

# class for inheritance to avoid "Test" prefix
class AtsClass:
    __ATS_TEST_CLASS__ = True

# decorator to mark functions as tests (to avoid "Test" prefix)
def ats_test(f):
    setattr(f, "__ATS_TEST_CLASS__", True)
    return f

def test_1():
    pass

@ats_test
def some_global_test():
    pass

class MyClass(AtsClass):
    def test_4(self):
        pass

    @ats_test
    def some_func(self):
        pass

conftest.py

import pytest
import inspect

# @pytest.hookimpl(hookwrapper=True)
def pytest_pycollect_makeitem(collector, name, obj):
    # outcome = yield
    # res = outcome.get_result()
    if inspect.isclass(obj) and obj.__name__ != "AtsClass" and hasattr(obj, "__ATS_TEST_CLASS__") and obj.__ATS_TEST_CLASS__ == 1:
        print("WE HAVE FOUND OUR CLASS")
        return pytest.Class(name, parent=collector)
        # outcome.force_result(pytest.Class(name, parent=collector))
    if inspect.isfunction(obj) and hasattr(obj, "__ATS_TEST_CLASS__") and obj.__ATS_TEST_CLASS__ == 1:
        print("WE HAVE FOUND OUR FUNCTION")
        return pytest.Function(name, parent=collector)
        # outcome.force_result([pytest.Function(name, parent=collector)])


def pytest_generate_tests(metafunc):
    print("-->Generate: {}".format(metafunc.function.__name__))

In this case hook "pytest_pycollect_makeitem" creates test for function "some_global_test", but hook "pytest_generate_tests" is not executed for function "some_global_test".

I have found a solution, call collector._genfunctions(name, obj) from my hook. But I think it is not the right decision, cause _genfunctions is a private method and not declared.

Is there another way to solve my task?

If you want only to change prefix of tests you can set custom python_functions and python_classes options at pytest.ini .

For more information follow a link .

So, nobody knows the answer and I decided to offer my solution (it can be useful for others):

    class TestBaseClass:
        __test__ = True

    def mark_test(f):
        setattr(f, "__test__", True)
        return f

    # using base class and decorator
    class MyTestClass(TestBaseClass):
        @mark_test
        def some_func(self):
            pass

Pytest uses attribute __test__ to detect nose-tests, so you can use nose-library or just use such base class and decorator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM