All Projects → jerry-git → pytest-split

jerry-git / pytest-split

Licence: MIT license
Pytest plugin which splits the test suite to equally sized "sub suites" based on test execution time.

Programming Languages

python
139335 projects - #7 most used programming language

Projects that are alternatives of or similar to pytest-split

pytest-involve
A pytest plugin to run tests pertaining to a specific file or changeset
Stars: ✭ 28 (-69.89%)
Mutual labels:  pytest-plugin
pytest-datafixtures
Data fixtures for pytest made simple
Stars: ✭ 24 (-74.19%)
Mutual labels:  pytest-plugin
pytest-mock-server
Mock server plugin for pytest
Stars: ✭ 19 (-79.57%)
Mutual labels:  pytest-plugin
pytest-stress
A Pytest plugin that allows you to loop tests for a user defined amount of time.
Stars: ✭ 39 (-58.06%)
Mutual labels:  pytest-plugin
pytest-csv
CSV reporter for pytest.
Stars: ✭ 16 (-82.8%)
Mutual labels:  pytest-plugin
pytest-test-groups
A Pytest plugin that gives you a way to split your tests into groups of a specific size
Stars: ✭ 37 (-60.22%)
Mutual labels:  pytest-plugin
pytest-datafiles
pytest plugin to create a tmpdir containing a preconfigured set of files and/or directories.
Stars: ✭ 75 (-19.35%)
Mutual labels:  pytest-plugin
pytest-notebook
A pytest plugin for regression testing and regenerating Jupyter Notebooks
Stars: ✭ 35 (-62.37%)
Mutual labels:  pytest-plugin
pytest-aiohttp
pytest plugin for aiohttp support
Stars: ✭ 110 (+18.28%)
Mutual labels:  pytest-plugin
pytest-snail
Plugin for adding a marker to slow running tests. 🐌
Stars: ✭ 15 (-83.87%)
Mutual labels:  pytest-plugin
pytest-pycodestyle
pytest plugin to run pycodestyle
Stars: ✭ 15 (-83.87%)
Mutual labels:  pytest-plugin
pytest-subprocess
Pytest plugin to fake subprocess.
Stars: ✭ 83 (-10.75%)
Mutual labels:  pytest-plugin
pytest-mongo
This is a pytest plugin, that enables you to test your code that relies on a running MongoDB database. It allows you to specify fixtures for MongoDB process and client.
Stars: ✭ 18 (-80.65%)
Mutual labels:  pytest-plugin
pytest-dependency
Manage dependencies of tests
Stars: ✭ 113 (+21.51%)
Mutual labels:  pytest-plugin
pytest-eth
PyTest plugin for testing smart contracts for Ethereum blockchain.
Stars: ✭ 23 (-75.27%)
Mutual labels:  pytest-plugin
seaworthy
Test harness for Docker container images 🌊 🚢
Stars: ✭ 29 (-68.82%)
Mutual labels:  pytest-plugin
pytest-elk-reporter
A plugin to send pytest test results to ELK stack
Stars: ✭ 17 (-81.72%)
Mutual labels:  pytest-plugin
pytest-localstack
Pytest plugin for local AWS integration tests
Stars: ✭ 66 (-29.03%)
Mutual labels:  pytest-plugin
playwright-pytest
Pytest plugin to write end-to-end browser tests with Playwright.
Stars: ✭ 214 (+130.11%)
Mutual labels:  pytest-plugin
pytest-pipeline
Pytest plugin for functional testing of data analysis pipelines
Stars: ✭ 19 (-79.57%)
Mutual labels:  pytest-plugin

pytest-split

PyPI PyPI - Python Version PyPI - License Coookiecutter - Wolt


Documentation: https://jerry-git.github.io/pytest-split

Source Code: https://github.com/jerry-git/pytest-split

PyPI: https://pypi.org/project/pytest-split/


Pytest plugin which splits the test suite to equally sized "sub suites" based on test execution time.

