I’ve been writing some unit tests that use pytest fixtures (a fastai learner and dataloader with random data) and I’ve run into an odd set of errors when I use the star imports from
fastai==2.2.7
.
My workaround here is to not use star imports - even though it looks using star imports is the recommended approach.
Here’s a toy example:
import numpy as np
import pandas as pd
import pytest
# Using the star imports
from fastai.tabular.all import *
@pytest.fixture
def fastai_dl(tmp_path):
# Returns a TabularDataLoader with some random data
m = np.random.random_sample((10, 10))
df = pd.DataFrame(m, columns=[f"x{i}" for i in range(10)])
df["y"] = (np.random.rand(10, 1) > 0.5).astype(int)
return TabularDataLoaders.from_df(df, path=tmp_path, y_names=["y"])
@pytest.fixture
def fastai_learner(fastai_dl):
learner = tabular_learner(fastai_dl)
learner.fit_one_cycle(n_epoch=1)
return learner
def test_example(fastai_learner):
# Run a simple assertion just as a demo
assert type(fastai_learner).__name__ == "TabularLearner"
When running this, I get a ton of errors. They are all fixture '<name>' not found
.
❯ pytest test_fastai.py
================================================ test session starts ================================================
platform darwin -- Python 3.8.7, pytest-6.2.2, py-1.10.0, pluggy-0.13.1
rootdir: /Users/neal/src/github.com/operatorai/modelstore, configfile: pytest.ini
collected 15 items
test_fastai.py EEEEEEEEEEEEEE. [100%]
====================================================== ERRORS =======================================================
__________________________________________ ERROR at setup of test_overflow __________________________________________
file /Users/neal/.pyenv/versions/3.8.7/envs/operatorai.example.fastai/lib/python3.8/site-packages/fastai/callback/fp16.py, line 82
def test_overflow(x):
E fixture 'x' not found
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, fastai_dl, fastai_learner, monkeypatch, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
[...]
ERROR test_fastai.py::test_overflow
ERROR test_fastai.py::test_set
ERROR test_fastai.py::test_sig
ERROR test_fastai.py::test_fail
ERROR test_fastai.py::test
ERROR test_fastai.py::test_eq
ERROR test_fastai.py::test_eq_type
ERROR test_fastai.py::test_ne
ERROR test_fastai.py::test_close
ERROR test_fastai.py::test_is
ERROR test_fastai.py::test_shuffled
ERROR test_fastai.py::test_stdout
ERROR test_fastai.py::test_warns
ERROR test_fastai.py::test_fig_exists
If I replace the *
import with explicit imports, then my tests are all green:
from fastai.callback.schedule import fit_one_cycle
from fastai.learner import load_learner
from fastai.tabular.data import TabularDataLoaders
from fastai.tabular.learner import tabular_learner
(For completeness, I had to figure out to also explicitly import fit_one_cycle
to resolve the 'TabularModel' object has no attribute 'fit_one_cycle'
problem that would otherwise pop up)
I haven’t been able to find any similar problems on this forum or stackoverflow relating to this – perhaps I have haven’t configured pytest
in the right way? Either way, I thought I’d share it here in case anyone has a better solution or runs into a similar problem: feedback welcome