Pytest is one of the best open-source, simple, scalable and Python-based Test Automation Framework available at the market today. Pytest powers you to test anything including Databases, UI and is more popular among testers for API Testing. It can either be run as an individual tool for testing or it can be attached to Python web development frameworks like Django or Flask, enhancing their unit test capabilities and reliability. Tests in Pytest are basically python functions and we can run tests as whole, or specifically based on tags or names. Also, parallel test running feature is inbuilt to Pytest and you can access that by simply specifying an extra argument to CLI pytest run.
Creating tests in pytest is simple as writing a Python Function, except the function name should start with ‘test_’. We can use statements like assert to verify whether the expected output is the same as actual output. We can also write test classes. But in this blog, we will stick with writing functions.
Example:
Here we are going to test a simple function that returns an Integer 10. In our test, we will verify whether we got the expected output.
Program test_fun.py
def my_func():
return 10
def test_my_func():
expected_out = 10
assert my_func() == expected_out
We can execute this test using pytest CLI and verify whether everything works fine.
Output:
In order to use pytest, we need python in our PC and then ‘pip install pytest’. In the below example we can see that, we ran only specifying command pytest, not even the file name.
In the example.1, we ran a test without specifying anything, by utilizing the pytest inbuilt intelligent test auto-discovery feature. Pytest can automatically identify test functions name starting with ‘test_’ and files names starting with ‘test’ or ending with ‘_test’ from the directory and the sub-directories. We can introduce other name patterns to be included in this test auto-discovery by configuring pytest.ini.
Pytest has so many awesome features under the hood which are available as command-line arguments. You can see it all by typing ‘pytest –help’. I’ll explain some basic ones here.
Run tests in the specified file
e.g: pytest test_demo.py
Runs the specified function in the specified file, we can specify multiple files in the same format
e.g:pytest test_demo::test_addition
Runs all the tests with specified markers, user for grouping
In test automation, there will be some scenarios where we need to automate similar test cases with minute differences. For example, we may need to verify whether some sites are accessible via http and https and do some more similar steps. So if there are 15 steps 13 will be similar, instead of writing two different test cases, pytest provides a functionality called Parameterization, where we can club them as one and parameterize them with the changing variables.
Example:
Program test_parameterization.py
from pytest import mark
@mark.parametrize(“http_method”,[‘http’, ‘https’])
def test_my_func(http_method):
# Some steps
print(http_method)
# Some more steps
Output:
Here we can see that, both of the parameters where executes as different tests.
Fixtures are a special type of function which will run before test function, module, or the whole session based on their configuration and return any intended values. They will help us to execute a piece of code. Like we may need to create a database object or so on and then return them if necessary. A fixture can be session-scoped, module scoped or function scoped and that defines their lifetime.
Example:
We are returning a string to test functions as an example. We can do a lot more using these fixtures.
Program test_db.py
import pytest
@pytest.fixture
def input_value():
database = ‘my_sql’
return database
def test_div_3(input_value):
print(input_value)
def test_div_5(input_value):
print(input_value)
Output :
Hooks are a great way to modify the behavior of the pytest like test identification, logging. It also helps to set up something on startup and so on. We generally write hooks and fixtures in a file in the main directory which contains the test.
Markers help us to easily categories our test. We can do any number of marking and choose which one to run at the test run starting time. Also some markers have some special behavior. For example we can mark a test as skip and that test won’t be executed as part of the run
Example:
import pytest
@pytest.mark.runthis
def test_div_3():
print(“Marked Test”) +
@pytest.mark.skip
def test_div_5():
print(“Skipped Test”)
Output :
In the output, only the markers given behind them are run. If you don’t specify any markers in CLI command every test marked as skip will be avoided.
Plug-in is a great way to extend the functionality of pytest. Some of the commonly used plugins are
Apart from showing a log in the CLI, PyTest has inbuilt feature to write the logs to a file. For example you can use PyTest–junitxml=<path> to store the logs in the specified path.
PyTest is still gaining popularity and the community is also developing more and more plugins and features for PyTest. Hope you can take advantage of PyTest and its features in automation testing APIs or any other kind of testing.