[pytest-dev] Testing fixture teardown / finalisation

James Cooke me at jamescooke.info
Thu Jan 7 09:57:45 EST 2021


Hi Bruno,

This is great! Just echoing what Brian said - simple and obvious, and I'm disappointed that I didn't see it myself. I've integrated your suggestion today and the teardown tests are now much simpler, so this definitely helped.

Would it be worth PR-ing this suggestion into the docs? My guess is that it would help many devs. Am happy to do the copypasta if you think it's worth it.

Cheers,

James


On Thu, 7 Jan 2021, at 5:56 AM, Brian Okken wrote:
> Bruno,
> 
> This is brilliant in that it’s obvious now that I see it, but didn’t occur to me before. 
> 
> Super cool. 
> 
> - Brian
> 
>> On Jan 6, 2021, at 10:26 AM, Bruno Oliveira <nicoddemus at gmail.com> wrote:
>> 
>> Hi James,

>> What I suggest you do in your case is to decouple your code from the fixture, so if you have something like this today:

>> `    @pytest.fixture(scope="module")
    def my_work_reqs():
        # some 
        # complicated 
        # setup 
        # code

        yield  x # some result

        # some 
        # complicated 
        # teardown 
        # code
`
>> You can write instead:

>> `
    @contextmanager
    def handle_work_reqs():
        # some 
        # complicated 
        # setup 
        # code
        try:
            yield x # some result
        finally:            
            # some 
            # complicated 
            # teardown 
            # code

    @pytest.fixture(scope="module")
    def my_work_reqs():
        with handle_work_reqs() as x:
            yield x
`
>> Now you can test `handle_work_reqs` normally, as it is not tied to the pytest framework.

>> I like this approach in general, decoupling custom code from a framework is a great way to make it easier to test.


>> HTH,
>> Bruno.

>> 
>> 
>> On Wed, Jan 6, 2021 at 2:37 PM James Cooke <me at jamescooke.info> wrote:
>>> Hi all,
>>> 
>>> It's been a while since I've had to write a complicated and robust pytest fixture and I'm struggling with testing the teardown / finalisation code.
>>> 
>>> Instead of boring you with the [my-work-project] requirements of cleaning up GCS after tests, I'll refer to the fixture in the docs https://docs.pytest.org/en/stable/fixture.html#fixture-finalization-executing-teardown-code :
>>> 
>>>     @pytest.fixture(scope="module")
>>>     def smtp_connection():
>>>         smtp_connection = smtplib.SMTP("smtp.gmail.com", 587, timeout=5)
>>>         yield smtp_connection  # provide the fixture value
>>>         print("teardown smtp")
>>>         smtp_connection.close()
>>> 
>>> My (very old) usual strategy for testing teardown of a fixture that uses `yield` would be:
>>> 
>>> * Start test
>>> 
>>>     - Instantiate the fixture.
>>> 
>>>     - Manipulate the instance with `next()` to trigger the teardown.
>>> 
>>>     - Ensure that teardown was successful - in this case assert that the SMTP connection returned when the fixture was instantiated was closed successfully.
>>> 
>>> Given that since v4.1 (https://github.com/pytest-dev/pytest/issues/4545), the arrangement step of "Instantiate the fixture" does not work, could someone point me at the recommended method of testing fixture teardown?
>>> 
>>> I would like to ensure that teardown is resilient and can resolve multiple conditions that can happen in [my-work-project]'s test suite. I can see that there are multiple tests on fixtures in https://github.com/pytest-dev/pytest/blob/48c9a96a03261e7cfa5aad0367a9186d9032904a/testing/python/fixtures.py , are there any preferred / recommended / efficient methods in this file? Alternatively, is there a way to by-pass the fixture wrapping that happens that prevents it being callable? Should I be using `smtp_connection.__pytest_wrapped__.obj()` to instantiate? (this seems bad)
>>> 
>>> Any pointers / suggestions would be great.
>>> 
>>> Thanks,
>>> 
>>> James
>>> 
>>> 
>>> _______________________________________________
>>> pytest-dev mailing list
>>> pytest-dev at python.org
>>> https://mail.python.org/mailman/listinfo/pytest-dev
>> _______________________________________________
>> pytest-dev mailing list
>> pytest-dev at python.org
>> https://mail.python.org/mailman/listinfo/pytest-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.python.org/pipermail/pytest-dev/attachments/20210107/be44556c/attachment.html>


More information about the pytest-dev mailing list