PyTest-Locker
PyTest-Locker: The fastest way to check for unexpected changes between test runs
The general concept
In essense Pytest-Locker changes the basis of testing from having to assert everything that is relevant about an object
to only having to assert that an object should not change unexpectedly (i.e. the object is locked).
This, of course, implies that the pytest-locker approach makes a lot of sense
when the assertion logic becomes complex. I found it especially handy when testing if I'm sending the right API calls.
Since objects can be just about anything in python
(output, state, or even function calls via mocking)
you can use this approach for just about everything.
Since you need to validate if the object to lock is correct, both in the first run and after desired modifications,
the test flow is slightly different:
Why use PyTest-Locker
Install
run pip install pytest-locker
Usage
Configuring the project and writing your first test.
- Add
from pytest_locker import locker
to your
conftest.py
file - To access the locker by adding it to the method parameters i.e.
def test_example(locker)
- Use
locker.lock(your_string, optional_name)
to lock the data (of-course you can also lock other types). - Ensure that the pytest rootdir is fixed.
See the pytest customize documentation for all the options (one
is adding a
pytest.ini
to the root folder) - Ensure that
.pytest_locker/
is synced via git, to ensure that you, your team, and your CI/CD pipelines are working
with the same data.
And you're all set!
Accepting the current behavior and checking fo changes in this behavior
There are two modes based on for locking. The first is
-
When user input is allowed, i.e. when running pytest with
--capture no
or -s
When user input is allowed and the given data does not correspond to the data in the lock the user is prompted if
the new data should be stored or if the tests should fail.
-
When user input is captured which is default behavior for pytest
If user input is not allowed the tests will automatically fail if the expected lock file does not exist or if the
data does not correspond to the data in the lock file.
The Locker class
You can also use pytest_locker.Locker
(i.e. the class of which the
locker
fixture returns an instance) directly to create fixtures that locks a (non-string) object without needing to
turn the object into a string it.
Examples
For example of use look at the tests in
repr-utils.