3
\$\begingroup\$

I have just started using pytest and I am still getting used to how they do things. It seems like fixtures are at the core of the library, and that they can be used for making small pieces of dummy data that will get reused. I see that there are other methods for handling large dummy data. I have the following test code which tests a module I wrote called generate_kml.

import pytest
import generate_kml as gk
import pandas


@pytest.fixture
def line_record():
    return pandas.Series({gk.DB_VERTICES: "LINESTRING(1.1 1.1,2.2 2.2)"})


def test_convert_wkt_to_coords(line_record):
    expected = pandas.Series({gk.DB_VERTICES: [("1.1", "1.1"), ("2.2", "2.2")]})
    assert gk.convert_wkt_vertices_to_coords(line_record).equals(expected)

I am wondering if this is the way fixtures are meant to be used; to set up small reused data. (I plan to use the line_record multiple times in the test file). Additionally, I am wondering about the readability or redundancy of assigning the expected value to expected. If I directly compared the two Series, the line would exceed PEP8's recommended line length, so I would break it into two lines anyway. If it adds readability here, then would it be good practice to always assign the expected value to a variable called expected (assuming you are comparing values that are expected to be equal)? Here is the function being tested from generate_kml:

def convert_wkt_vertices_to_coords(vertices_as_wkt):
    def parse_coords(wkt):
        wkt = wkt[wkt.find("(") + 1:wkt.find(")")]
        coords = wkt.split(",")
        coords = [tuple(x.split(" ")) for x in coords]
        return coords
    return vertices_as_wkt.apply(parse_coords)

One more thing here; in convert_wkt_vertices_to_coords I have a nested function. I don't plan on reusing it, but in the past I haven't had a need for nested functions, so it feels a bit off to me. Should I leave it as a nested function or break it out as its own function in the module?

\$\endgroup\$
2
+50
\$\begingroup\$

This is one of the way you can use fixtures. Fixtures are a form of dependency injection. For example, I use pytest to execute integration testing for an embedded target over ssh. So I want to reuse the ssh connection between tests.

The pytest fixture documentation has a similar example with SMTP: https://docs.pytest.org/en/latest/fixture.html

Note that if you want to reuse the same exact object between tests, you need to specify the scope @pytest.fixture(scope='module')

Another reason to use fixtures is that they are the basis for writing plugins. Here's the pytest documentation on turning fixtures into plugins: https://docs.pytest.org/en/latest/writing_plugins.html

If you want to learn more about fixtures I would recommend checking out the source for some of the 3rd party plugins they have one their website: https://pytest.readthedocs.io/en/2.7.3/plugins_index/index.html

So that should give you an idea that fixtures are really flexible and people have implemented a lot of really cool ones.

Pytest fixtures let you do things like examine the values of existing command line options and add new command line options. https://docs.pytest.org/en/latest/example/simple.html#pass-different-values-to-a-test-function-depending-on-command-line-options

\$\endgroup\$
  • \$\begingroup\$ Just for clarification: "This is one of the the way you can use fixtures" means "Yes, using fixtures to create small pieces of reusable dummy data is a good practice and one of their common applications "? Also, Do you have any thoughts on the second part of the question about using a variable named expected? And the third part about using a nested function in the place I use it? \$\endgroup\$ – Albert Rothman Aug 27 '18 at 17:27
  • \$\begingroup\$ Within your own project you can use a fixture for anything you want. In this exact example, is there much advantage to using a fixture over just calling the function? probably not. But is it 'right' or 'wrong'? <intentionally not answered> \$\endgroup\$ – Jonah Aug 28 '18 at 2:00
  • \$\begingroup\$ To answer what are you supposed to do with them, read the documentation on the more advanced features and look at published plugins to understand how they are used by other people. They are the architectural mechanism to make pytest extensible. re question 2, I think one line is too long. re question 3, what is your alternative? It's long to be a lambda and try to cram in a single statement. Seems like exactly the right time to use a nested function. \$\endgroup\$ – Jonah Aug 28 '18 at 2:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.