Crates.io | egui_kittest |
lib.rs | egui_kittest |
version | 0.32.3 |
created_at | 2024-12-16 17:01:51.480437+00 |
updated_at | 2025-09-12 06:02:25.002203+00 |
description | Testing library for egui based on kittest and AccessKit |
homepage | https://github.com/emilk/egui |
repository | https://github.com/emilk/egui |
max_upload_size | |
id | 1485295 |
size | 219,449 |
Ui testing library for egui, based on kittest (an AccessKit based testing library).
use egui::accesskit::Toggled;
use egui_kittest::{Harness, kittest::{Queryable, NodeT}};
fn main() {
let mut checked = false;
let app = |ui: &mut egui::Ui| {
ui.checkbox(&mut checked, "Check me!");
};
let mut harness = Harness::new_ui(app);
let checkbox = harness.get_by_label("Check me!");
assert_eq!(checkbox.accesskit_node().toggled(), Some(Toggled::False));
checkbox.click();
harness.run();
let checkbox = harness.get_by_label("Check me!");
assert_eq!(checkbox.accesskit_node().toggled(), Some(Toggled::True));
// Shrink the window size to the smallest size possible
harness.fit_contents();
// You can even render the ui and do image snapshot tests
#[cfg(all(feature = "wgpu", feature = "snapshot"))]
harness.snapshot("readme_example");
}
There is a snapshot testing feature. To create snapshot tests, enable the snapshot
and wgpu
features.
Once enabled, you can call Harness::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 cause the tests to succeed.
This is so that you can set UPDATE_SNAPSHOTS=true
and update all tests, without cargo test
failing on the first failing crate.
If you want to have multiple snapshots in the same test, it makes sense to collect the results in a Vec
(look here for an example).
This way they can all be updated at the same time.
You should add the following to your .gitignore
:
**/tests/snapshots/**/*.diff.png
**/tests/snapshots/**/*.new.png
insta
snapshot tests over image comparison tests because…
The default tolerance settings should be fine for almost all gui comparison tests. However, especially when you're using custom rendering, you may observe images difference with different setups leading to unexpected test failures.
First check whether the difference is due to a change in enabled rendering features, potentially due to difference in hardware (/software renderer) capabilitites. Generally you should carefully enforcing the same set of features for all test runs, but this may happen nonetheless.
Once you validated that the differences are miniscule and hard to avoid, you can try to carefully adjust the comparison tolerance setting (SnapshotOptions::threshold
, TODO(#5683): as well as number of pixels allowed to differ) for the specific test.
⚠️ WARNING ⚠️ Picking too high tolerances may mean that you are missing actual test failures. It is recommended to manually verify that the tests still break under the right circumstances as expected after adjusting the tolerances.
In order to avoid image differences, it can be useful to form an understanding of how they occur in the first place.
Discrepancies can be caused by a variety of implementation details that depend on the concrete GPU, OS, rendering backend (Metal/Vulkan/DX12 etc.) or graphics driver (even between different versions of the same driver).
Common issues include:
textureLoad
)
NaN
/Inf
handling
NaN
/Inf
, implementations may free to yield an indeterminate value insteaddpdxFine
or dpdxCoarse
From this follow a few simple recommendations (these may or may not apply as they may impose unwanted restrictions on your rendering setup):