Improve error message when kittest fails (#5427)

* Closes https://github.com/emilk/egui/issues/5423

New output is actionable

```
failures:

---- demo::demo_app_windows::tests::demos_should_match_snapshot stdout ----
thread 'demo::demo_app_windows::tests::demos_should_match_snapshot' panicked at crates/egui_demo_lib/src/demo/demo_app_windows.rs:433:9:
Errors: [
    "'demos/Code Example' Image size did not match snapshot. Expected: (402, 574), Actual: (415, 574).
     Run `UPDATE_SNAPSHOTS=1 cargo test` to update the snapshots.",
]
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    demo::demo_app_windows::tests::demos_should_match_snapshot
```
This commit is contained in:
Emil Ernerfeldt 2024-12-03 13:40:51 +01:00 committed by GitHub
parent 3411aba768
commit c7224aab26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 11 deletions

View File

@ -1 +1,2 @@
/crates/egui_kittest @lucasmerlin
/crates/egui-wgpu @Wumpf /crates/egui-wgpu @Wumpf

View File

@ -426,7 +426,7 @@ mod tests {
let result = harness.try_wgpu_snapshot_options(&format!("demos/{name}"), &options); let result = harness.try_wgpu_snapshot_options(&format!("demos/{name}"), &options);
if let Err(err) = result { if let Err(err) = result {
errors.push(err); errors.push(err.to_string());
} }
} }

View File

@ -53,6 +53,9 @@ impl SnapshotOptions {
pub enum SnapshotError { pub enum SnapshotError {
/// Image did not match snapshot /// Image did not match snapshot
Diff { Diff {
/// Name of the test
name: String,
/// Count of pixels that were different /// Count of pixels that were different
diff: i32, diff: i32,
@ -72,6 +75,9 @@ pub enum SnapshotError {
/// The size of the image did not match the snapshot /// The size of the image did not match the snapshot
SizeMismatch { SizeMismatch {
/// Name of the test
name: String,
/// Expected size /// Expected size
expected: (u32, u32), expected: (u32, u32),
@ -89,32 +95,43 @@ pub enum SnapshotError {
}, },
} }
const HOW_TO_UPDATE_SCREENSHOTS: &str =
"Run `UPDATE_SNAPSHOTS=1 cargo test` to update the snapshots.";
impl Display for SnapshotError { impl Display for SnapshotError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::Diff { diff, diff_path } => { Self::Diff {
name,
diff,
diff_path,
} => {
write!( write!(
f, f,
"Image did not match snapshot. Diff: {diff}, {diff_path:?}" "'{name}' Image did not match snapshot. Diff: {diff}, {diff_path:?}. {HOW_TO_UPDATE_SCREENSHOTS}"
) )
} }
Self::OpenSnapshot { path, err } => match err { Self::OpenSnapshot { path, err } => match err {
ImageError::IoError(io) => match io.kind() { ImageError::IoError(io) => match io.kind() {
ErrorKind::NotFound => { ErrorKind::NotFound => {
write!(f, "Missing snapshot: {path:?}") write!(f, "Missing snapshot: {path:?}. {HOW_TO_UPDATE_SCREENSHOTS}")
} }
err => { err => {
write!(f, "Error reading snapshot: {err:?}\nAt: {path:?}") write!(f, "Error reading snapshot: {err:?}\nAt: {path:?}. {HOW_TO_UPDATE_SCREENSHOTS}")
} }
}, },
err => { err => {
write!(f, "Error decoding snapshot: {err:?}\nAt: {path:?}") write!(f, "Error decoding snapshot: {err:?}\nAt: {path:?}. Make sure git-lfs is setup correctly. Read the instructions here: https://github.com/emilk/egui/blob/master/CONTRIBUTING.md#making-a-pr")
} }
}, },
Self::SizeMismatch { expected, actual } => { Self::SizeMismatch {
name,
expected,
actual,
} => {
write!( write!(
f, f,
"Image size did not match snapshot. Expected: {expected:?}, Actual: {actual:?}" "'{name}' Image size did not match snapshot. Expected: {expected:?}, Actual: {actual:?}. {HOW_TO_UPDATE_SCREENSHOTS}"
) )
} }
Self::WriteSnapshot { path, err } => { Self::WriteSnapshot { path, err } => {
@ -194,6 +211,7 @@ pub fn try_image_snapshot_options(
if previous.dimensions() != current.dimensions() { if previous.dimensions() != current.dimensions() {
maybe_update_snapshot(&path, current)?; maybe_update_snapshot(&path, current)?;
return Err(SnapshotError::SizeMismatch { return Err(SnapshotError::SizeMismatch {
name: name.to_owned(),
expected: previous.dimensions(), expected: previous.dimensions(),
actual: current.dimensions(), actual: current.dimensions(),
}); });
@ -217,13 +235,16 @@ pub fn try_image_snapshot_options(
err, err,
})?; })?;
maybe_update_snapshot(&path, current)?; maybe_update_snapshot(&path, current)?;
return Err(SnapshotError::Diff { diff, diff_path }); Err(SnapshotError::Diff {
name: name.to_owned(),
diff,
diff_path,
})
} else { } else {
// Delete old diff if it exists // Delete old diff if it exists
std::fs::remove_file(diff_path).ok(); std::fs::remove_file(diff_path).ok();
Ok(())
} }
Ok(())
} }
/// Image snapshot test. /// Image snapshot test.