PythonTesting - mwicat/personal GitHub Wiki

Mocking function calls and return values

from unittest.mock import Mock, patch, MagicMock


@patch('my.module.my_fun')
def test_something(my_fun_mock):
    my_fun_mock.return_value = my_return_value
    my_fun_mock.return_value = [
        MagicMock(__len__=Mock(return_value=0)),
    ]
sudo pip install pytest pylama
# content of test_expectation.py
import pytest


@pytest.fixture
def smtp_connection():
   import smtplib
   return smtplib.SMTP("smtp.gmail.com", 587, timeout=5)

@pytest.fixture
def auth_statsd_mock():
    with patch('myprog.release.auth.statsd') as mock:
        yield mock

@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 54)])
def test_eval(smtp_connection, test_input, expected):
        assert eval(test_input) == expected
pytest
pylama

Test with web client

django

https://pytest-django.readthedocs.io/en/latest/helpers.html#fixtures

from django.urls import reverse

def test_none_matched(client, find_active_campaigns_mock):
    url = reverse('api:suggest_notifications')

    res = client.post(url, data={
        'country': 'ru',
        'lang': 'pl'
    })

    find_active_campaigns_mock.assert_called_once()

    assert res.status_code == 204
    res.render()
    assert res.content == b''

django rest framework

https://www.django-rest-framework.org/api-guide/testing/

from django.urls import reverse

from rest_framework.test import APIClient

@pytest.fixture
def api_client():
    key = 'test'
    client = APIClient()
    client.credentials(HTTP_AUTHORIZATION='Token {}'.format(key))
    yield client

def test_adding_ok(api_client, auth_statsd_mock,
                   mongo_test_conn, campaign_data):
    url = reverse('release:campaign-list')
    res = api_client.post(url, campaign_data)
    assert res.status_code == 201, 'Failed: %s' % res.content
    assert Campaign.objects.count() == 1
    auth_statsd_mock.incr.assert_called_with('api.v1.auth.ok.test')

Parametrize with raises

from contextlib import contextmanager
import pytest


@contextmanager
def does_not_raise():
    yield


@pytest.mark.parametrize(
    "example_input,expectation",
    [
        (3, does_not_raise()),
        (2, does_not_raise()),
        (1, does_not_raise()),
        (0, pytest.raises(ZeroDivisionError)),
    ],
)
def test_division(example_input, expectation):
    """Test how much I know division."""
    with expectation:
        assert (6 / example_input) is not None

Coverage

sudo pip3 install pytest pytest-cov

Terminal report

pytest --cov --cov-append --cov-report=term-missing src/

HTML report

pytest --cov --cov-append --cov-report=html src/
xdg-open htmlcov/index.html