I know in pytest-timeout
I can specify tiemout for each testcase but single failure terminates whole test run instead failing the slacking off testcase.
Am I forced to make my own solution of this or there are ready-to-use tools which provide that?
I looked into this issue a long time ago and also came to the conclusion that a self-made solution would be better.
My plugin was killing the whole pytest process, but it can be adjusted to fail only a single (current) test easily. Here is the adjusted draft:
When you do
kill -ALRM $pid
, or when each test times out individually due to the preset alarm, only the current test will fail, but the other tests will continue.And this
TimeoutExit
will not be suppressed by the libraries which doexcept Exception: pass
because it inherits fromBaseException
.So, it is alike
SystemExit
in this aspect. However, unlikeSystemExit
orKeyboardInterruption
, pytest will not catch it, and will not exit on such an exception.The exception will be injected into wherever the test does at the moment of the alarm, even if it does
time.sleep(...)
(so as for any signals).Remember, that you can only have one single alarm set for the process (OS limitation). Which also makes it incompatible with
pytest-timeout
, because it also uses the ALRM signal for the same purpose.If you want to have the global & per-test timeouts, you have to implement you smart alarm manager, which will keep track of few alarms, set the OS alarm to the earliest one, and decide which handler to call when the alarm signal is received.
In case, when you do
kill -TERM $pid
or justkill $pid
(graceful termination), it will be terminated immediately — because it inherits fromSystemExit
, which is theBaseException
and is usually not caught by the code or by pytest.The latter case mostly demonstrates how you can set different reactions to different signals. You can do the similar things with USR1 & USR2 and other catchable signals.
For a quick-test, put the plugin code above to the
conftest.py
file (a pseudo-plugin).Consider this test file:
Running pytest without a timeout does nothing, and both tests pass:
Running it with the timeout fail the first test, but pass the second one: