pytest
Pytest is a test framework for python. It detects the test files and functions based on their names : test_example.py, example_test().
installation
- -U : upgrade if not installed
To test the installation, use something small, and call you file either test_xxx or xxx_test.py
| test_sample.py | |
|---|---|
So this is a forced wrong assertion, run pytest
| run | |
|---|---|
It will end in red coloured output, ending in :
Mostly your error will be the last section to display. Some handy flags to find the problem better are these :
| -slx | |
|---|---|
- -s : means print the normal output of the program. It will be hidden by default.
- -l : show the local variables
- -x : stop after the first error
However in this simple case, it would not make a difference (no local variables, 1 error and no output)
test discovery
Pytest follows these rules when detecting tests :
- start from the current directory or the one given from the commandline
- Descend into directories, unless they match norecursedirs.
- In those directories, search for test.py or _test.py files, imported by their test package name.
-
From those files, collect test items
-
test_ prefixed test functions or methods outside of class.
- test_ prefixed test functions or methods inside Test prefixed test classes (without an init method).
If you need to test a specific directory, file or function, use this notation:
The less you specify, the wider the test set.
exception testing
To expect an exception use raises()
| exceptions | |
|---|---|
test classes
You can just use flat functions, but a test class can be used as well:
| test classes | |
|---|---|
This class does not have to be instantiated, the test_ functions just get executed like flat functions are.
parameterization
This one is handy, to run a function multiple times with other parameters. This example shows three parameter sets, where the last will fail.
| parameters | |
|---|---|
The parameters are mapped to the test_eval parameters and so this is like running test_eval 3 times :
That opens up some possibilities. I could alter the login function for the portal to :
This compared to a string of blocks each with another setup. You can also use this to parallelize tests with the pytest-parallel plugin. When you install python-parallel you can specify how many workers you want running the tests.
Or any number, auto will assign workers according to your number of cpu's/cores.
This plugin just takes each test_ and puts it in a worker. So if you parametrize your function like this :
| repeat | |
|---|---|
You effectively made 4 test_loop functions, each can be assigned to a worker, and they will each loop through another number of tests in 4 separate browsers. The statistics message in the end will report 4 tests extra, not the number of loops !
To be precise, it counts every function with test_ or _test in the title, and when they are parametrized multiple times.