Motivation

  • Splitting the test suite is a prerequisite for parallelization (who does not want faster CI builds?). It's valuable to have sub suites which execution time is around the same.
  • pytest-test-groups is great but it does not take into account the execution time of sub suites which can lead to notably unbalanced execution times between the sub suites.
  • pytest-xdist is great but it's not suitable for all use cases. For example, some test suites may be fragile considering the order in which the tests are executed. This is of course a fundamental problem in the suite itself but sometimes it's not worth the effort to refactor, especially if the suite is huge (and smells a bit like legacy). Additionally, pytest-split may be a better fit in some use cases considering distributed execution.

Installation

pip install pytest-split

Usage

First we have to store test durations from a complete test suite run. This produces .test_durations file which should be stored in the repo in order to have it available during future test runs. The file path is configurable via --durations-path CLI option.

pytest --store-durations

Then we can have as many splits as we want:

pytest --splits 3 --group 1
pytest --splits 3 --group 2
pytest --splits 3 --group 3

Time goes by, new tests are added and old ones are removed/renamed during development. No worries! pytest-split assumes average test execution time (calculated based on the stored information) for every test which does not have duration information stored. Thus, there's no need to store durations after changing the test suite. However, when there are major changes in the suite compared to what's stored in .test_durations, it's recommended to update the duration information with --store-durations to ensure that the splitting is in balance.

The splitting algorithm can be controlled with the --splitting-algorithm CLI option and defaults to duration_based_chunks. For more information about the different algorithms and their tradeoffs, please see the section below.

CLI commands

slowest-tests

Lists the slowest tests based on the information stored in the test durations file. See slowest-tests --help for more information.

Interactions with other pytest plugins

  • pytest-random-order and pytest-randomly: ⚠️ pytest-split running with the duration_based_chunks algorithm is incompatible with test-order-randomization plugins. Test selection in the groups happens after randomization, potentially causing some tests to be selected in several groups and others not at all. Instead, a global random seed needs to be computed before running the tests (for example using $RANDOM from the shell) and that single seed then needs to be used for all groups by setting the --random-order-seed option.

  • nbval: pytest-split could, in principle, break up a single IPython Notebook into different test groups. This most likely causes broken up pieces to fail (for the very least, package imports are usually done at Cell 1, and so, any broken up piece that doesn't contain Cell 1 will certainly fail). To avoid this, after splitting step is done, test groups are reorganized based on a simple algorithm illustrated in the following cartoon:

image

where the letters (A to E) refer to individual IPython Notebooks, and the numbers refer to the corresponding cell number.

Splitting algorithms

The plugin supports multiple algorithms to split tests into groups. Each algorithm makes different tradeoffs, but generally least_duration should give more balanced groups.

Algorithm Maintains Absolute Order Maintains Relative Order Split Quality Works with random ordering
duration_based_chunks Good
least_duration Better

Explanation of the terms in the table:

  • Absolute Order: whether each group contains all tests between first and last element in the same order as the original list of tests
  • Relative Order: whether each test in each group has the same relative order to its neighbours in the group as in the original list of tests
  • Works with random ordering: whether the algorithm works with test-shuffling tools such as pytest-randomly

The duration_based_chunks algorithm aims to find optimal boundaries for the list of tests and every test group contains all tests between the start and end boundary. The least_duration algorithm walks the list of tests and assigns each test to the group with the smallest current duration.

Demo with GitHub Actions

Development

  • Clone this repository
  • Requirements:
  • Create a virtual environment and install the dependencies
poetry install
  • Activate the virtual environment
poetry shell

Testing

pytest

Documentation

The documentation is automatically generated from the content of the docs directory and from the docstrings of the public signatures of the source code. The documentation is updated and published as a Github project page automatically as part each release.

Releasing

Trigger the Draft release workflow (press Run workflow). This will update the changelog & version and create a GitHub release which is in Draft state.

Find the draft release from the GitHub releases and publish it. When a release is published, it'll trigger release workflow which creates PyPI release and deploys updated documentation.

Pre-commit

Pre-commit hooks run all the auto-formatters (e.g. black, isort), linters (e.g. mypy, flake8), and other quality checks to make sure the changeset is in good shape before a commit/push happens.

You can install the hooks with (runs for each commit):

pre-commit install

Or if you want them to run only for each push:

pre-commit install -t pre-push

Or if you want e.g. want to run all checks manually for all files:

pre-commit run --all-files

This project was generated using the wolt-python-package-cookiecutter template.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].