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

Add egui testing library #5166

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft

Add egui testing library #5166

wants to merge 9 commits into from

Conversation

lucasmerlin
Copy link
Collaborator

This adds a testing library to egui based on AccessKit. The api is inspired by the js testing-library where the idea is also to query the dom based on accessibility attributes.

I think a part of this can be generalized in a general ui testing library that works with all rust ui frameworks with accesskit support. This is currently in the accesskit_query crate in the PR but I think this should probably be put in a new repository? Currently it's a very light extension to accesskit_consumer with a trait but I want to add a lot more utility functions there to make testing as ergonomic as possible.

The egui testing library is called etest, but unfortunately that crate name is already taken so it will need to be renamed.

It currently has support for:

  • running the egui app, frame by frame
  • building the accesskit tree
  • ergonomic queries via accesskit_query
    • via get_by(closure), get_by_name, get_by_role
  • simulating events based on the accesskit node id
  • creating arbitrary events based on Harness::input_mut
  • rendering screenshots via wgpu
  • running snapshot tests with these screenshots

A simple test looks like this:

fn main() {
    let mut checked = false;
    let mut app = |ctx: &Context| {
        CentralPanel::default().show(ctx, |ui| {
            ui.checkbox(&mut checked, "Check me!");
        });
    };

    let mut harness = Harness::new().with_size(Vec2::new(200.0, 100.0));
    harness.run(&mut app);

    let checkbox = harness.root().get_by_name("Check me!");
    assert_eq!(checkbox.toggled(), Some(Toggled::False));
    harness.click(checkbox.id());

    harness.run(&mut app);

    let checkbox = harness.root().get_by_name("Check me!");
    assert_eq!(checkbox.toggled(), Some(Toggled::True));

    let image = TestRenderer::new().render(&harness);
    // Will fail if the ui changes visually
    // Snapshots can be updated with the UPDATE_SNAPSHOTS env var
    image_snapshot(image, "visual_test");
}

Since getting wgpu to run in ci is a hassle, I'm taking another shot at creating a software renderer for egui (ideally without a huge dependency like skia)

Copy link

Preview available at https://egui-pr-preview.github.io/pr/5166-lucas/testing_library
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

@lucasmerlin lucasmerlin added tests Unit tests, regression tests, manual tests, … dev-experience labels Sep 25, 2024
@emilk
Copy link
Owner

emilk commented Sep 25, 2024

After some discussion we came to these conclusions:

  • Investigate using git lfs for storing the .png snapshot files so we don't bloat the git repository. Try to set it up in such a way that git clone + cargo test still works for contributors without lfs.
  • Try to set up a proper software wgpu backend that works on CI, same as the wgpu repository uses. This will be the most powerful and accurate, and allow us to test more than just egui (i.e. the Rerun Viewer)
  • Move the accesskit-specific part of the integration to its own repository and eventually invite collaborators from other GUI toolkits to collaborate on it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dev-experience tests Unit tests, regression tests, manual tests, …
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improved unit/regression test support Integration testing/event injection
2 participants