Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the benefit of a fixture with function scope and no teardown code?

Tags:

python

pytest

What's advantage of a (default) function-scope fixture without teardown code? Why not just call the function at the beginning of the test?

For example, what's the benefit of writing:

@pytest.fixture
def smtp():
    return smtplib.SMTP("smtp.gmail.com")

def test_ehlo(smtp):
    response, msg = smtp.ehlo()
    # ...

instead of simply:

def create_smtp():
    return smtplib.SMTP("smtp.gmail.com")

def test_ehlo():
    smtp = create_smtp()
    response, msg = smtp.ehlo()
    # ...

I understand why fixtures are useful when we need teardown code. I also understand why fixtures with scope other than function are useful: we may want to reuse the same "external" object in multiple tests (to save the time it takes to create it; or perhaps even to maintain its state -- although that seems to be rather dangerous since this creates an hard-to-see coupling between separate tests).

like image 965
max Avatar asked Feb 17 '17 22:02

max


People also ask

What is a benefit of properly implemented fixtures?

tear down logic can be easily managed no matter how many fixtures are used. Fixture scopes can be set for each fixture which will helps tremendously in saving a lot of time and computing resources while running expensive test cases.

What is pytest fixture scope function?

Fixture scopes function : the default scope, the fixture is destroyed at the end of the test. class : the fixture is destroyed during teardown of the last test in the class. module : the fixture is destroyed during teardown of the last test in the module.

What is the default scope of the fixture?

fixture() can have the values of function, class, module, or session. The default scope is function.

Which of the following is a function of fixtures?

A fixture's primary purpose is to create a secure mounting point for a workpiece, allowing for support during operation and increased accuracy, precision, reliability, and interchangeability in the finished parts.


2 Answers

I had a similar question when I started using it. Here's my experience:

  • Fixtures can be set to autouse=True, i.e., trigger automatically that may not be possible with an inline call. This is useful in some cases.
  • Fixtures add readability, at least for me. Looking at the signature of the test, one can figure out what initialisations are a pre-requisite for a given test. In that sense, it also help keep the test and it's initialisation isolated.
like image 176
Sharad Avatar answered Sep 27 '22 20:09

Sharad


What's advantage of a (default) function-scope fixture without teardown code? Why not just call the function at the beginning of the test?

Saving vertical space.

Consider something like this, where you have more than one fixture per test:

import pytest


@pytest.fixture
def value1():
  return 1

@pytest.fixture
def value2():
  return 2

@pytest.fixture
def value3():
  return 3


def test_values(value1, value2, value3):
    assert value1 == 1
    assert value2 == 2
    assert value3 == 3

If we were to do this your way:

def test_values():
    v1 = value1()
    v2 = value2()
    v3 = value3()

    assert v1 == 1
    assert v2 == 2
    assert v3 == 3

That's three extra lines of code. Not a big deal, but then what if you had 10 tests that needed value1, value2 and value3? Now you have 30 extra lines of vertical space for basically no reason.

Obviously, both of our examples are overly simplified (I could just have done the call and assert inline), but I think it's straightforward to see how this could have an impact with real code.

like image 33
Jack Avatar answered Sep 27 '22 21:09

Jack