Esta charla no trata sobre buenas prácticas de testing sino de la presentación y consejos de uso sobre una selección “curada” de plugins de pytest., dentro del gran ecosistema, que hemos ido encontrando durante el desarrollo de proyectos, sobretodo de proyectos con Django. Esta charla está pensada para introducir a los desarrolladores una serie de paquetes para usar conjuntamente con pytest para tareas de testing, bien sea para tests unitarios, funcionales o de integración, y sobretodo, aplicado a proyectos Django. Se explicará brevemente los conceptos básicos de pytest. Algunos de los paquetes que se comentaran serán: pytest-django, pytest-watch, pytest-testmon, model-mommy, pytest-flake8..
2. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Who am I
Andreu Vallbona @avallbona
Bachelor degree in computer science
Web developer at APSL, Mallorca, Spain
Mainly developing with Python and Django
3. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
What we do at APSL
Web development
Systems engineering - devops
Data science
Mobile apps
Consulting and formation
4. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Advantages
Advantages
5. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Advantages
● Ensure the quality of the code
● Confidence when changes/refactors are made
● Facilitate Python and / or Django version
upgrades
● Ease in database system changes (e.g.: from
mysql to postgres)
6. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Why pytest?
Why pytest?
7. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Why pytest?
● Very little boilerplate code, which makes tests
easy to write and understand
● Can easily be extended with plugins
● Parametrize any test and cover all uses of a
unit without code duplication
● Uses fixtures as a method to recreate previous
scenario
8. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Why pytest?
9. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Recommendations
Recommendations
10. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Recommendations
● Test database in local and / or memory
● Be careful with the signals of Django
● Mock external services
● Concurrent execution
● Review PEP8
11. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Recommendations
● Do not overly sophisticate the tests
● Self-contained and independent tests
● Use parametrize
● Use fixtures
12. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Fixtures are objects/dependencies that we predefine and can then be used
by our test functions. You can define different scopes:
● function level: runs once per test
● class level: runs once per test class
● module level: runs once per per module
● session level: runs once per session
fixtures
13. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Fixtures can be parametrized
fixtures
14. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Fixtures can be autoinjected to test functions
fixtures
15. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Plugins
16. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest plugin that gives us a whole series of helpers and fixtures very useful
to test projects implemented in Django. Among others we can highlight:
● django_db - gives access to the database
● rf - request factory
● client - test client
● admin_client - authenticated test client
● admin_user - authenticated superuser
● settings - access to the django settings
● mailoutbox - mailbox where to test the sending of emails
pytest-django
17. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Some key features of this plugin are:
● allow us to set a settings for the test scenario
● allow us to reuse the test database between test sessions
● allow us not to execute the migrations when creates the test database, it
create the test database directly from the models
pytest-django
18. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
●
pytest-django
19. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-django
20. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Allow us to populate easily the database with initial test data
pytest-django
21. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Package that helps us to easily create fixtures based on django models very
easily
● field values are generated automatically
● random content of the fields but can be specified individually
● You can create objects:
○ in memory (mommy.prepare) useful for unit tests model methods
○ persistent (mommy.make) useful for integration tests
● you can define relationships between objects (fk, m2m)
● you can define recipes, which are like templates
● sequence fields can be defined
model-mommy
22. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Giving the following model:
model-mommy
23. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
We could generate an instance of it with:
model-mommy
24. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
and then use it in a test:
model-mommy
25. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
example of sequence fields
that would generate 3 instances of the model Administrator and the value of
the name field would be respectively
model-mommy
26. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
custom generator for specific fields types
model-mommy
27. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
model mommy or factoryboy
model-mommy
28. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
model mommy or factoryboy
model-mommy
29. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Plugin that helps us to use the fixtures in lazy mode, which allows us, for
example, to use the fixtures as parameters with the parametrize.
pytest-lazy-fixture
30. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Plugin that helps us to use the fixtures in lazy mode, which allows us, for
example, to use the fixtures as parameters with the parametrize.
pytest-lazy-fixture
31. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
This plugin installs a mocker fixture which is a thin-wrapper around the
patching API provided by the mock package.
Allows us to patch a certain function or method in order to be able to test
our logic given an specific mocked result.
E.g. Test calls to external services, such as a call to an external API.
pytest-mock
32. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Given a certain method
pytest-mock
33. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
And an expected result
pytest-mock
34. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
We can mock the method as:
pytest-mock
35. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Plugin that helps us verify that we do not leave any breakpoint inserted in our
code. It analyzes the Abstract Syntax Tree of our code.
pytest-checkipdb
36. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
And warn us
pytest-checkipdb
37. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Plugin that helps us detect which part of our code is not yet "covered" by the
tests. Allows us to generate reports to easily see untested parts
pytest-cov
38. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Small case example without testing
pytest-cov
39. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Plugin that helps us to ensure that our code follows a style guide, for
example, in the case of python, the PEP8
pytest-flake8
40. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-sugar
Plugin that helps us to change the look & feel of the pytest output
41. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
freezegun
Package that helps us to "freeze" time. If we have methods that makes use
of the functions:
datetime.datetime.now(), datetime.datetime.utcnow(), datetime.date.today(),
time.time(), time.localtime(), time.gmtime(), time.strftime()
Will always return the moment (date and / or time) in which they have been
frozen.
42. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
freezegun
Simple example
43. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
freezegun
We can generate data
44. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
freezegun
and then check it
45. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-eradicate
Plugin that detect if we left commented code. Is able to differentiate
commented code from real comments.
Before executing pytest --eradicate
46. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-eradicate
Plugin that detect if we left commented code. Is able to differentiate
commented code from real comments.
After executing pytest --eradicate
47. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-eradicate
Plugin that detect if we left commented code. Is able to differentiate
commented code from real comments.
48. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-xdist
Plugin that allows us to run tests in parallel, allows us to reduce the total
execution time.
It is mandatory that the tests are completely self-contained for the use of
xdist.
When tests are invoked with xdist, pytest-django will create a separate test
database for each process. Each test database will be given a suffix
(something like “gw0”, “gw1”) to map to a xdist process.
49. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-xdist
50. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-xdist
51. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
Package that helps us generate data random for our specification or data
model.
Helps us to test that our code works for any value within a range and not
only for specific cases.
hypothesis
52. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
hypothesis
53. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
hypothesis
54. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-watch
It helps us to re-launch, automatically, the tests when changes have been
detected in the project files
Allows us to execute commands before and after the execution of the tests
and also commands depending on the success or failure of the tests
We use it in combination with the following plugin, pytest-testmon
55. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-testmon
Select and re-execute only the tests affected by the latest changes, whether
they are changes in business classes or in the tests themselves
https://www.youtube.com/watch?v=1xahPJ_LNXM&feature=youtu.be
56. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-testmon
Select and re-execute only the tests affected by the latest changes, whether
they are changes in business classes or in the tests themselves
57. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-splinter
Plugin that allow us to execute browser session for the execution of
functional tests
It gives us a bunch of fixtures
Allow to capture the screen when an error has ocurred
It allows us to execute the tests on remote servers (e.g.: sauce labs)
58. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-splinter
Allows the execution of javascript inside the test itself
59. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-splinter
Test example
60. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Plugins
pytest-splinter
Test example
61. Andreu Vallbona - PyBCN - June 2019Pytest: recommendations and basic packages for testing in Python and Django
Thanks
That’s all.
Thank you!
Questions?
@avallbona