Isaak Uchakaev
7 Jul 2021
•
7 min read
Experienced programmers understand perfectly well that in development they spend most of the time reading code and therefore they treat the process of writing code with the deepest trepidation (and sometimes with fanaticism). To write quality and maintainable code, you need to take the time to write tests and integrate QA tools. There is a whole technique aimed at test-driven development (TDD) and I will not devote this article to the topic of testing as such. Tests are absolutely necessary and there is nothing to discuss. In this article, we are going to talk about tools that help you write quality Python code.
Table of content:
pytest is a framework that makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.
Features
unittest
(including trial) and nose test suites out of the box;Hypothesis is a family of testing libraries that let you write tests parametrized by a source of examples. A Hypothesis implementation then generates simple and comprehensible examples that make your tests fail. This simplifies writing your tests and makes them more powerful at the same time, by letting software automate the boring bits and do them to a higher standard than a human would, freeing you to focus on the higher-level test logic.
Robot Framework is a generic open-source automation framework for acceptance testing, acceptance test-driven development (ATDD), and robotic process automation (RPA). It has simple plain text syntax and it can be extended easily with libraries implemented using Python or Java.
unittest is a unit testing framework from Python's stdlib, which was originally inspired by JUnit and has a similar flavor as major unit testing frameworks in other languages. It supports test automation, sharing of setup and shutdown code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework.
tox is a command-line-driven CI frontend and development task automation tool.
tox creates virtual environments for all configured so-called testenvs
, it then installs the project and other necessary dependencies and runs the configured set of commands:
Selenium is an umbrella project encapsulating a variety of tools and libraries enabling web browser automation. Selenium specifically provides an infrastructure for the W3C WebDriver specification — a platform and language-neutral coding interface compatible with all major web browsers.
Locust is an easy-to-use, scriptable, and scalable performance testing tool. You define the behavior of your users in regular Python code, instead of using a clunky UI or domain-specific language. This makes Locust infinitely expandable and very developer-friendly.
TestCafe is a Node.js tool to automate end-to-end web testing. Write tests in JS or TypeScript, run them and view results.
npm install -g testcafe
Usage example:
PyAutoGUI is a cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.
Mimesis is a high-performance fake data generator for Python, which provides data for a variety of purposes in a variety of languages. The fake data could be used to populate a testing database, create fake API endpoints, create JSON and XML files of arbitrary structure, anonymize data are taken from production and etc.
The key features are:
Performance: The fastest data generator available for Python.
Extensibility: You can create your own data providers and use them with Mimesis.
Generic data provider: The simplified access to all the providers from a single object.
Multilingual: Supports data for a lot of languages.
Data variety: Supports a lot of data providers for a variety of purposes.
Schema-based generators: Provides an easy mechanism to generate data by the schema of any complexity.
Country-specific data providers: Provides data specific only for some countries.
unittest.mock is a library from Python's stdlib for mocking. It allows you to replace parts of your system under test with mock objects and make assertions about how they have been used.
unittest.mock
provides a core Mock
class removing the need to create a host of stubs throughout your test suite.
After performing an action, you can make assertions about which methods/attributes were used and arguments they
were called with. You can also specify return values and set needed attributes in the normal way.
FreezeGun is a library that allows your Python tests to travel through time by mocking the datetime module.
Once the decorator or context manager have been invoked, all calls to datetime.datetime.now()
,
datetime.datetime.utcnow()
, datetime.date.today()
, time.time()
, time.localtime()
, time.gmtime()
, and time.strftime()
will return the time that has been frozen.
HTTPretty is an HTTP client mocking tool for Python - inspired by Fakeweb for Ruby.
Common use cases:
responses is a utility library for mocking out the requests Python library.
Example of usage:
import responses
import requests
@responses.activate
def test_simple():
responses.add(responses.GET, 'http://twitter.com/api/1/foobar',
json={'error': 'not found'}, status=404)
resp = requests.get('http://twitter.com/api/1/foobar')
assert resp.json() == {"error": "not found"}
assert len(responses.calls) == 1
assert responses.calls[0].request.url == 'http://twitter.com/api/1/foobar'
assert responses.calls[0].response.text == '{"error": "not found"}'
Coverage.py measures code coverage, typically during test execution. It uses the code analysis tools and tracing hooks provided in the Python standard library to determine which lines are executable, and which have been executed.
factory_boy is a fixtures replacement based on thoughtbot's factory_bot.
As a fixtures replacement tool, it aims to replace static, hard to maintain fixtures with easy-to-use factories for complex objects.
wemake-python-styleguide is is strictest and most opinionated python linter ever.
Goals of WPS:
Python 3.6+
usagepycodestyle is a tool to check your Python code against some of the style conventions in PEP8.
Features:
stdlib
. You can use just the pycodestyle.py
file for this purpose.Black is the uncompromising Python code formatter. By using it, you agree to cede
control over minutiae of hand-formatting. In return, Black gives you speed,
determinism, and freedom from pycodestyle
nagging about formatting. You will save time
and mental energy for more important matters.
yapf is a formatter for Python files.
YAPF takes a different approach. It's based off of clang-format
, developed by Daniel Jasper. In essence,
the algorithm takes the code and reformats it to the best formatting that conforms to the style guide, even if the
original code didn't violate the style guide. The idea is also similar to the 'gofmt' tool for the Go programming
language: end all holy wars about formatting - if the whole codebase of a project is simply piped through YAPF
whenever modifications are made, the style remains consistent throughout the project and there's no point
arguing about style in every code review.
mypy is an optional static type checker for Python. You can add type
hints (PEP 484) to your Python programs, and use mypy
to type check them statically. Find bugs in your
programs without even running them!
Here is a small example to whet your appetite (Python 3):
from typing import Iterator
def fib(n: int) -> Iterator[int]:
a, b = 0, 1
while a < n:
yield a
a, b = b, a + b
Pyre is a performant type checker for Python compliant with PEP 484. Pyre can analyze codebases with millions of lines of code incrementally – providing instantaneous feedback to developers as they write code.
Pyre ships with Pysa, a security-focused static analysis tool we've built on top of Pyre that reasons about data flows in Python applications. Please refer to our documentation to get started with our security analysis.
Typeshed contains external type annotations for the Python standard library and Python builtins, as well as third party packages as contributed by people external to those projects.
django-stubs contains type stubs and a custom mypy
plugin to
provide more precise static types and type inference for Django
framework. Django uses some Python "magic"
that makes having precise types for some code patterns problematic. This is why we need this project. The final goal
is to be able to get precise types for most common patterns.
returns gonna make your functions return something meaningful, typed, and safe!
Features:
mypy
, PEP561 compatibleThat's it for now!
Ground Floor, Verse Building, 18 Brunswick Place, London, N1 6DZ
108 E 16th Street, New York, NY 10003
Join over 111,000 others and get access to exclusive content, job opportunities and more!