Last modified on 01 Oct 2021.

Install

pip install pytest

Rules

  • Name all testing files with[ref] test_*.py or *_test.py.
  • Name all “be tested” functions with def test_*.

Executing

pytest test_sample.py
pytest -q test_sample.py # quiet mode
# ignore all files in folder statistics
pytest -k "not statistics"

Simple

# test_sample.py
def func(x):
    return x + 1

def test_answer():
    assert func(3) == 5
# then run
pytest test_sample.py

With parameters

# test_sample.py
@pytest.mark.parametrize(
    "input, param_1, param_2, result",
    [
        (df_1, 'date', np.mean, df_result_1),
        (df_2, 'date', np.mean, df_result_2),
    ]
)

def test_run(input, param_1, param_2, result):
    spts = SPTS(param_1=param_1, param_2=param_2)
    df_tmp = spts.run(df)
    assert isinstance(df_tmp, pd.DataFrame)
    assert df_tmp.equals(result)
# To get all combinations
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])

def test_foo(x, y):
    pass

# Then the arguments set to `x=0/y=2`,
#    `x=1/y=2`, `x=0/y=3`, and `x=1/y=3`.

Note that, @pytest.mark.parametrize must be placed right before the function who uses it. Otherwise, there is an error fixture not found.

# ERROR
@pytest.mark.parametrize("x", [0, 1])
def test_foo(x):
    pass

def test_bar(x):
    pass
# FIX
@pytest.mark.parametrize("x", [0, 1])
def test_foo(x):
    pass

@pytest.fixture
def test_bar(x):
    pass

Custom marker

Run tests who have a specific marker.[ref]

@pytest.mark.marker_1
def test_func1():
    pass

@pytest.mark.marker_2
def test_func2():
    pass

@pytest.mark.marker_1
def test_func3():
    pass
# with tag 'marker_1'
pytest -v -m marker_1

# except tag 'marker_1'
pytest -v -m 'not marker_1'

Errors

# ImportError: No module named atomicwrites
python -m pytest
python3 -m pytest

Ignore warning

👉 Main reference.

# eg: RuntimeWarning: numpy.ufunc size changed,
@pytest.mark.filterwarnings('ignore::RuntimeWarning')
@pytest.mark.level_1
def test_load(df_test, report):

References

Notes with this notation aren't good enough. They are being updated. If you can see this, you are so smart. ;)