1/3/19

How to unit test python

Lets start with something simple:
Lets say you have one method called "simple_inc" at module my:

# my.py
def simple_inc(x):   
    return x + 1 
Lets build some test using pytest framework:

# test_my.py
from my import simple_inc
def test_answer():
    res = simple_inc(3)
    assert res == 4
So far so good

Sub Method

Now lets change the code, so the "simple_inc" will use some sub method, lets call it "simple_child_inc":

def simple_inc(x):   
    return simple_child_inc(x)

def simple_child_inc(x):   
    return x + 1   
Now the test still should run as before, without any problems...

Mocking Sub Method

Since we want to stick to single responsibility principle, it will be better not to call the "real" submethod but its mock :

@mock.patch('my.simple_child_inc') 
def test_answer(mock_simple_child_inc):
    mock_simple_child_inc.return_value = 4 // correct val
    res = simple_inc(3)
    assert res == 4

If we change the correct value of the mock - the test will fail

@mock.patch('my.simple_child_inc') 
def test_answer(mock_simple_child_inc):
    mock_simple_child_inc.return_value = 4 // INCORRECT val
    res = simple_inc(3)
    assert res == 4

Async Method

Lets say the method we are testing is asynchronous:


import asyncio
async def inc(x):
    await asyncio.sleep(0.1)
    return x + 1

So the test should be modified in following way:

import asyncio

@pytest.mark.asyncio
async def test_answer():
    res = await inc(3)
    assert res == 4
The following test will also work if we make "inc" method to call "child_inc" (which is also async)

import asyncio

async def inc(x):
    res = await child_inc(x)
    return res

async def child_inc(x):
    await asyncio.sleep(0.1)
    return x + 1

Mocking Async Method

All we have to do is add asynctest package:


pip install asynctest
Now can change test:

import asynctest


@pytest.mark.asyncio
@asynctest.patch('my.child_inc')
async def test_answer(mock_child_inc):
    mock_child_inc.return_value = 4
    res = await inc(3)
    assert res == 4

Getting started with docker

It is very simple to get started usig docker. All you need to do-is download the docker desktop for your system Once you get docker syste...