Pytest is an open source python testing framework that allows for super easy standing up of a test framework, collection of tests, and general python goodness. This tutorial shows the basics of how a basic pytest project works and how a simple setup works. Throughout this, I'm using Python 3.7.3, Pytest 5.0.1, and bash on Ubuntu 19.10. The pytest syntax and knowledge should still be applicable to non *nix systems.
Pytest is available through pip. Assuming Python and pip are installed run:
pip install pytest
Create a new folder called
pytest-learning and create the file
my_first_test.py within it. I placed it in my home, but they could be anywhere. By default, these commands will place the files in your current working directory.
This file will contain our first pytests.
Add the following lines to
def test_my_first_ever(): ''' This test simply passes through! By default pytest assumes a test that returns is a test that passes ''' pass
Let's run this test, then talk through it. Navigate inside
cd pytest-learning) and run
pytest. You should see an output like:
Pytest right out of the box creates a neat looking test report. It shows the start of the pytest session, platform + version information, and the name of the test file ran. The "." is pytest's shorthand way of showing that the test has passed. There will be a "." for every test ran. Since there's only one test in
my_first_test.py, we only see one dot. Finally, it ends with how long the session took and how many tests passed.
As mentioned in the doc string, pytest by default will pass any test that doesn't check anything. Typically you'd want to write a test to check a condition which is where the assert statement comes in.
Assert statements are ubiquitous throughout most programming languages. They're often used as a way for developers to check at runtime that their code is working properly. Within a pytest, assert is used to create pass/fail conditions. When the statement after
assert evaluates to true, the test continues until either the test is done or another assert fails. When the statement after
assert evaluates to false, the test fails and pytest moves on to the next test in the sequence. It does not run the rest of the lines in the test by default. Let's look at some examples to illustrate this. These functions are all in my_first_test.py
def test_evaluate_true(): ''' This test passes with an assert. 1 + 1 == 2 evaluates to True so this test will pass. ''' assert 1 + 1 == 2 def test_evaluate_false(): ''' This test fails at the second assert statement. Notice how it fails the entire test despite the other two assert statements evaluating to True. ''' assert 2 + 2 == 4 assert 1 + 1 == 3 assert True
pytest in the
pytest-learning folder and look at the result.
Notice how there are two "." and an F! The two "." represent "test_my_first_ever" and "test_evaluate_true" while the F represents "test_evaluate_false". Pytest makes it clear which exact test is failing and at the exact assert statement. The line labeled ">" is the assert statement that failed. This is labeled failure rather than error on purpose. In a general pytest configuration, failure means an assert within a test case evaluated to false. An error means the python file failed to execute properly. As shown in the this image, test_evaluate_false failed an assert statement, so all of the code preceding that ran (but not neccessarily correctly!).
If we fix the second assert in
assert 1 + 1 == 3) we can get a nice three tests that pass.
Stay tuned for part 2 where we'll take a look at fixtures, command line options and
conftest.py! If you have any comment shoot me a message on github!