Skip to content

Commit

Permalink
Merge #162, adding --in-diff
Browse files Browse the repository at this point in the history
  • Loading branch information
sourcefrog committed Nov 13, 2023
1 parent 2733fb5 commit 9e2833d
Show file tree
Hide file tree
Showing 22 changed files with 892 additions and 23 deletions.
34 changes: 32 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ name: Tests
permissions:
contents: read

on: push
on:
push:
branches:
- main
pull_request:

# see https://matklad.github.io/2021/09/04/fast-rust-builds.html
env:
Expand Down Expand Up @@ -43,9 +47,35 @@ jobs:
- name: Test
run: cargo test --workspace

incremental-mutants:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Relative diff
run: |
git branch -av
git diff origin/${{ github.base_ref }}.. | tee git.diff
- uses: dtolnay/rust-toolchain@master
with:
toolchain: beta
- uses: Swatinem/rust-cache@v2
- run: cargo install --path .
- name: Mutants
run: |
cargo mutants --no-shuffle --exclude console.rs -j 2 -vV --in-diff git.diff
- name: Archive mutants.out
uses: actions/upload-artifact@v3
if: always()
with:
name: mutants-incremental.out
path: mutants.out

cargo-mutants:
runs-on: ubuntu-latest
needs: build
# needs: [build, incremental-mutants]
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
Expand Down
112 changes: 112 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ indoc = "2.0.0"
itertools = "0.11"
mutants = "0.0.3"
nix = "0.27"
patch = "0.7"
path-slash = "0.2"
quote = "1.0"
serde_json = "1"
Expand Down Expand Up @@ -105,6 +106,8 @@ exclude = [
"testdata/tree/cfg_attr_mutants_skip",
"testdata/tree/cfg_attr_test_skip",
"testdata/tree/dependency",
"testdata/tree/diff0",
"testdata/tree/diff1",
"testdata/tree/error_value",
"testdata/tree/everything_skipped",
"testdata/tree/factorial",
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# cargo-mutants changelog

## 23.11.1

- New `--in-diff FILE` option tests only mutants that are in the diff from the
given file. This is useful to avoid testing mutants from code that has not changed,
either locally or in CI.

## 23.11.0

- Changed: `cargo mutants` now tries to match the behavior of `cargo test` when run within a workspace. If run in a package directory, it tests only that package. If run in a workspace that is not a package (a "virtual workspace"), it tests the configured default packages, or otherwise all packages. This can all be overridden with the `--package` or `--workspace` options.
Expand Down
4 changes: 3 additions & 1 deletion book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
- [Error values](error-values.md)
- [Improving performance](performance.md)
- [Parallelism](parallelism.md)
- [Incremental tests of modified code](in-diff.md)
- [Integrations](integrations.md)
- [Continuous integration](ci.md)
- [Continuous integration](ci.md)
- [Incremental tests of pull requests](pr-diff.md)
- [How it works](how-it-works.md)
- [Goals](goals.md)
- [Mutations vs coverage](vs-coverage.md)
Expand Down
52 changes: 52 additions & 0 deletions book/src/in-diff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Incremental tests of modified code

If you're working on a large project or one with a long test suite, you may not want to test the entire codebase every time you make a change. You can use `cargo-mutants --in-diff` to test only mutants generated from recently changed code.

The `--in-diff DIFF_FILE` option tests only mutants that overlap with regions changed in the diff.

The diff is expected to either have a prefix of `b/` on the new filename, which is the format produced by `git diff`, or no prefix.

Some ways you could use `--in-diff`:

1. Before submitting code, check your uncommitted changes with `git diff`.
2. In CI, or locally, check the diff between the current branch and the base branch of the pull request.

Changes to non-Rust files, or files from which no mutants are produced, are ignored.

`--in-diff` is applied on the output of other filters including `--package` and `--regex`. For example, `cargo mutants --in-diff --package foo` will only test mutants in the `foo` package that overlap with the diff.

## Caution

`--in-diff` makes tests faster by covering the mutants that are most likely to be missed in the changed code. However, it's certainly possible that edits in one region cause code in a different region or a different file to no longer be well tested. Incremental tests are helpful for giving faster feedback, but they're not a substitute for a full test run.

## Example

In this diff, we've added a new function `two` to `src/lib.rs`, and the existing code is unaltered. With `--in-diff`, `cargo-mutants` will only test mutants that affect the function `two`.

```diff

```diff
--- a/src/lib.rs 2023-11-12 13:05:25.774658230 -0800
+++ b/src/lib.rs 2023-11-12 12:54:04.373806696 -0800
@@ -2,6 +2,10 @@
"one".to_owned()
}

+pub fn two() -> String {
+ format!("{}", 2)
+}
+
#[cfg(test)]
mod test_super {
use super::*;
@@ -10,4 +14,9 @@
fn test_one() {
assert_eq!(one(), "one");
}
+
+ #[test]
+ fn test_two() {
+ assert_eq!(two(), "2");
+ }
}
```
42 changes: 42 additions & 0 deletions book/src/pr-diff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Incremental tests of pull requests

You can use `--in-diff` to test only the code that has changed in a pull request. This can be useful for incremental testing in CI, where you want to test only the code that has changed since the last commit.

For example, you can use the following workflow to test only the code that has changed in a pull request:

```yaml
name: Tests

permissions:
contents: read

on:
push:
branches:
- main
pull_request:

jobs:
incremental-mutants:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Relative diff
run: |
git branch -av
git diff origin/${{ github.base_ref }}.. | tee git.diff
- uses: Swatinem/rust-cache@v2
- run: cargo install cargo-mutants
- name: Mutants
run: |
cargo mutants --no-shuffle -j 2 -vV --in-diff git.diff
- name: Archive mutants.out
uses: actions/upload-artifact@v3
if: always()
with:
name: mutants-incremental.out
path: mutants.out
```
Loading

0 comments on commit 9e2833d

Please sign in to comment.