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.
Files changed (36) hide show
  1. flakeguard-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
  2. flakeguard-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  3. flakeguard-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
  4. flakeguard-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +14 -0
  5. flakeguard-0.1.0/.github/workflows/ci.yml +24 -0
  6. flakeguard-0.1.0/.github/workflows/example.yml +40 -0
  7. flakeguard-0.1.0/.github/workflows/release.yml +47 -0
  8. flakeguard-0.1.0/.gitignore +23 -0
  9. flakeguard-0.1.0/CHANGELOG.md +34 -0
  10. flakeguard-0.1.0/CODE_OF_CONDUCT.md +58 -0
  11. flakeguard-0.1.0/CONTRIBUTING.md +80 -0
  12. flakeguard-0.1.0/LICENSE +21 -0
  13. flakeguard-0.1.0/PKG-INFO +141 -0
  14. flakeguard-0.1.0/README.md +122 -0
  15. flakeguard-0.1.0/action.yml +91 -0
  16. flakeguard-0.1.0/docs/demo.gif +0 -0
  17. flakeguard-0.1.0/examples/reports/run1.xml +10 -0
  18. flakeguard-0.1.0/examples/reports/run2.xml +12 -0
  19. flakeguard-0.1.0/examples/reports/run3.xml +10 -0
  20. flakeguard-0.1.0/pyproject.toml +32 -0
  21. flakeguard-0.1.0/src/flakeguard/__init__.py +21 -0
  22. flakeguard-0.1.0/src/flakeguard/__main__.py +6 -0
  23. flakeguard-0.1.0/src/flakeguard/cli.py +149 -0
  24. flakeguard-0.1.0/src/flakeguard/models.py +60 -0
  25. flakeguard-0.1.0/src/flakeguard/parsers/__init__.py +21 -0
  26. flakeguard-0.1.0/src/flakeguard/parsers/junit_xml.py +98 -0
  27. flakeguard-0.1.0/src/flakeguard/report.py +108 -0
  28. flakeguard-0.1.0/src/flakeguard/scoring.py +122 -0
  29. flakeguard-0.1.0/tests/conftest.py +8 -0
  30. flakeguard-0.1.0/tests/fixtures/jest-report.xml +34 -0
  31. flakeguard-0.1.0/tests/fixtures/pytest-report.xml +5 -0
  32. flakeguard-0.1.0/tests/test_cli.py +48 -0
  33. flakeguard-0.1.0/tests/test_gating.py +26 -0
  34. flakeguard-0.1.0/tests/test_junit_xml.py +44 -0
  35. flakeguard-0.1.0/tests/test_real_reports.py +58 -0
  36. 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,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Question or idea
4
+ url: https://github.com/PrathameshKulkarni2k4/flakeguard/discussions
5
+ about: Ask questions and discuss ideas with the community.
@@ -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.
@@ -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
+ ![flakeguard demo](docs/demo.gif)
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
+ [![CI](https://github.com/PrathameshKulkarni2k4/flakeguard/actions/workflows/ci.yml/badge.svg)](https://github.com/PrathameshKulkarni2k4/flakeguard/actions/workflows/ci.yml)
33
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
34
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](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
+ ![flakeguard demo](docs/demo.gif)
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
+ [![CI](https://github.com/PrathameshKulkarni2k4/flakeguard/actions/workflows/ci.yml/badge.svg)](https://github.com/PrathameshKulkarni2k4/flakeguard/actions/workflows/ci.yml)
14
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
15
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](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).