PatrickL
PatrickL

Reputation: 11

Use fixture only one time in a parametrized function

I want to read a multiline string from a serial port and then compare it line by line with a reference .txt file. The compare function itself uses a second .txt file, where I define what operation should be done with each line (e.g. 1:1 diff or compare a value with a tolerance) - my ids file.

For this line by line thing, I parametrized my test_function with a line parameter. So I can assert each line. The problem now is, that each time my fixture is called again, and it cost some time to read out the serial port.

Is there a smoother way than my current workaround?

#test_class.py
import pytest
import serial

buffered_port_readback = []


@pytest.mark.basic
@pytest.mark.parametrize("line", range(8))
def test_portname_command(fix_port_readback, fix_port_reference, fix_port_ids, line):
    if (line == 0):
        get_port_readback(fix_port_readback)
    port_compare(fix_port_reference[line], fix_port_ids[line], buffered_port_readback[line])
#conftest.py
import pytest
import serial
import os
import datetime
import socket
import subprocess
import sys


@pytest.fixture(scope="function")
def fix_port_readback(request, fix_port_command, fix_port, line):
    if(line == 0):
        fix_port.reset_input_buffer()
        fix_port.write(fix_port_command)
        readback = fix_port.read_until(b'usb>')
        readback_decode = readback.decode("utf-8")
        readback_lines = readback_decode.split("\n")

        new_readback_lines = []
        for entry in readback_lines:
            mod_entry = entry.replace('\r', '')
            new_readback_lines.append(mod_entry)

        return new_readback_lines

As you can see my current workaround is to read the port only in the first loop by making sure line == 0 and save that in a buffer. I think that's not the best way.

Upvotes: 1

Views: 262

Answers (1)

Masklinn
Masklinn

Reputation: 42302

The simplest would probably be to increase the scope of your fixtures, the granularity is a bit limited (class, module, package and session) but if it works....

A related alternative is to have your function fixture depend on a larger "cache" fixture and inspect the request, that way it can check the properties of the requester and either create a new value or get one from the cache.

Finally, the "big hammer" is to dynamically generate fixture result by plugging into pytest_fixture_setup or pytest_generate_tests, something like that, and then do whatever you want on the fly.

Upvotes: 1

Related Questions