Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve egui_kittest documentation and update CONTRIBUTING.md #5296

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ This contains a bunch of uses of `egui` and looks like the ui code you would wri
Thin wrapper around `egui_demo_lib` so we can compile it to a web site or a native app executable.
Depends on `egui_demo_lib` + `eframe`.

### `egui_kittest`
A test harness for egui based on [kittest](https://github.com/rerun/kittest) and [AccessKit](https://github.com/AccessKit/accesskit/).

### Other integrations

There are also many great integrations for game engines such as `bevy` and `miniquad` which you can find at <https://github.com/emilk/egui#integrations>.
8 changes: 8 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ For small things, just go ahead an open a PR. For bigger things, please file an
Browse through [`ARCHITECTURE.md`](ARCHITECTURE.md) to get a sense of how all pieces connects.

You can test your code locally by running `./scripts/check.sh`.
There are snapshots test that might need to be updated. Run the tests with `UPDATE_SNAPSHOTS=true` to update them.
For more info about the tests see [egui_kittest](./crates/egui_kittest/README.md).

We use [git-lfs](https://git-lfs.com/) to store big files in the repository.
Make sure you have it installed (running `git lfs ls-files` from the repository root should list some files).
Don't forget to run `git lfs install` after installing the git-lfs binary.

If you see an `InvalidSignature` error when running snapshot tests, it's probably a problem related to git-lfs.

When you have something that works, open a draft PR. You may get some helpful feedback early!
When you feel the PR is ready to go, do a self-review of the code, and then open it for review.
Expand Down
12 changes: 12 additions & 0 deletions crates/egui_kittest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Ui testing library for egui, based on [kittest](https://github.com/rerun-io/kittest) (an [AccessKit](https://github.com/AccessKit/accesskit) based testing library).

## Example usage
```rust
use egui::accesskit::{Role, Toggled};
use egui::{CentralPanel, Context, TextEdit, Vec2};
Expand Down Expand Up @@ -33,3 +34,14 @@ fn main() {
harness.wgpu_snapshot("readme_example");
}
```

## Snapshot testing
There is a snapshot testing feature. To create snapshot tests, enable the `snapshot` and `wgpu` features.
Once enabled, you can call `Harness::wgpu_snapshot` to render the ui and save the image to the `tests/snapshots` directory.

To update the snapshots, run your tests with `UPDATE_SNAPSHOTS=true`, so e.g. `UPDATE_SNAPSHOTS=true cargo test`.
Running with `UPDATE_SNAPSHOTS=true` will still cause the tests to fail, but on the next run, the tests should pass.

If you want to have multiple snapshots in the same test, it makes sense to collect the results in a `Vec`
([look here](https://github.com/emilk/egui/blob/70a01138b77f9c5724a35a6ef750b9ae1ab9f2dc/crates/egui_demo_lib/src/demo/demo_app_windows.rs#L388-L427) for an example).
This way they can all be updated at the same time.
12 changes: 12 additions & 0 deletions crates/egui_kittest/src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ impl Display for SnapshotError {
}

/// Image snapshot test.
/// The snapshot will be saved under `tests/snapshots/{name}.png`.
/// The new image from the last test run will be saved under `tests/snapshots/{name}.new.png`.
/// If new image didn't match the snapshot, a diff image will be saved under `tests/snapshots/{name}.diff.png`.
///
/// # Errors
/// Returns a [`SnapshotError`] if the image does not match the snapshot or if there was an error
Expand Down Expand Up @@ -170,6 +173,9 @@ fn maybe_update_snapshot(
}

/// Image snapshot test.
/// The snapshot will be saved under `tests/snapshots/{name}.png`.
/// The new image from the last test run will be saved under `tests/snapshots/{name}.new.png`.
/// If new image didn't match the snapshot, a diff image will be saved under `tests/snapshots/{name}.diff.png`.
///
/// # Panics
/// Panics if the image does not match the snapshot or if there was an error reading or writing the
Expand All @@ -187,6 +193,9 @@ pub fn image_snapshot(current: &image::RgbaImage, name: &str) {
#[cfg(feature = "wgpu")]
impl Harness<'_> {
/// Render a image using a default [`crate::wgpu::TestRenderer`] and compare it to the snapshot.
/// The snapshot will be saved under `tests/snapshots/{name}.png`.
/// The new image from the last test run will be saved under `tests/snapshots/{name}.new.png`.
/// If new image didn't match the snapshot, a diff image will be saved under `tests/snapshots/{name}.diff.png`.
///
/// # Errors
/// Returns a [`SnapshotError`] if the image does not match the snapshot or if there was an error
Expand All @@ -198,6 +207,9 @@ impl Harness<'_> {
}

/// Render a image using a default [`crate::wgpu::TestRenderer`] and compare it to the snapshot.
/// The snapshot will be saved under `tests/snapshots/{name}.png`.
/// The new image from the last test run will be saved under `tests/snapshots/{name}.new.png`.
/// If new image didn't match the snapshot, a diff image will be saved under `tests/snapshots/{name}.diff.png`.
///
/// # Panics
/// Panics if the image does not match the snapshot or if there was an error reading or writing the
Expand Down
10 changes: 10 additions & 0 deletions crates/egui_kittest/src/wgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use image::RgbaImage;
use std::iter::once;
use wgpu::Maintain;

/// Utility to render snapshots from a [`Harness`] using [`egui_wgpu`].
pub struct TestRenderer {
device: wgpu::Device,
queue: wgpu::Queue,
Expand All @@ -19,6 +20,7 @@ impl Default for TestRenderer {
}

impl TestRenderer {
/// Create a new [`TestRenderer`] using a default [`wgpu::Instance`].
pub fn new() -> Self {
let instance = wgpu::Instance::new(InstanceDescriptor::default());

Expand All @@ -39,6 +41,7 @@ impl TestRenderer {
Self::create(device, queue)
}

/// Create a new [`TestRenderer`] using the provided [`wgpu::Device`] and [`wgpu::Queue`].
pub fn create(device: wgpu::Device, queue: wgpu::Queue) -> Self {
Self {
device,
Expand All @@ -47,13 +50,20 @@ impl TestRenderer {
}
}

/// Enable or disable dithering.
///
/// Disabled by default.
#[inline]
pub fn with_dithering(mut self, dithering: bool) -> Self {
self.dithering = dithering;
self
}

/// Render the [`Harness`] and return the resulting image.
pub fn render(&mut self, harness: &Harness<'_>) -> RgbaImage {
// We need to create a new renderer each time we render, since the renderer stores
// textures related to the Harnesses' egui Context.
// Calling the renderer from different Harnesses would cause problems if we store the renderer.
let mut renderer = egui_wgpu::Renderer::new(
&self.device,
TextureFormat::Rgba8Unorm,
Expand Down
Loading