[py-dev] order of setup / teardown
holger krekel
holger at merlinux.eu
Mon Apr 12 13:13:08 CEST 2010
Hi Philippe,
(note to all: i am back from a long and fun vacation
and will see to answer pending issues in the next days)
On Mon, Apr 12, 2010 at 12:37 +0200, Philippe Fremy wrote:
> Hi,
>
> I am not sure if this has been brought before, but I am surprised to see
> some calls inside the test "hooks" after the test session has finished.
>
> I am referring here to teardown_class, revealed by a quick example:
>
> pytest_sessionstart
>
> setup_class
> setup_method
>
> test1
>
> teardown_method
>
> setup_method
> test2
>
> teardown_method
>
> pytest_sessionfinish
>
> teardown_class
>
> This is creating problems for me because
> I am assuming that all resources are setup in sesssionstart,
> and torn down in sessionfinish. And teardown_class is using one of
> those resources.
>
> Is it a bug or intended behavior ?
setup and teardown of python test functions are implemented through the builtin
py/_plugin/pytest_runner.py plugin. It itself implements hooks called from the
"session" in order to provide the setup/teardown semantics. There,
it only tears down class/module state if the "next" test does not need it and
this is decided at setup time of said next test. This means that
after the last test has run, some resources might still require teardown
and currently this is done through implementing it in a pytest_sessionfinish
hook. The latter, however, is invoked after all user-provided hooks have
been invoked.
So much for the analysis. Also related to your other "directory-setup"
issue i am not entirely happy about pointing people to pytest_namespace
and sessionstart/sessionfinish for scoped python setup purposes. Maybe
more python-specific setup/teardown hook(s) would make more sense?
Relatedly, I ponder giving up on the incremental collection of tests and
internally immediately produce a fully exploded lists of tests at
session start. This way teardown could be done in a more precise manner --
right after the resource/scope is not needed anymore. It would also make
randomization and other test re-ordering easy. A downside is that it takes
longer for the first test to run. A plus is that it probably eases
implementation and provides less surprises (such as the one you are having
because pytest_runner would not need to work through sessionfinish anymore).
If you don't tell anyone - :) - there also is a immediate work around
to your issue i think. You could implement something like
def pytest_sessionfinish(__multicall__):
__multicall__.execute() # call other sessionfinish implementers first
'__multicall__' is the object representing the current
ongoing plugin hook call and allows to dynamically call other reamining
hook implementers first. It's not documented or advertised
(but used sometimes from pytest's own builtin plugins) because i
think a more declarative decorator-based way of setting call
ordering is saner. Then again, i hope to avoid the need
altogether for simplicity sake.
cheers,
holger
More information about the Pytest-dev
mailing list