Testing APIs offline and fast with vcrpy
Motivation
While testing code against online sources like websites or APIs I often find myself waiting for their responses. Furthermore it feels strange to knock on anyone’s door every couple of seconds just to test what I’m processing locally anyway.
A solution for this issue comes in the form of vcrpy.
Vcrpy frees you from the burden of waiting or even to be online at all. Responses are stored locally in the form of yaml files called cassettes.
In the following post I’ll test against Migros’ mobile plan named M-Budget. Migros is one of Switzerland’s largest wholesale retailers.
The test consists of asserting a word’s appearance on Migros’ website.
Requirements
Python
python --version
Python 3.8.1
Module
pip install --user pytest
pip install --user pytest-vcr
Create the test
|
|
Line 10 says we want our cassetes saved in home/ra/tmp/vhs/test_mbudget
Line 15 asserts the appearance of the word ‘csrf-token’ in the requested website’s source
Run the test
pytest ~/tmp/vhs/test_mbudget.py
============================= test session starts ==============================
platform linux -- Python 3.8.1, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: /home/ra
plugins: vcr-1.0.2, pycharm-0.5.0
collected 1 item
../tmp/vhs/test_mbudget.py . [100%]
============================== 1 passed in 11.40s ==============================
Note the time the test needed to pass: 11.40s
Check folders and files
Check the newly created cassettes folder
tree ~/tmp/vhs/
/home/ra/tmp/vhs/
├── __pycache__
│ └── test_mbudget.cpython-38-pytest-5.3.5.pyc
├── test_mbudget
│ └── test_mbudget.yaml
└── test_mbudget.py
2 directories, 3 files
Check the created file
cat ~/tmp/vhs/test_mbudget/test_mbudget.yaml | grep 'csrf-token'
/>\n<meta name=\"csrf-token\" content=\"wtwue7j8wcWPZEw2iI3aJtohGxfN9iSMVlGdbf4kUyT31iupUO2EyJ2i/aZA8z+LHclUsYBbH+HTrScrIaxGyg==\"
Go offline
Let’s disable our network connection
sudo ip link set wlp3s0 down
Run the test again - offline
pytest ~/tmp/vhs/test_mbudget.py
============================= test session starts ==============================
platform linux -- Python 3.8.1, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: /home/ra
plugins: vcr-1.0.2, pycharm-0.5.0
collected 1 item
../tmp/vhs/test_mbudget.py . [100%]
============================== 1 passed in 0.05s ===============================
Note how much faster (0.05s) the test ran and we’re offline
.
Go back online
Mind to re-enable your network connection
sudo ip link set wlp3s0 up
Conclusion
We were able to reduce waiting from 11 seconds to 0.5 seconds (you’re already doing the ratio math in your head, right?). Furthermore we’re able to continue our development offline and aren’t bothering anyone with countless requests.
Or simply quoting vcrpy’s unique selling propositions:
- The ability to work offline
- Completely deterministic tests
- Increased test execution speed