-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
08eecc8
commit 54d307a
Showing
7 changed files
with
95 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,113 @@ | ||
# Deepcov | ||
|
||
[![PyPI versions](https://img.shields.io/pypi/pyversions/deepcov?logo=python&logoColor=white)](https://pypi.org/project/deepcov) | ||
[![PyPI versions](https://img.shields.io/pypi/v/deepcov?logo=python&logoColor=white)](https://pypi.org/project/deepcov) [![Twitter](https://img.shields.io/static/v1?label=twitter&message=follow&color=blue&logo=twitter)](https://twitter.com/treebeardtech) | ||
|
||
**<div style="font-size:21px">🚧 under construction, do not attempt to use 🚧</div>** | ||
|
||
The goal of this project is to make it easier to identify the root cause of pytest failures. | ||
|
||
Deepcov lets you view coverage data for each individual test case in VSCode to identify which (if any) changes in your code caused failures. | ||
<p align="center"> | ||
<img width="150" src="docs/icon.png" style="border: 1px solid rgba(0,0,0,0.3)" /> | ||
</p> | ||
<p align="center">See test results for every line of Python code | ||
|
||
## The Problem | ||
</p> | ||
<p align="center"> | ||
<a href="https://pypi.org/project/pytest-deepcov"><img src="https://img.shields.io/pypi/pyversions/pytest-deepcov?logo=python&logoColor=white" /></a> | ||
<a href="https://pypi.org/project/pytest-deepcov"><img src="https://img.shields.io/pypi/v/pytest-deepcov?logo=python&logoColor=white" /></a> | ||
<a href="https://twitter.com/treebeardtech"><img src="https://img.shields.io/static/v1?label=twitter&message=follow&color=blue&logo=twitter" /></a> | ||
</p> | ||
|
||
You are working on a bug fix. Main branch is clean according to CI, so you create a branch then put in a few source changes. All config and dependencies remain unchanged. | ||
**Deepcov is a pytest plugin + VSCode extension which combines test status and code coverage data.** | ||
|
||
Let's run some tests before opening a PR: | ||
|
||
```log | ||
FAILED workflow_handler/tests/test_model_r13n.py::TestR13n::test_when_data_not_fetched_then_no_regional_update | ||
FAILED workflow_handler/tests/test_model_r13n.py::TestR13n::test_connect | ||
FAILED workflow_handler/tests/test_model_r13n.py::TestR13n::test_when_data_fetched_then_update | ||
====== 3 failed, 510 passed, 2 xfailed, 51 warnings in 140.83s (0:02:20) ======= | ||
``` | ||
<p align="center"> | ||
<img width="550" src="docs/screen.png" style="border: 1px solid rgba(0,0,0,0.3)" /> | ||
</p> | ||
|
||
These tests look unfamiliar. They may be new, and I don't think they are related to my change. The error logs are hard to decipher. | ||
## Making Sense of Test Runs | ||
|
||
What could be wrong? | ||
Tests can often fail due to unreliable infrastructure, such as network dependencies. When this happens, it can be difficult figuring out if we should let it distract us from what we're working on. | ||
|
||
1. False positive: The tests are not configured for my dev environment | ||
2. False positive: The tests are flaky, due to a network dependency/race condition | ||
3. True positive: My code has somehow modified these testcases | ||
4. Some combination of the above | ||
What if we just wanted to pay attention to tests running through components we have changed? | ||
|
||
There are various courses of action I can take to make sense of this. Re-running the suite, debugging individual tests or opening a PR to run CI can help, but are time consuming. | ||
**Pytest** can tell us if tests pass, but can't tell us if we changed their behaviour, whereas **coverage** data can tell us if tests are running through a component, but not if they are passing. | ||
|
||
Deepcov proposes a way of identifying if your code change has impacted a test without re-running failures. | ||
|
||
## The Solution | ||
| | pytest | pytest-cov | pytest-deepcov | | ||
|-----------------------------|--------|------------|----------------| | ||
| indicates code health | <span style="color: #00CE1C">✔</span> | <span style="color: #DF0E25">✖</span> | <span style="color: #00CE1C">✔</span> | | ||
| data for every line of code | <span style="color: #DF0E25">✖</span> | <span style="color: #00CE1C">✔</span> | <span style="color: #00CE1C">✔</span> | | ||
|
||
Deepcov shows lines of code that were run by failing tests, so you can connect test failures with source changes. | ||
## Tutorial | ||
|
||
### Pre-req: Capture test coverage and results when you run pytest | ||
We are going to debug a toy test suite using deepcov. | ||
|
||
```zsh | ||
pip install -U pytest pytest-cov | ||
<p align="center"> | ||
<img width="550" src="docs/demo.gif" style="border: 1px solid rgba(0,0,0,0.3)" /> | ||
</p> | ||
|
||
pytest \ | ||
--cov=src \ # Collect coverage data for your repo | ||
--cov-context=test \ # Ensure coverage data is segmented per-test | ||
--junit-xml=results.xml # Output test results | ||
Before starting, ensure you have python and VSCode installed. | ||
### Run tests with deepcov attached | ||
1. Fork and clone this repo | ||
1. `code pytest-deepcov/python-cli/tests/resources` | ||
1. Open `src/lib.py` and `src/test_lib.py` | ||
1. Create yourself a new terminal window in VSCode | ||
1. (optional) `virtualenv .venv; . .venv/bin/activate` | ||
1. `pip install pytest-deepcov` | ||
1. `pytest --cov=src` | ||
1. the tests should fail, and a new directory `.deepcov` should be created | ||
|
||
### Visualise deepcov data | ||
1. Install the [VSCode extension](https://marketplace.visualstudio.com/items?itemName=treebeardtech.deepcov). It will add a 'deepcov' button to the top right of your editor. Don't click it yet :) | ||
1. Configure your CLI location: Open VSCode settings, then search for `deepcov`. Follow the instruction to connect with the python package. | ||
1. Enable deepcov using the 'deepcov' button to view your pytest test results from above. | ||
1. `src/lib.py` and `src/test_lib.py` should have annotations on every line with test results. | ||
1. Disable deepcov using the same button | ||
|
||
### Troubleshooting | ||
|
||
1. If it complains that it can't find the CLI, you will need to (a) ensure the CLI is correct, (b) close and reopen VSCode to refresh the config | ||
1. Are you on Windows? If so, please try windows subsystem for linux. | ||
1. Please log an issue on this repo and I will help | ||
1. If you are feeling brave, try using the CLI to debug (see below) | ||
## Deepcov Internals | ||
|
||
The VSCode extension fetches data for each line of code from the deepcov python package. | ||
|
||
`deepcov /Users/a/git/treebeardtech/deepcov/python-cli/tests/resources/src/lib.py` | ||
```json | ||
{ | ||
"lines": { | ||
"3": { | ||
"passed": [], | ||
"failed": [] | ||
}, | ||
"1": { | ||
"passed": [ | ||
"ran on startup" | ||
], | ||
"failed": [] | ||
}, | ||
... | ||
"5": { | ||
"passed": [ | ||
"src.test_lib.TestLib.test_divide2[3.0]", | ||
"src.test_lib.test_divide", | ||
"src.test_lib.test_divide2[3.0]" | ||
], | ||
"failed": [ | ||
"src.test_lib.TestLib.test_divide2[0]", | ||
"src.test_lib.test_divide2[0]" | ||
] | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### View the code ran by failing tests | ||
|
||
When coverage and test report data is captured, you can view test statuses for each line of code. | ||
(Note: this cli must be run inside the `.deepcov` output directory) | ||
|
||
<p align="center"> | ||
<img width="750" src="docs/editor.png" /> | ||
</p> | ||
You can use this approach to create plugins for other text editors. | ||
|
||
## See also | ||
## Limitations | ||
* Project structure: Your pytest root directory must be the same as your vscode root directory. | ||
* `coveragepy` is used to capture coverage data using the Python trace hook. This means: | ||
1. You cannot use the debugger and deepcov at the same time. Deepcov detects when the debugger is active and disables itself. | ||
1. Everything takes 30% longer. It is best to only use deepcov to rerun subsets of a failing test suite. | ||
## Diving Deeper | ||
|
||
- https://arxiv.org/abs/1607.04347 | ||
- https://github.com/saeg/jaguar | ||
- https://arxiv.org/pdf/1607.04347.pdf | ||
Having test results for every line of code opens up the possibility of implementing *spectrum-based fault localisation* | ||
- https://arxiv.org/abs/1607.04347 contains a description of this technique and expected results | ||
- https://github.com/saeg/jaguar implements the described heuristics in java |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters