Introduction to py.test
Presentation by Jean Cruypenynck/@nonatomiclabs
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!
- good documentation
- hooks for all steps
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,433