3 minute read


To gain experience using Pytest I am going to write code that works like a calculator.

I will test it using pytest.

Then I’ll automate and streamline the test and delivery process.

You can find more articles of this series with the Pytest tag


The code we will be testing

Since we need code to run some tests against it we will be testing a couple of simple and straightforward calculator functions. They will serve the porpouse of testing well since they receive and input and return a result value which will be useful when running assertions to decide if the test was successful or not.

You can clone the code from this repository


def add(x, y):
   return x + y

def subtract(x, y):
   return x - y

def multiply(x, y):
   return x * y

def divide(x, y):
   return x / y


There are 4 python functions , they all receive 2 parameters and operate with them to return an integer as a result.

There are multiple tests that can be run against this fairly simple set of functions.

  • use good input, test that the application returns the correct value
  • use a list of good input, test that the application returns the correct value consistently
  • use bad input, test if the application santizes it
  • use bad input, test that the application returns the correct value
  • and many many more

We will start slow, writing a single test case for every function where we test them with the same input , 8 and 2.

The tests



import calculator

def test_add():
    result = calculator.add(8, 2)
    expected = 10
    assert result == expected

def test_substract():
    result = calculator.subtract(8, 2)
    expected = 6
    assert result == expected

def test_multiply():
    result = calculator.multiply(8, 2)
    expected = 16
    assert result == expected

def test_divide():
    result = calculator.divide(8, 2)
    expected = 4
    assert result == expected


We will start by importing the code to be tested. We’ll be interacting with it on every test.

There is a test for every function writen on the code package.

There is a simple structure we follow for every test.


def test_add():

// We called the function with the preset 
// parameters and save its output to a 
// variable called result.

    result = calculator.add(8, 2)
	
// we set the expected result, what the 
// function should return given the 
// predefined parameters.

    expected = 10
	
// We compare the expected output against
// the real output to check if the code 
// is working as expected.

    assert result == expected

Running our tests against the code

The simplest way to run our test against our code is to launch pytest thourgh the cli while on the root folder of our project

Default pytest execution


pytest

If you only want to run the tests located on the V1 folder you can change the current path of your cli to that folder to run the command from there.

This will gather our test file and run all the tests for us. The previous command output should look something like this


=========== test session starts ==============
platform win32 -- Python 3.9.0, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
rootdir: C:\ww\ww\ww\testingwithpytest
collected 4 items

test_calculator.py ....

[100%]

=========== 4 passed in 0.02s =================

It ouputs some debugging information, the number of tests that will be executed and, afterwards, the results.

If a test failed it would output it’s information.

Verbose pytest execution

Running the command pytest with the verbose option will output debugging information and the name of each individual test with it’s result


pytest - v


========== test session starts ==========
platform win32 -- Python 3.9.0, pytest-6.2.1, py-1.10.0, pluggy-0.13.1 -- 
c:\ww\ww\ww\testingwithpytest\venv\scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\ww\ww\ww\testingwithpytest
collected 4 items

test_calculator.py::test_add PASSED
[ 25%]
test_calculator.py::test_substract PASSED
[ 50%]
test_calculator.py::test_multiply PASSED
[ 75%]
test_calculator.py::test_divide PASSED
[100%]

========== 4 passed in 0.03s ============