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

Integration testing/event injection #3491

Closed
svenstaro opened this issue Oct 20, 2023 · 5 comments · Fixed by #5166
Closed

Integration testing/event injection #3491

svenstaro opened this issue Oct 20, 2023 · 5 comments · Fixed by #5166

Comments

@svenstaro
Copy link

I didn't find anything about this in this whole project which is odd so I think the following should be considered a feature request.

There's currently no documented (or even possible?) way to do integration testing/event injection/instrumentation for the purposes of integration testing. It's probably possible to abuse the new accessibility features for that like in other frameworks but it would still be good to have an official way for doing this for people that want to test their UIs.

@YgorSouza
Copy link
Contributor

Wouldn't that be the same as any other integration? In which case you could follow the instructions in https://docs.rs/egui/0.23.0/egui/index.html#integrating-with-egui.

@svenstaro
Copy link
Author

svenstaro commented Oct 21, 2023

It might be, but this issue is about documenting the flow for integration testing in an obvious manner. I'll give it a shot and maybe make a PR.

@drewmiller
Copy link

It might be, but this issue is about documenting the flow for integration testing in an obvious manner. I'll give it a shot and maybe make a PR.

Consider the Imgui test engine here: https://github.com/ocornut/imgui_test_engine. It seems like something similar should be on the roadmap.

@xiyuzhai
Copy link

xiyuzhai commented Aug 7, 2024

I'm also confused about what to do for continuous integration.

@emilk
Copy link
Owner

emilk commented Aug 27, 2024

Some automated testing of an egui app would be great, and I think the best approach might be to interface with accesskit, both for reading the location of widgets and for automating interaction with them. That way the same code can be reusable across GUI toolkits (i.e. not be egui specific)

hacknus pushed a commit to hacknus/egui that referenced this issue Oct 30, 2024
- closes emilk#3491 
- closes emilk#3926

This adds a testing library to egui based on
[kittest](https://github.com/rerun-io/kittest). Kittest is a new
[AccessKit](https://github.com/AccessKit/accesskit/)-based testing
library. The api is inspired by the js
[testing-library](https://testing-library.com/) where the idea is also
to query the dom based on accessibility attributes.
We made kittest with egui in mind but it should work with any rust gui
framework with AccessKit support.

It currently has support for:
- running the egui app, frame by frame
- building the AccessKit tree
- ergonomic queries via kittest
  - via e.g. 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
- snapshot tests with these screenshots

A simple test looks like this: 
```rust
fn main() {
    let mut checked = false;
    let app = |ctx: &Context| {
        CentralPanel::default().show(ctx, |ui| {
            ui.checkbox(&mut checked, "Check me!");
        });
    };

    let mut harness = Harness::builder().with_size(egui::Vec2::new(200.0, 100.0)).build(app);
    
    let checkbox = harness.get_by_name("Check me!");
    assert_eq!(checkbox.toggled(), Some(Toggled::False));
    checkbox.click();
    
    harness.run();

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

    // You can even render the ui and do image snapshot tests
    #[cfg(all(feature = "wgpu", feature = "snapshot"))]
    egui_kittest::image_snapshot(&egui_kittest::wgpu::TestRenderer::new().render(&harness), "readme_example");
}
```

~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)~ (this didn't work as well as I hoped and it turns out in CI
you can just run tests on a mac runner which comes with a real GPU)
 
Here is a example of a failed snapshot test in ci, it will say which
snapshot failed and upload an artifact with the before / after and diff
images:

https://github.com/emilk/egui/actions/runs/11183049487/job/31090724606?pr=5166
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants