Skip tests based on tracing data
Project description
YourBase Python Acceleration
Tests are important. For large monoliths, they're also a major source of drag on velocity.
YourBase is a tool that traces your tests to determine which functions each test depends on. It can later use this information to determine which tests don't need to run because their code paths have not changed. These tests are skipped automatically.
No configuration, setup, or babysitting required. All you need is
pip install yourbase
YourBase works with Python 2.7+ and Python 3.5+; using pytest
or
unittest
.
Access
YourBase will work for free locally for 14 days. Please consider purchasing a license if you like it -- those who do generally get more back than they spend.
A license also lets YourBase work in your CI, and synchronize its tracing data among an arbitrary number of machines (without leaving your network).
First run
After installing yourbase
, if you are using unittest
you must put
import unittest
import yourbase
yourbase.attach(unittest)
in a file that runs before your tests (e.g. tests/__init__.py
). Do not do this
step if you are using pytest
.
Run your tests with the same command you typically use. You should see some output from YourBase similar to
[YB] Starting Python acceleration
The first run will be cold, so if you just want to see YourBase in action and your tests are going to take a while, you can run a subset of tests. Tracing data for the subset will be used correctly even if you later run all tests.
After the run finishes, running again will skip all tests. Modifying a dependency will run only tests whose code paths touched the changed code. You're YourBased! 🚀
Installing for yourself vs. your team
If you add YourBase to your requirements file, it will work with no configuration for your whole team. However if you want to just try it out yourself, you can choose not to add it. Either way, YourBase will behave the same.
Forcing specific tests to run
You can tell YourBase to never skip specific tests with decorators:
# pytest
import pytest
@pytest.mark.do_not_accelerate
def test_function():
# ...
# unittest
import yourbase.plugins.unittest as yourbase
@yourbase.do_not_accelerate
class TestClass(unittest.TestCase):
def test_function():
# ...
The test or group will never be skipped due to unchanged dependencies. If you are using test cohorting (below), it may still be skipped if it is not assigned to the running shard.
We do not yet support this feature for unittest
.
Synchronizing tracing data
By default, YourBase's tracing data will not leave the machine it was gathered on without further configuration. This means CI or containerized test runs will not be able to share tracing data forward, kneecapping YourBase.
To solve this, YourBase can be made to share tracing data among any number of machines using an S3 bucket as a collaboration point. To do so, all machines should set
YOURBASE_REMOTE_CACHE=s3://BUCKETNAME
where BUCKETNAME
is an S3 bucket that each machine has Get/Put/List access to.
Any successful tracing data generated for a clean working tree will be
synchronized to this location after tests have finished.
The tracing data includes test names, file names, function names, and a small amount of metadata like commit hash and build time. Your code will never be uploaded to the bucket. Neither your code nor any of your tracing data will touch YourBase servers.
It is safe to share one bucket between multiple repositories, even if across multiple YourBase-supported languages.
You can optionally specify a key prefix using the path component:
# A trailing slash will be added if absent
YOURBASE_REMOTE_CACHE=s3://BUCKETNAME/path/to/anywhere
AWS credentials
We'll use the system AWS credentials by default. This can be configured via environment variables or AWS CLI configuration files
# To use system AWS credentials via environmental variables, ensure your
# credentials are exported in your environment.
export AWS_ACCESS_KEY_ID=changeme
export AWS_SECRET_ACCESS_KEY=changeme
If you're setting the system AWS credentials to bogus values for the purposes of your tests and/or CI, you can set these YourBase specific environment variables instead:
# To set YourBase specific AWS credentials, export the following:
export YOURBASE_AWS_ACCESS_KEY_ID=changeme
export YOURBASE_AWS_SECRET_ACCESS_KEY=changeme
If these are set, we'll use them instead of the system credentials.
Cohorting / sharding
YourBase supports sharding your tests without negatively affecting tracing or acceleration. It uses consistent hashing to split tests into cohorts that stay the same between runs, even as the test pool grows or shrinks.
- Set
YOURBASE_COHORT_COUNT
to the number of cohorts your tests should be split into. This should be the same among all shards. - Set
YOURBASE_ACTIVE_COHORT
to the cohort ID this run should identify as, starting with 1. This should be different among all shards.
Without these set, YourBase assumes a value of "1"
for both, meaning one shard
will run one cohort; that cohort will contain all tests.
Note that tests are only guaranteed to remain in the same cohort as long as
YOURBASE_COHORT_COUNT
doesn't change.
Compatibility
Poetry
YourBase is compatible with the packaging and dependency management tool Poetry. Once the YourBase package is installed, simply use Poetry as normally.
For example:
# Install the YourBase package
poetry add yourbase
# Execute tests
poetry run pytest
Known issues
Incorrectly skipped tests
If you are using unittest
and define your own setUp
/tearDown
functions, be
sure they call super
before performing other actions:
class MyTestClass:
def setUp(self):
super(self.__class__, self).setUp()
# ...
def tearDown(self):
super(self.__class__, self).tearDown()
# ...
If you are not defining your own setUp
and tearDown
functions, you do not
need to do this.
Errors
If you run into errors about the _sqlite3
module not being found, first run
# Debian-based
sudo apt-get install libsqlite3-dev
# macOS
brew install sqlite3
then rebuild and reinstall the Python version you are using. If you use
pyenv
, this will look something like
pyenv install --force <PYTHON_VERSION>
# If that doesn't work, try
PYTHON_CONFIGURE_OPTS="--enable-loadable-sqlite-extensions" pyenv install --force <PYTHON_VERSION>
Conflicts
Coverage.py's dynamic_context
option
YourBase has a tracing conflict with one particular config setting in your .coveragerc
:
[run]
dynamic_context = test_function
If this specific key is set to this specific value, YourBase will "miss" some functions when tracing tests, causing its subsequent runs to skip tests that should not be skipped.
You can work around this by either unsetting the option, or by enabling YourBase's experimental line-granularity tracing, which does not conflict with this setting:
export YOURBASE_TRACING_TYPE=line
Although this circumvents the issue, this tracing type is in early stages and is less stable than function-granularity tracing (the default).
If you do not have this specific setting set in your .coveragerc
or in
Coverage.py's command line arguments, you do not have to worry about this issue.
Proxy objects
Python objects that opaquely wrap other objects by overriding Python builtins
like __name__
and __class__
can cause tracing issues in YourBase that may
manifest as errors from within those proxy objects. If you experience these
issues, you can set
export YOURBASE_TIMID=true
to use a slower tracing algorithm that will avoid these errors. Tracing overhead is dramatically increased using this flag, so we don't recommend setting this if you are not experiencing issues.
Contributing
This open source package is a lightweight wrapper for YourBase proprietary code. We welcome contributions to this wrapper, but at this time we have not built shims or mocks to allow it to be tested end to end without both pieces.
Code style
We use Black for code formatting, which is similar in personality to
gofmt
-- ruthless consistency, no configuration. Your build will not pass
CI if the Black run doesn't come back clean, so we recommend you have your
editor automatically run it on save. You can run it manually with
black .
Changelog
- 5.0.7 (2021-05-06)
- Fixes a JSON decoding issue present in Python 3.5
- Fixes a breaking bug when YourBase is enabled alongside tests that use
moto
mocks
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Hashes for yourbase-5.1.1a4-py39-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 17dbe46946bf04d275cb88b9e20e191fd7e88a020f314c92cd5264855c37d94e |
|
MD5 | fe8d217b6a42a3eccf7e0129118d5986 |
|
BLAKE2b-256 | c62da62e87b99211199c7a7142c52318e006477435f03470fc052e3f42e8b2a1 |
Hashes for yourbase-5.1.1a4-py38-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b50832bf4dc4c18c06c7252ffddeb22e08ad7e017fe3f842dd87aa8fd2cc1f76 |
|
MD5 | 1497077636c78ebc256fca6e0d888f22 |
|
BLAKE2b-256 | df8c52629dfc95194cdc22ac73966c98e34a41b8e857e9031c6e1e52caeede1a |
Hashes for yourbase-5.1.1a4-py37-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 46d8d93daeef8bb4506f86f4508e4ee2df8a4b7d364d660dfa2c0a3402c203f5 |
|
MD5 | 7e74cb7054c0c268506a3de9b7b63b8f |
|
BLAKE2b-256 | 0b8d804e1c08dcc56e7c09b6de596bc09d6d91f5e1494e1963467ad6ea68d5fb |
Hashes for yourbase-5.1.1a4-py36-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | fcb3a3c5167f249b1692f5120e21258aa5353c89d1dc32b8916e140c46379a15 |
|
MD5 | 56bb93c17e438f4c82516789a45fde6e |
|
BLAKE2b-256 | 3cd22bfc34398f72171209fc875f315fe68b8534b0e478eedd01dcc7edb215ca |
Hashes for yourbase-5.1.1a4-py35-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 985173031d28222aa5b4f34d0e2202a7d8a8cee351f88cb20d5bd447329062e9 |
|
MD5 | 89ebcbd39dfcd8afeed7fe03c5709dac |
|
BLAKE2b-256 | 4656c875c98ae13a85cc0447d2d70d3b6d745ac39122867491e318aed45fb580 |
Hashes for yourbase-5.1.1a4-py27-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 59b39fba8aaafdfb37fd9665dc8da0244921d337a000b10e08579a732d27a0db |
|
MD5 | 8ec239e51e0f165c0cec3adf87ab4206 |
|
BLAKE2b-256 | acd816fc5d7bef55a26c9b13898d1621bade9e755861b69e648a62acf30c196c |