Skip to content

Commit 5782cf0

Browse files
authored
HTML report, token cost reduction (#11)
* feat: source file mutation instead of per function block WIP * feat: modify per source file WIP * feat: add html report * refactor * refactor * update readme * update readme * update readme * apply formatter
1 parent 80ebda6 commit 5782cf0

28 files changed

+1310
-1393
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,4 +165,6 @@ vendor
165165
dist*
166166

167167
*.html
168-
*.log
168+
*.log
169+
logs/*
170+
*.db

README.md

Lines changed: 46 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -25,32 +25,36 @@ We'd love to hear your feedback, suggestions, and any thoughts you have on mutat
2525
- [Unit Test Generator: Enhancing Line and Mutation Coverage (WIP)](#unit-test-generator-enhancing-line-and-mutation-coverage-wip)
2626
- [Getting Started with Mutation Testing](#getting-started-with-mutation-testing)
2727
- [Examples](#examples)
28-
- [LLM Survivng Mutant Analysis Report](#mutant-report)
29-
- [Examples](#examples)
3028
- [CI/CD Integration](#cicd-integration)
3129

3230
Mutahunter can automatically generate unit tests to increase line and mutation coverage, leveraging Large Language Models (LLMs) to identify and fill gaps in test coverage. It uses LLM models to inject context-aware faults into your codebase. This AI-driven approach produces fewer equivalent mutants, mutants with higher fault detection potential, and those with higher coupling and semantic similarity to real faults, ensuring comprehensive and effective testing.
3331

3432
## Features
3533

36-
- **Automatic Test Generation:** Generates unit tests to increase line and mutation coverage, leveraging LLMs to identify and fill gaps in test coverage. See the [Unit Test Generator](#unit-test-generator-enhancing-line-and-mutation-coverage-wip) section for more details.
34+
- **Automatic Unit Test Generation:** Generates unit tests to increase line and mutation coverage, leveraging LLMs to identify and fill gaps in test coverage. See the [Unit Test Generator](#unit-test-generator-enhancing-line-and-mutation-coverage-wip) section for more details.
3735
- **Language Agnostic:** Compatible with languages that provide coverage reports in Cobertura XML, Jacoco XML, and lcov formats. Extensible to additional languages and testing frameworks.
3836
- **LLM Context-aware Mutations:** Utilizes LLM models to generate context-aware mutants. [Research](https://arxiv.org/abs/2406.09843) indicates that LLM-generated mutants have higher fault detection potential, fewer equivalent mutants, and higher coupling and semantic similarity to real faults. It uses a map of your entire git repository to generate contextually relevant mutants using [aider's repomap](https://aider.chat/docs/repomap.html). Supports self-hosted LLMs, Anthropic, OpenAI, and any LLM models via [LiteLLM](https://github.com/BerriAI/litellm).
39-
- **Change-Based Testing:** Runs mutation tests on modified files and lines based on the latest commit or pull request changes, ensuring that only relevant parts of the code are tested.
37+
- **Diff-Based Mutations:** Runs mutation tests on modified files and lines based on the latest commit or pull request changes, ensuring that only relevant parts of the code are tested.
4038
- **LLM Surviving Mutants Analysis:** Automatically analyzes survived mutants to identify potential weaknesses in the test suite, vulnerabilities, and areas for improvement.
41-
- **Extreme Mutation Testing:** Leverages language agnostic [TreeSitter](https://tree-sitter.github.io/) parser to apply extreme mutations to the codebase without using LLMs. [Research](https://arxiv.org/abs/2103.08480) shows that this approach is effective at detecting pseudo-tested methods with significantly lower computational cost. Currently supports Python, Java, JavaScript, and Go. Check the [scheme files](/src/mutahunter/core/queries/) to see the supported operators. We welcome contributions to add more operators and languages.
4239

43-
## Recommended Mutation Testing Process
40+
## Unit Test Generator: Enhancing Line and Mutation Coverage (WIP)
4441

45-
![Workflow](/images/diagram.svg)
42+
This tool generates unit tests to increase both line and mutation coverage, inspired by papers:
4643

47-
We recommend running Mutahunter per test file. This approach ensures that the mutation testing is focused on the test suite's effectiveness and efficiency. Here are some best practices to follow:
44+
- [Automated Unit Test Improvement using Large Language Models at Meta](https://arxiv.org/abs/2402.09171):
45+
- Uses LLMs to identify and fill gaps in test coverage.
46+
- [Effective Test Generation Using Pre-trained Large Language Models and Mutation Testing](https://arxiv.org/abs/2308.16557):
47+
- Generates tests that detect and kill code mutants, ensuring robustness.
4848

49-
1. **Achieve High Line Coverage:** Ensure your test suite has high line coverage, preferably 100%.
49+
```bash
50+
## go to examples/java_maven
51+
## remove some tests from BankAccountTest.java
5052

51-
2. **Strict Mutation Testing:** Use strict mutation testing during development to improve mutation coverage during development without additional cost. Utilize the `--only-mutate-file-paths` flag for targeted testing on critical files.
53+
mutahunter gen --test-command "mvn clean test" --code-coverage-report-path "target/site/jacoco/jacoco.xml" --test-file-path "src/test/java/BankAccountTest.java" --source-file-path "src/main/java/com/example/BankAccount.java" --coverage-type jacoco --model "gpt-4o"
5254

53-
3. **LLM-Based Mutation Testing on Changed Files:** Inject context-aware mutants using LLMs on changed files during pull requests as the final line of defense. Use the `--modified-files-only` flag to focus on recent changes. In this way it will make the mutation testing significantly **faster** and **cost effective.**
55+
Line coverage increased from 47.00% to 100.00%
56+
Mutation coverage increased from 92.86% to 92.86%
57+
```
5458

5559
## Getting Started with Mutation Testing
5660

@@ -66,28 +70,38 @@ $ export ANTHROPIC_API_KEY=your-key-goes-here
6670

6771
# Run Mutahunter on a specific file.
6872
# Coverage report should correspond to the test command.
69-
$ mutahunter run --test-command "pytest tests/unit" --code-coverage-report-path "coverage.xml" --only-mutate-file-paths "app_1.py" "app_2.py"
70-
71-
# Run mutation testing on modified files based on the latest commit
72-
$ mutahunter run --test-command "pytest tests/unit" --code-coverage-report-path "coverage.xml" --modified-files-only
73-
74-
. . . . .-. .-. . . . . . . .-. .-. .-.
75-
|\/| | | | |-| |-| | | |\| | |- |(
76-
' ` `-' ' ` ' ' ` `-' ' ` ' `-' ' '
77-
78-
2024-07-05 00:26:13,420 INFO: 📊 Line Coverage: 100% 📊
79-
2024-07-05 00:26:13,420 INFO: 🎯 Mutation Coverage: 61.54% 🎯
80-
2024-07-05 00:26:13,420 INFO: 🦠 Total Mutants: 13 🦠
81-
2024-07-05 00:26:13,420 INFO: 🛡️ Survived Mutants: 5 🛡️
82-
2024-07-05 00:26:13,420 INFO: 🗡️ Killed Mutants: 8 🗡️
83-
2024-07-05 00:26:13,421 INFO: 🕒 Timeout Mutants: 0 🕒
84-
2024-07-05 00:26:13,421 INFO: 🔥 Compile Error Mutants: 0 🔥
85-
2024-07-05 00:26:13,421 INFO: 💰 Total Cost: $0.00583 USD 💰
86-
2024-07-05 00:26:13,421 INFO: Report saved to logs/_latest/mutation_coverage.json
87-
2024-07-05 00:26:13,421 INFO: Report saved to logs/_latest/mutation_coverage_detail.json
88-
2024-07-05 00:26:13,421 INFO: Mutation Testing Ended. Took 43s
73+
$ mutahunter run --test-command "mvn test" --code-coverage-report-path "target/site/jacoco/jacoco.xml" --coverage-type jacoco --model "gpt-4o-mini"
74+
75+
. . . . .-. .-. . . . . . . .-. .-. .-.
76+
|\/| | | | |-| |-| | | |\| | |- |(
77+
' ` `-' ' ` ' ' ` `-' ' ` ' `-' ' '
78+
79+
2024-07-29 12:31:22,045 INFO:
80+
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
81+
82+
📊 Overall Mutation Coverage 📊
83+
📈 Line Coverage: 100.00% 📈
84+
🎯 Mutation Coverage: 63.33% 🎯
85+
🦠 Total Mutants: 30 🦠
86+
🛡️ Survived Mutants: 11 🛡️
87+
🗡️ Killed Mutants: 19 🗡️
88+
🕒 Timeout Mutants: 0 🕒
89+
🔥 Compile Error Mutants: 0 🔥
90+
💰 Total Cost: $0.00167 USD 💰
91+
92+
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
93+
94+
2024-07-29 12:31:22,050 INFO: HTML report generated: mutation_report.html
95+
2024-07-29 12:31:22,058 INFO: HTML report generated: 1.html
96+
2024-07-29 12:31:22,058 INFO: Mutation Testing Ended. Took 127s
8997
```
9098
99+
### HTML Mutation Report
100+
101+
![HTML Report](/images/mutation_overall.png)
102+
![HTML Report](/images/mutation_report.png)
103+
![HTML Report](/images/mutation_details.png)
104+
91105
### Examples
92106
93107
Go to the examples directory to see how to run Mutahunter on different programming languages:
@@ -101,37 +115,6 @@ Check [Java Example](/examples/java_maven/) to see some interesting LLM-based mu
101115
102116
Feel free to add more examples! ✨
103117
104-
## Unit Test Generator: Enhancing Line and Mutation Coverage (WIP)
105-
106-
This tool generates unit tests to increase both line and mutation coverage, inspired by papers:
107-
108-
- [Automated Unit Test Improvement using Large Language Models at Meta](https://arxiv.org/abs/2402.09171):
109-
- Uses LLMs to identify and fill gaps in test coverage.
110-
- [Effective Test Generation Using Pre-trained Large Language Models and Mutation Testing](https://arxiv.org/abs/2308.16557):
111-
- Generates tests that detect and kill code mutants, ensuring robustness.
112-
113-
```bash
114-
## go to examples/java_maven
115-
## remove some tests from BankAccountTest.java
116-
117-
mutahunter gen --test-command "mvn clean test" --code-coverage-report-path "target/site/jacoco/jacoco.xml" --test-file-path "src/test/java/BankAccountTest.java" --source-file-path "src/main/java/com/example/BankAccount.java" --coverage-type jacoco --model "gpt-4o"
118-
119-
Line coverage increased from 47.00% to 100.00%
120-
Mutation coverage increased from 92.86% to 92.86%
121-
```
122-
123-
## Mutant Report
124-
125-
Check the logs directory to view the report:
126-
127-
- `mutants.json` - Contains the list of mutants generated.
128-
- `coverage.txt` - Contains information about mutation coverage.
129-
- `audit.md` - Contains the analysis of survived mutants
130-
131-
### Survivng Mutant Analysis Audit Report
132-
133-
![Report](/images/audit.png)
134-
135118
## CI/CD Integration
136119
137120
You can integrate Mutahunter into your CI/CD pipeline to automate mutation testing. Here is an example GitHub Actions workflow file:
@@ -180,7 +163,7 @@ jobs:
180163
env:
181164
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
182165
run: |
183-
mutahunter run --test-command "mvn test" --code-coverage-report-path "target/site/jacoco/jacoco.xml" --coverage-type jacoco --model "gpt-4o" --modified-files-only
166+
mutahunter run --test-command "mvn test" --code-coverage-report-path "target/site/jacoco/jacoco.xml" --coverage-type jacoco --model "gpt-4o" --diff
184167
185168
- name: PR comment the mutation coverage
186169
uses: thollander/[email protected]

examples/go_webservice/README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,4 @@ export OPENAI_API_KEY=your-key-goes-here
2424
mutahunter run --test-command "go test" --code-coverage-report-path "coverage.xml" --only-mutate-file-paths "app.go" --model "gpt-4o-mini"
2525
```
2626

27-
### Surviving Mutant Analysis
28-
29-
[Mutants](./mutants.json)
30-
31-
[Report](./mutant_analysis.md)
27+
Check `logs/_latest/html` for mutation report.

examples/java_maven/readme.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@ mutahunter run --test-command "mvn test" --code-coverage-report-path "target/sit
2323

2424
```bash
2525
# remove some tests
26-
mutahunter gen --test-command "mvn clean test" --code-coverage-report-path "target/site/jacoco/jacoco.xml" --test-file-path "src/test/java/BankAccountTest.java" --source-file-path "src/main/java/com/example/BankAccount.java" --coverage-type jacoco --model "gpt-4o-mini"
26+
mutahunter gen --test-command "mvn test" --code-coverage-report-path "target/site/jacoco/jacoco.xml" --coverage-type jacoco --test-file-path "src/test/java/BankAccountTest.java" --source-file-path "src/main/java/com/example/BankAccount.java" --model "gpt-4o"
2727
```
2828

29-
### Surviving Mutant Analysis
30-
31-
[Mutants](./mutants.json)
32-
33-
[Report](./mutant_analysis.md)
29+
Check `logs/_latest/html` for mutation report.

examples/js_vanilla/README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,4 @@ export OPENAI_API_KEY=your-key-goes-here
1616
mutahunter run --test-command "npm run test" --code-coverage-report-path "coverage/coverage.xml" --only-mutate-file-paths "ui.js" --model "gpt-4o-mini"
1717
```
1818

19-
### Surviving Mutant Analysis
20-
21-
[Mutants](./mutants.json)
22-
23-
[Report](./mutant_analysis.md)
19+
Check `logs/_latest/html` for mutation report.

examples/python_fastapi/README.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,4 @@ export OPENAI_API_KEY=your-key-goes-here
1616
mutahunter run --test-command "pytest" --code-coverage-report-path "coverage.xml" --only-mutate-file-paths "app.py" --model "gpt-4o-mini"
1717
```
1818

19-
### Surviving Mutant Analysis
20-
21-
[Mutants](./mutants.json)
22-
23-
[Report](./mutant_analysis.md)
24-
∂∂∂
19+
Check `logs/_latest/html` for mutation report.

images/diagram.svg

Lines changed: 0 additions & 21 deletions
This file was deleted.

images/mutation_details.png

293 KB
Loading

images/mutation_overall.png

193 KB
Loading

images/mutation_report.png

267 KB
Loading

0 commit comments

Comments
 (0)