Python testing
Python Testing#
Testing Framework#
Possible Ways Of Doing#
- Python
- Using assert; no module require
- Using assert with setup_module(module) & teardown_module(module) methods for resource setup (define global variables)
- unittest framework
- class level:
- inherit unittest.TestCase
- override setUP(self) method for resource setup as class members
- use self.assertEqual(var1, var2) or self.assertNotEqual(var1, var2)
- class level:
- pytest framework
- by functions: using assert & @pytest.fixture(scope="module") for resource setup
- by classes: (define all test cases inside) using assert & @pytest.fixture(scope="class") for resource setup
- Django
- Using django.test
- from django.test import TestCase
- same as unittest
- define class and inherit TestCase
- define test_cases(self) method
- use self.assertIs(var, bool)
- Using django.test
1. unittest Testing Framework#
Intro#
- Inbuilt
- Class based
- import class unittest.TestCase
- define setUp method for setup resources
- define testcase method for assertion/testing
- execution: run the module or python -m unittest test_module_name.py
- Note: Module & method should have 'test_' prefix & class have 'Test' prefix
- e.g.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
mock Library (Python 2.x) & unittest.mock Library (Python 3.x)#
Intro#
unittest.mock is a library for testing in Python. It allows us to replace parts of our system under test with mock objects and make assertions about how they have been used.
It is based on the 'action --> assertion' pattern instead of 'record --> replay' used by many mocking framework.
Features#
- Mock class
- patch() decorator
- MagicMock class
Why#
-
**Increased speed â ** Tests that run quickly are extremely beneficial. E.g. if you have a very resource intensive function, a mock of that function would cut down on unnecessary resource usage during testing, therefore reducing test run time.
-
**Avoiding undesired side effects during testing â ** If you are testing a function which makes calls to an external API, you may not want to make an actual API call every time you run your tests. You'd have to change your code every time that API changes, or there may be some rate limits, but mocking helps you avoid that.
2. pytest Framework#
-
Introduction:
- The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.
-
Source:
- https://pypi.python.org/pypi/pytest/3.2.3
- https://docs.pytest.org/en/latest/contents.html#toc
-
Installation:
- pip install pytest
-
execution:
- execute: pytest pytest_ex1.py
Types#
assert#
It's an standard python statement for verifying expectations and values. Input type: logical conditions Output: * Nothing/blank, if true * Raise AssertionError exception, if false
e.g.
1 2 3 4 5 6 7 8 9 10 |
|
Running multiple tests#
pytest will run all files in the current directory and its subdirectories of the form test_.py or _test.py. More generally, it follows standard test discovery rules.
Asserting that a certain exception is raised#
If you want to assert that some code raises an exception you can use the raises helper:
1 2 3 4 5 6 7 8 |
|
Grouping multiple tests in a class#
Once you start to have more than a few tests it often makes sense to group tests logically, in classes and modules. Letâs write a class containing two tests:
1 2 3 4 5 6 7 8 9 |
|
The two tests are found because of the standard Conventions for Python test discovery. There is no need to subclass anything. We can simply run the module by passing its filename:
1 |
|
Resource Setup#
- setup & teardown (classic xunit style)
- fixture (recommended)
- complies with dependency injection
Features#
- Detailed informations on assert statements
- Auto-discovery of test modules and functions to study
- Modular fixtures for managing small or parameterized long-lived test resources to study
3. coverage.py Tool#
Intro#
- a tool for measuring code coverage of Python programs
- It monitors your program, noting which parts of the code have been executed, then analyzes the source to identify code that could have been executed but was not
- Use
- typically used to gauge the effectiveness of tests.
- It can show which parts of your code are being exercised by tests, and which are not.
Quick Start#
-
Install using
2. run the module1
pip install coverage
3. get coverage report1
coverage run my_program.py arg1 arg2
1
coverage report -m
-
get coverage report in html
1
coverage html
Best Practices#
-
https://www.jayfreestone.com/writing/opinionated-guide-to-unit-tests/