flakeguard 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flakeguard-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
- flakeguard-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- flakeguard-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
- flakeguard-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +14 -0
- flakeguard-0.1.0/.github/workflows/ci.yml +24 -0
- flakeguard-0.1.0/.github/workflows/example.yml +40 -0
- flakeguard-0.1.0/.github/workflows/release.yml +47 -0
- flakeguard-0.1.0/.gitignore +23 -0
- flakeguard-0.1.0/CHANGELOG.md +34 -0
- flakeguard-0.1.0/CODE_OF_CONDUCT.md +58 -0
- flakeguard-0.1.0/CONTRIBUTING.md +80 -0
- flakeguard-0.1.0/LICENSE +21 -0
- flakeguard-0.1.0/PKG-INFO +141 -0
- flakeguard-0.1.0/README.md +122 -0
- flakeguard-0.1.0/action.yml +91 -0
- flakeguard-0.1.0/docs/demo.gif +0 -0
- flakeguard-0.1.0/examples/reports/run1.xml +10 -0
- flakeguard-0.1.0/examples/reports/run2.xml +12 -0
- flakeguard-0.1.0/examples/reports/run3.xml +10 -0
- flakeguard-0.1.0/pyproject.toml +32 -0
- flakeguard-0.1.0/src/flakeguard/__init__.py +21 -0
- flakeguard-0.1.0/src/flakeguard/__main__.py +6 -0
- flakeguard-0.1.0/src/flakeguard/cli.py +149 -0
- flakeguard-0.1.0/src/flakeguard/models.py +60 -0
- flakeguard-0.1.0/src/flakeguard/parsers/__init__.py +21 -0
- flakeguard-0.1.0/src/flakeguard/parsers/junit_xml.py +98 -0
- flakeguard-0.1.0/src/flakeguard/report.py +108 -0
- flakeguard-0.1.0/src/flakeguard/scoring.py +122 -0
- flakeguard-0.1.0/tests/conftest.py +8 -0
- flakeguard-0.1.0/tests/fixtures/jest-report.xml +34 -0
- flakeguard-0.1.0/tests/fixtures/pytest-report.xml +5 -0
- flakeguard-0.1.0/tests/test_cli.py +48 -0
- flakeguard-0.1.0/tests/test_gating.py +26 -0
- flakeguard-0.1.0/tests/test_junit_xml.py +44 -0
- flakeguard-0.1.0/tests/test_real_reports.py +58 -0
- flakeguard-0.1.0/tests/test_scoring.py +80 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Something isn't working as expected
|
|
4
|
+
title: ""
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
**What did you run?**
|
|
10
|
+
The exact command, please.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
flakeguard scan ...
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**What happened?**
|
|
17
|
+
|
|
18
|
+
**What did you expect to happen?**
|
|
19
|
+
|
|
20
|
+
**A snippet of the report file**
|
|
21
|
+
If you can share a (redacted) piece of the report that caused it, that helps
|
|
22
|
+
enormously.
|
|
23
|
+
|
|
24
|
+
**Environment**
|
|
25
|
+
|
|
26
|
+
- flakeguard version (`flakeguard --version`):
|
|
27
|
+
- Python version:
|
|
28
|
+
- OS:
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest an idea for flakeguard
|
|
4
|
+
title: ""
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
**What problem are you trying to solve?**
|
|
10
|
+
Describe the pain, not just the feature. It helps us find the best fix.
|
|
11
|
+
|
|
12
|
+
**What would you like to happen?**
|
|
13
|
+
|
|
14
|
+
**Anything else?**
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## What does this change?
|
|
2
|
+
|
|
3
|
+
<!-- A short description of what and why. -->
|
|
4
|
+
|
|
5
|
+
## Related issue
|
|
6
|
+
|
|
7
|
+
<!-- e.g. Closes #12 -->
|
|
8
|
+
|
|
9
|
+
## Checklist
|
|
10
|
+
|
|
11
|
+
- [ ] I added or updated tests for this change.
|
|
12
|
+
- [ ] `pytest -q` passes locally.
|
|
13
|
+
- [ ] I updated the docs / CHANGELOG if behaviour changed.
|
|
14
|
+
- [ ] The change keeps the flakiness score explainable (no black box).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.9", "3.11", "3.12"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
- name: Install
|
|
20
|
+
run: pip install -e ".[dev]"
|
|
21
|
+
- name: Test
|
|
22
|
+
run: pytest -q
|
|
23
|
+
- name: Self-check (dogfood)
|
|
24
|
+
run: flakeguard scan examples/reports
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Example: run Flakeguard on every pull request.
|
|
2
|
+
#
|
|
3
|
+
# Copy this into your own repository as .github/workflows/flakeguard.yml,
|
|
4
|
+
# then adjust the "Generate reports" step to run *your* test suite a few
|
|
5
|
+
# times and collect JUnit XML into a directory.
|
|
6
|
+
|
|
7
|
+
name: Flaky test check
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
pull_request:
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
flakeguard:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
pull-requests: write # needed to post the report as a PR comment
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
# 1. Produce test reports. Replace this with your real test command.
|
|
22
|
+
# Running the suite several times is what makes flakiness visible.
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
- name: Generate reports
|
|
27
|
+
run: |
|
|
28
|
+
pip install pytest
|
|
29
|
+
mkdir -p reports
|
|
30
|
+
for i in 1 2 3 4 5; do
|
|
31
|
+
pytest --junitxml="reports/run-$i.xml" || true
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
# 2. Analyse them and comment on the PR.
|
|
35
|
+
- name: Flakeguard
|
|
36
|
+
uses: ./
|
|
37
|
+
with:
|
|
38
|
+
reports: reports
|
|
39
|
+
min-runs: 3
|
|
40
|
+
max-flaky: 0 # fail the check if any flaky test is found
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Publish to PyPI when a version tag is pushed.
|
|
2
|
+
#
|
|
3
|
+
# Setup (one time, done by the maintainer):
|
|
4
|
+
# 1. Create the project on PyPI.
|
|
5
|
+
# 2. Add a "Trusted Publisher" on PyPI pointing at this repository and the
|
|
6
|
+
# workflow file name "release.yml" (PyPI > project > Publishing).
|
|
7
|
+
# 3. Push a tag: git tag v0.1.0 && git push origin v0.1.0
|
|
8
|
+
#
|
|
9
|
+
# No API token is stored anywhere - PyPI trusts this workflow directly (OIDC).
|
|
10
|
+
|
|
11
|
+
name: Release
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
tags:
|
|
16
|
+
- "v*"
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
- uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
- name: Build
|
|
27
|
+
run: |
|
|
28
|
+
python -m pip install --upgrade build
|
|
29
|
+
python -m build
|
|
30
|
+
- uses: actions/upload-artifact@v4
|
|
31
|
+
with:
|
|
32
|
+
name: dist
|
|
33
|
+
path: dist/
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
needs: build
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
environment: pypi
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write # required for trusted publishing
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/download-artifact@v4
|
|
43
|
+
with:
|
|
44
|
+
name: dist
|
|
45
|
+
path: dist/
|
|
46
|
+
- name: Publish to PyPI
|
|
47
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Byte-compiled / cache
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
|
|
9
|
+
# Virtual envs
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
|
|
13
|
+
# Test / tooling caches
|
|
14
|
+
.pytest_cache/
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.coverage
|
|
18
|
+
htmlcov/
|
|
19
|
+
|
|
20
|
+
# Editors / OS
|
|
21
|
+
.idea/
|
|
22
|
+
.vscode/
|
|
23
|
+
.DS_Store
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. The format is based
|
|
4
|
+
on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
|
|
5
|
+
aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Test identity when a framework repeats the name in both `classname` and
|
|
12
|
+
`name` (e.g. jest-junit), which could otherwise merge distinct tests.
|
|
13
|
+
- Clearer CLI errors when report files are missing or not valid JUnit XML.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Hardened the parser against real reports from pytest and jest-junit, with
|
|
18
|
+
regression fixtures captured from those tools.
|
|
19
|
+
|
|
20
|
+
## [0.1.0] - 2026-10-18
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- JUnit XML parser, so one tool serves every language.
|
|
25
|
+
- Explainable flakiness scoring:
|
|
26
|
+
`2 * min(passes, failures) / (passes + failures)`.
|
|
27
|
+
- CLI: `flakeguard scan` with `text`, `json`, and `markdown` output.
|
|
28
|
+
- `--min-runs`, `--min-score`, `--output`, and `--fail-on-flaky` options.
|
|
29
|
+
- GitHub Action: analyses reports, comments on pull requests, and enforces a
|
|
30
|
+
flakiness budget.
|
|
31
|
+
- Test suite, MIT license, and CI workflow.
|
|
32
|
+
|
|
33
|
+
[Unreleased]: https://github.com/PrathameshKulkarni2k4/flakeguard/compare/v0.1.0...HEAD
|
|
34
|
+
[0.1.0]: https://github.com/PrathameshKulkarni2k4/flakeguard/releases/tag/v0.1.0
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics,
|
|
8
|
+
gender identity and expression, level of experience, education,
|
|
9
|
+
socio-economic status, nationality, personal appearance, race, religion, or
|
|
10
|
+
sexual identity and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our standards
|
|
16
|
+
|
|
17
|
+
Examples of behaviour that contributes to a positive environment:
|
|
18
|
+
|
|
19
|
+
- Demonstrating empathy and kindness toward other people.
|
|
20
|
+
- Being respectful of differing opinions, viewpoints, and experiences.
|
|
21
|
+
- Giving and gracefully accepting constructive feedback.
|
|
22
|
+
- Accepting responsibility and apologising to those affected by our mistakes,
|
|
23
|
+
and learning from the experience.
|
|
24
|
+
- Focusing on what is best for the community.
|
|
25
|
+
|
|
26
|
+
Examples of unacceptable behaviour:
|
|
27
|
+
|
|
28
|
+
- The use of sexualised language or imagery, and sexual attention or advances
|
|
29
|
+
of any kind.
|
|
30
|
+
- Trolling, insulting or derogatory comments, and personal or political
|
|
31
|
+
attacks.
|
|
32
|
+
- Public or private harassment.
|
|
33
|
+
- Publishing others' private information without their explicit permission.
|
|
34
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
|
35
|
+
professional setting.
|
|
36
|
+
|
|
37
|
+
## Enforcement responsibilities
|
|
38
|
+
|
|
39
|
+
Project maintainers are responsible for clarifying and enforcing these
|
|
40
|
+
standards and will take appropriate and fair corrective action in response to
|
|
41
|
+
any behaviour they deem inappropriate, threatening, offensive, or harmful.
|
|
42
|
+
|
|
43
|
+
## Scope
|
|
44
|
+
|
|
45
|
+
This Code of Conduct applies within all community spaces, and also applies
|
|
46
|
+
when an individual is officially representing the community in public spaces.
|
|
47
|
+
|
|
48
|
+
## Enforcement
|
|
49
|
+
|
|
50
|
+
Instances of abusive, harassing, or otherwise unacceptable behaviour may be
|
|
51
|
+
reported to the maintainer at prathameshkulkarni22092004@gmail.com. All
|
|
52
|
+
complaints will be reviewed and investigated promptly and fairly.
|
|
53
|
+
|
|
54
|
+
## Attribution
|
|
55
|
+
|
|
56
|
+
This Code of Conduct is adapted from the [Contributor
|
|
57
|
+
Covenant](https://www.contributor-covenant.org), version 2.1, available at
|
|
58
|
+
https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Contributing to flakeguard
|
|
2
|
+
|
|
3
|
+
Thanks for wanting to help — genuinely. This project exists for the
|
|
4
|
+
developer community, and it only gets better with more hands on it.
|
|
5
|
+
|
|
6
|
+
## The quickest way to help
|
|
7
|
+
|
|
8
|
+
If you are new to open source, the best first contribution is **adding
|
|
9
|
+
support for a new test-report format**. The parsers are deliberately small
|
|
10
|
+
and self-contained, and there is a clear pattern to follow (see below).
|
|
11
|
+
|
|
12
|
+
Look for issues labelled **`good first issue`**.
|
|
13
|
+
|
|
14
|
+
## Setting up a development environment
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
git clone https://github.com/PrathameshKulkarni2k4/flakeguard
|
|
18
|
+
cd flakeguard
|
|
19
|
+
python -m venv .venv
|
|
20
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
21
|
+
pip install -e ".[dev]"
|
|
22
|
+
pytest -q
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
You should see all tests pass. If they don't, that's a bug — please open an
|
|
26
|
+
issue.
|
|
27
|
+
|
|
28
|
+
## Running the tool on the examples
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
flakeguard scan examples/reports
|
|
32
|
+
flakeguard scan examples/reports --format json
|
|
33
|
+
flakeguard scan examples/reports --fail-on-flaky
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Adding a new report format
|
|
37
|
+
|
|
38
|
+
1. Create `src/flakeguard/parsers/<format>.py` with a function that takes a
|
|
39
|
+
file path and returns a list of `flakeguard.models.TestCase`.
|
|
40
|
+
2. Register it in `src/flakeguard/parsers/__init__.py` under `by_suffix`.
|
|
41
|
+
3. Add a fixture file under `examples/reports/` and a test under `tests/`.
|
|
42
|
+
|
|
43
|
+
That's the whole job. A good parser is small and boring, which is exactly
|
|
44
|
+
what we want.
|
|
45
|
+
|
|
46
|
+
## Guidelines
|
|
47
|
+
|
|
48
|
+
- **Keep the score explainable.** Never replace the flakiness formula with a
|
|
49
|
+
black box. Trust is the product.
|
|
50
|
+
- **Never be confidently wrong.** If a parser is unsure, it should error
|
|
51
|
+
clearly rather than guess.
|
|
52
|
+
- **Small pull requests.** One change per PR is easier to review and merge.
|
|
53
|
+
- **Add a test** for anything you change. Tests are how we keep the promise
|
|
54
|
+
that the tool is trustworthy.
|
|
55
|
+
- **Match the existing style.** No configs to fight — just read the file you
|
|
56
|
+
are editing.
|
|
57
|
+
|
|
58
|
+
## Commit messages
|
|
59
|
+
|
|
60
|
+
A short imperative summary is enough:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
Add TAP report parser
|
|
64
|
+
Fix crash on reports with no <testsuite>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Reporting bugs
|
|
68
|
+
|
|
69
|
+
Please include:
|
|
70
|
+
|
|
71
|
+
- what you ran (the exact command),
|
|
72
|
+
- what happened,
|
|
73
|
+
- what you expected,
|
|
74
|
+
- a snippet of the report file if you can share it (redact anything
|
|
75
|
+
sensitive).
|
|
76
|
+
|
|
77
|
+
## Code of Conduct
|
|
78
|
+
|
|
79
|
+
By taking part, you agree to follow our
|
|
80
|
+
[Code of Conduct](CODE_OF_CONDUCT.md). Be kind — we were all beginners once.
|
flakeguard-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Prathamesh Kulkarni
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: flakeguard
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Find, rank, and quarantine flaky tests from any language's test reports.
|
|
5
|
+
Project-URL: Homepage, https://github.com/PrathameshKulkarni2k4/flakeguard
|
|
6
|
+
Author: Prathamesh Kulkarni
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: ci,developer-tools,flaky-tests,junit,test-reports,testing
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Software Development :: Testing
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
Requires-Dist: pytest>=7; extra == 'dev'
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# flakeguard
|
|
21
|
+
|
|
22
|
+
### Your test suite is lying to you.
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
Flakeguard finds the tests that **randomly pass and fail**, ranks them by how
|
|
27
|
+
unreliable they are, and shows you why — so you can trust your tests again.
|
|
28
|
+
|
|
29
|
+
**Free · private · works with any language.** No account, no sign-up, and
|
|
30
|
+
nothing leaves your machine.
|
|
31
|
+
|
|
32
|
+
[](https://github.com/PrathameshKulkarni2k4/flakeguard/actions/workflows/ci.yml)
|
|
33
|
+
[](LICENSE)
|
|
34
|
+
[](https://www.python.org/)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## The problem, in 30 seconds
|
|
39
|
+
|
|
40
|
+
You have a test that fails once in a while. You re-run it. It passes. Was
|
|
41
|
+
that a real bug? A flaky test? Nobody knows — so everyone ignores it, and
|
|
42
|
+
that is exactly how real bugs hide.
|
|
43
|
+
|
|
44
|
+
A flaky test costs a team hours, and slowly destroys trust in the entire
|
|
45
|
+
test suite. Flakeguard fixes the hard half of the problem: it tells you
|
|
46
|
+
**exactly which tests are unreliable**, and how unreliable.
|
|
47
|
+
|
|
48
|
+
## Try it in 60 seconds
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pipx install flakeguard
|
|
52
|
+
flakeguard scan ./reports # a folder of test reports
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
No reports yet? Run it against the examples bundled in this repo:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git clone https://github.com/PrathameshKulkarni2k4/flakeguard
|
|
59
|
+
cd flakeguard
|
|
60
|
+
flakeguard scan examples/reports
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## What it does
|
|
64
|
+
|
|
65
|
+
- Reads your test results from **many runs** (the more runs, the sharper the
|
|
66
|
+
picture).
|
|
67
|
+
- Finds the tests that **disagree with themselves** across those runs.
|
|
68
|
+
- Gives each one a score from **0 (solid) to 1 (a coin-flip)**.
|
|
69
|
+
- Shows the **latest failure message**, so you can go fix it.
|
|
70
|
+
- Runs in your **CI** and can leave a comment on the pull request — or block
|
|
71
|
+
it when flakiness spikes.
|
|
72
|
+
|
|
73
|
+
## Works with any language
|
|
74
|
+
|
|
75
|
+
Flakeguard reads **JUnit XML**, the report format almost every test
|
|
76
|
+
framework can produce. One tool, every language:
|
|
77
|
+
|
|
78
|
+
| Language / framework | How to produce the report |
|
|
79
|
+
|---|---|
|
|
80
|
+
| Python (pytest) | `pytest --junitxml=report.xml` |
|
|
81
|
+
| Java (Maven / Gradle) | Surefire writes JUnit XML automatically |
|
|
82
|
+
| Go | `gotestsum --junitfile report.xml` |
|
|
83
|
+
| JavaScript (Jest) | the `jest-junit` reporter |
|
|
84
|
+
| Ruby (RSpec) | the `rspec_junit_formatter` gem |
|
|
85
|
+
| .NET, PHPUnit, … | built-in or plugin JUnit output |
|
|
86
|
+
|
|
87
|
+
## Use in CI (GitHub Actions)
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
- name: Flakeguard
|
|
91
|
+
uses: PrathameshKulkarni2k4/flakeguard@main
|
|
92
|
+
with:
|
|
93
|
+
reports: reports # dir/glob of JUnit XML files
|
|
94
|
+
min-runs: 3 # ignore tests seen in fewer runs
|
|
95
|
+
max-flaky: 0 # fail if any flaky test is found (-1 = never fail)
|
|
96
|
+
comment: "true" # post the report as a PR comment
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
See [`.github/workflows/example.yml`](.github/workflows/example.yml) for a
|
|
100
|
+
complete workflow that runs a suite several times and feeds the reports in.
|
|
101
|
+
|
|
102
|
+
To gate locally or in any other CI, use the exit code:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
flakeguard scan ./reports --fail-on-flaky # exits 1 if anything is flaky
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## How the score works
|
|
109
|
+
|
|
110
|
+
For each test we count passes vs. non-passes across all runs (skips are
|
|
111
|
+
ignored). The flakiness score is:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
score = 2 * min(passes, failures) / (passes + failures)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- always passes, or always fails → **0.0** (consistent, *not* flaky)
|
|
118
|
+
- flips on every run (50/50) → **1.0** (maximally flaky)
|
|
119
|
+
|
|
120
|
+
It is deliberately explainable — no black box. You can read the number and
|
|
121
|
+
know exactly how it was derived.
|
|
122
|
+
|
|
123
|
+
## Roadmap
|
|
124
|
+
|
|
125
|
+
- [x] JUnit XML parsing, flakiness scoring, text/JSON/Markdown reports
|
|
126
|
+
- [x] GitHub Action with PR comments and a flakiness budget
|
|
127
|
+
- [ ] TAP and native JSON report formats
|
|
128
|
+
- [ ] CI history so it learns across builds
|
|
129
|
+
- [ ] Failure-signature clustering (group the *same* flake across tests)
|
|
130
|
+
- [ ] Quarantine file so known flakes are set aside, not deleted
|
|
131
|
+
|
|
132
|
+
## Contributing
|
|
133
|
+
|
|
134
|
+
Contributions are very welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
135
|
+
Adding support for a new report format is a great first contribution and is
|
|
136
|
+
designed to be small. Please be kind; this project follows a
|
|
137
|
+
[Code of Conduct](CODE_OF_CONDUCT.md).
|
|
138
|
+
|
|
139
|
+
## License
|
|
140
|
+
|
|
141
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# flakeguard
|
|
2
|
+
|
|
3
|
+
### Your test suite is lying to you.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
Flakeguard finds the tests that **randomly pass and fail**, ranks them by how
|
|
8
|
+
unreliable they are, and shows you why — so you can trust your tests again.
|
|
9
|
+
|
|
10
|
+
**Free · private · works with any language.** No account, no sign-up, and
|
|
11
|
+
nothing leaves your machine.
|
|
12
|
+
|
|
13
|
+
[](https://github.com/PrathameshKulkarni2k4/flakeguard/actions/workflows/ci.yml)
|
|
14
|
+
[](LICENSE)
|
|
15
|
+
[](https://www.python.org/)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## The problem, in 30 seconds
|
|
20
|
+
|
|
21
|
+
You have a test that fails once in a while. You re-run it. It passes. Was
|
|
22
|
+
that a real bug? A flaky test? Nobody knows — so everyone ignores it, and
|
|
23
|
+
that is exactly how real bugs hide.
|
|
24
|
+
|
|
25
|
+
A flaky test costs a team hours, and slowly destroys trust in the entire
|
|
26
|
+
test suite. Flakeguard fixes the hard half of the problem: it tells you
|
|
27
|
+
**exactly which tests are unreliable**, and how unreliable.
|
|
28
|
+
|
|
29
|
+
## Try it in 60 seconds
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pipx install flakeguard
|
|
33
|
+
flakeguard scan ./reports # a folder of test reports
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
No reports yet? Run it against the examples bundled in this repo:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/PrathameshKulkarni2k4/flakeguard
|
|
40
|
+
cd flakeguard
|
|
41
|
+
flakeguard scan examples/reports
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## What it does
|
|
45
|
+
|
|
46
|
+
- Reads your test results from **many runs** (the more runs, the sharper the
|
|
47
|
+
picture).
|
|
48
|
+
- Finds the tests that **disagree with themselves** across those runs.
|
|
49
|
+
- Gives each one a score from **0 (solid) to 1 (a coin-flip)**.
|
|
50
|
+
- Shows the **latest failure message**, so you can go fix it.
|
|
51
|
+
- Runs in your **CI** and can leave a comment on the pull request — or block
|
|
52
|
+
it when flakiness spikes.
|
|
53
|
+
|
|
54
|
+
## Works with any language
|
|
55
|
+
|
|
56
|
+
Flakeguard reads **JUnit XML**, the report format almost every test
|
|
57
|
+
framework can produce. One tool, every language:
|
|
58
|
+
|
|
59
|
+
| Language / framework | How to produce the report |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Python (pytest) | `pytest --junitxml=report.xml` |
|
|
62
|
+
| Java (Maven / Gradle) | Surefire writes JUnit XML automatically |
|
|
63
|
+
| Go | `gotestsum --junitfile report.xml` |
|
|
64
|
+
| JavaScript (Jest) | the `jest-junit` reporter |
|
|
65
|
+
| Ruby (RSpec) | the `rspec_junit_formatter` gem |
|
|
66
|
+
| .NET, PHPUnit, … | built-in or plugin JUnit output |
|
|
67
|
+
|
|
68
|
+
## Use in CI (GitHub Actions)
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
- name: Flakeguard
|
|
72
|
+
uses: PrathameshKulkarni2k4/flakeguard@main
|
|
73
|
+
with:
|
|
74
|
+
reports: reports # dir/glob of JUnit XML files
|
|
75
|
+
min-runs: 3 # ignore tests seen in fewer runs
|
|
76
|
+
max-flaky: 0 # fail if any flaky test is found (-1 = never fail)
|
|
77
|
+
comment: "true" # post the report as a PR comment
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
See [`.github/workflows/example.yml`](.github/workflows/example.yml) for a
|
|
81
|
+
complete workflow that runs a suite several times and feeds the reports in.
|
|
82
|
+
|
|
83
|
+
To gate locally or in any other CI, use the exit code:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
flakeguard scan ./reports --fail-on-flaky # exits 1 if anything is flaky
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## How the score works
|
|
90
|
+
|
|
91
|
+
For each test we count passes vs. non-passes across all runs (skips are
|
|
92
|
+
ignored). The flakiness score is:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
score = 2 * min(passes, failures) / (passes + failures)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- always passes, or always fails → **0.0** (consistent, *not* flaky)
|
|
99
|
+
- flips on every run (50/50) → **1.0** (maximally flaky)
|
|
100
|
+
|
|
101
|
+
It is deliberately explainable — no black box. You can read the number and
|
|
102
|
+
know exactly how it was derived.
|
|
103
|
+
|
|
104
|
+
## Roadmap
|
|
105
|
+
|
|
106
|
+
- [x] JUnit XML parsing, flakiness scoring, text/JSON/Markdown reports
|
|
107
|
+
- [x] GitHub Action with PR comments and a flakiness budget
|
|
108
|
+
- [ ] TAP and native JSON report formats
|
|
109
|
+
- [ ] CI history so it learns across builds
|
|
110
|
+
- [ ] Failure-signature clustering (group the *same* flake across tests)
|
|
111
|
+
- [ ] Quarantine file so known flakes are set aside, not deleted
|
|
112
|
+
|
|
113
|
+
## Contributing
|
|
114
|
+
|
|
115
|
+
Contributions are very welcome — see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
116
|
+
Adding support for a new report format is a great first contribution and is
|
|
117
|
+
designed to be small. Please be kind; this project follows a
|
|
118
|
+
[Code of Conduct](CODE_OF_CONDUCT.md).
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
MIT — see [LICENSE](LICENSE).
|