Reputation: 191
I am new to pytest. When is @pytest.hookimpl executes? And what is the complete usage of it? I have tried with logs. For (hookwrapper=true), it is printing, 3 sets of after and before yield for a single test.
Upvotes: 5
Views: 14217
Reputation: 186
pytest uses @pytest.hookimpl
just to label hook methods. (So @pytest.hookimpl
is executed when pytest collects the hook method.)
If you read the source code of pytest, you can find these codes:
def normalize_hookimpl_opts(opts):
opts.setdefault("tryfirst", False)
opts.setdefault("trylast", False)
opts.setdefault("hookwrapper", False)
opts.setdefault("optionalhook", False)
It means pytest will label the hook method with @pytest.hookimpl(tryfirst=False, trylast=False, hookwrapper=False, optionalhook=False)
by default. Pytest will treat these hook methods in different ways according to this label(decorator) when executing them.
Take the hookwrapper
parameter for example. If the hook method is labeled as hookwrapper=True
, pytest will execute the part before yield
first and then execute other same type hook methods. After these methods executed, the part after yield
will be executed. (This feature is just like pytest fixtures.)
One usage of @pytest.hookimpl(hookwrapper=True)
is that you can calculate the total cost time of some hook methods.
(Here, the example code will calculate the tests collect time.)
@pytest.hookimpl(hookwrapper=True)
def pytest_collection(session):
collect_timeout = 5
collect_begin_time = time.time()
yield
collect_end_time = time.time()
c_time = collect_end_time - collect_begin_time
if c_time > collect_timeout:
raise Exception('Collection timeout.')
Upvotes: 9