Introduction to py.test

Why testing is important?

  • a bug is cheap if discovered early
  • more flexible workflow (CI, deployment)

             Coding is good…

… with testing, it is better…

… with automated testing, it is the best

Unit, integration, system?

Unit &

Component

Integration

System

3 main testing layers

Testing in Python?

  • easy to write
  • easy to read
  • easy to run
  • memory & CPU are not problems
  • deployment is not a problem

What is py.test?

pip install pytest
easy_install pytest
  • open-source Python testing tool
  • "helps you write better programs"
  • not included in stdlib but very well-known
  • active since 2007 and actively developed

Write and run your first test

2.  run tests

def test_division():
    assert division(1, 1) == 1

1.  create a function with the test_ prefix

py.test division.py
# Function to test
def division(a, b):
    return a / float(b)

Passing test

Failing test

How are tests discovered?

Any way you can imagine!!!

py.test
py.test test_module.py
py.test test_module.py::test_function
py.test test_module.py -k my_keyword

Skip, xfail, Xpass (1/3)

import pytest

@pytest.mark.skipif()
def test_skipped():
    assert 1
import pytest
import sys

@pytest.mark.skipif(sys.version_info[0] == 3,
                    reason="Only Python 2")
def test_skipped():
    assert 1

Simple

Conditional

Skip, xfail, Xpass (2/3)

@pytest.mark.xfail
def test_division_fail():
    assert division(1, 0) == 1
  • Mark test expected to fail
  • Also allows conditional use

Skip, xfail, Xpass (3/3)

We add exception handling to our function

def division(a, b):
    try:
	return a / float(b)
    except ZeroDivisionError:
	return 1
Output:

Parametrisation

Output:
@pytest.mark.parametrize("a", [1, 2, 3, 4])
def test_division_param(a):
    assert division(a, 1) == a

Fixtures (1/3)

  • Create the test context
    • Test setup
    • Test cleanup
  • Often used to provide instances
  • "Dependency injection"

Fixtures (2/3)

Example: tmpdir

def test_tmpdir(tmpdir):
    assert 0
Output:

Fixtures (3/3)

import pytest

@pytest.fixture
def structure():
    class MyStruct(object):
        text = ""
        num = 10
    return MyStruct()

def test_fix(structure):
    assert isinstance(structure.text, str)
    assert isinstance(structure.num, int)

Plugins

  • web frameworks (django, flask, …)
  • code coverage
  • xdist: multicore test distribution
  • timeout: long tests management
  • pep8
  • … (150+ plugins)

No plugin, write it!

unittest
  • included in stdlib
  • easy to use
  • lot of code to write
  • limited
nose
  • advanced features compared to unittest
  • more configuration needed
  • no fixtures

Other modules?

So, why py.test?

  • runs unittest and nose tests
  • easy
  • advanced features
  • plugins
  • runs on everything
  • good documentation
  • active development
  • used by Fedora, Mozilla, …

Thank you!

Questions?

nonatomiclabs.com

git clone https://github.com/filaton/pytest-intro.git
http://nonatomiclabs.com/blog/?p=89

Ressources

Introduction to py.test

By Jean Cruypenynck

Introduction to py.test

  • 4,318