Test HTTP and API interactions with vcrpy
Background
We have a simple PeopleRepository
class which we are going to use to interact with the Star Wars API. The repository class implements two methods:
MethodPurposeall()
Return a list of all people from Star Warsfind(**filter)
Return a list of all people from Star Wars who match the given filter.
Interaction with the API is through Python’s request package.
We want to write tests to test our repository class.
Solution
We are using the pytest-recording
plugin for pytest
which uses pyvcr
to record HTTP interaction.
To install pytest-recording
you can use pip
:
pip install pytest-recording
Here is an example what our tests would look like:
# File: test_peoplerepository.py
import pytest
from swapi import repository
# Apply these marks to all test cases from the module.
# Instruct VCR that default cassete should be stored in "swapi.yaml" rather than
# <test-case>.yaml
pytestmark = [pytest.mark.default_cassette("swapi.yaml"), ]
@pytest.fixture(scope="session")
def vcr_config():
return {
"filter_headers": ["authorization"],
"ignore_localhost": True,
# Instruct VCR that we want to record the interaction only once.
"record_mode": "once",
}
@pytest.fixture
def people_repo():
return repository.PeopleRepository()
@pytest.mark.vcr()
def test_people_repo_all_returns_expected_number_of_people(people_repo):
people = people_repo.all()
assert len(list(people)) == 82
@pytest.mark.vcr()
def test_people_repo_find_returns_expectd_person(people_repo):
results = list(people_repo.find(hair_color='blond', mass=None))
assert len(results) == 1
assert results.pop().name == 'Finis Valorum'
Running the tests with pytest
:
$ pytest tests/test_peoplerepository.py -vv --cov repository.py
Produces similar output:
============================================== test session starts ===============================================
platform win32 -- Python 3.9.6, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- c:\sandbox\repos\pyvcr-examples\.venv\scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\Sandbox\repos\pyvcr-examples
plugins: cov-3.0.0, recording-0.12.0
collected 2 items
star-wars-api/tests/test_repository.py::test_people_repo_all_returns_expected_number_of_people PASSED [ 50%]
star-wars-api/tests/test_repository.py::test_people_repo_find_returns_expectd_person PASSED [100%]
----------- coverage: platform win32, python 3.9.6-final-0 -----------
Name Stmts Miss Cover
-----------------------------------------
swapi\repository.py 41 6 85%
-----------------------------------------
TOTAL 41 6 85%
=============================================== 2 passed in 0.28s ================================================
Further Reading
- pytest-recording at Github
- vcrpy source at Github
- vcrpy documentation at Readthedocs
- Explore Python Libraries: Speed Up HTTP Tests with VCR.py article article (Pluralsight)
- Automatically mock your HTTP interactions to simplify and speed up testing article
Article originally published in my github pages: Test HTTP and API interactions with vcrpy