Skip to content

Cannot create Bevy app in tests due to non-main thread #1720

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

Closed
alice-i-cecile opened this issue Mar 22, 2021 · 5 comments
Closed

Cannot create Bevy app in tests due to non-main thread #1720

alice-i-cecile opened this issue Mar 22, 2021 · 5 comments
Labels
C-Usability A targeted quality-of-life change that makes Bevy easier to use

Comments

@alice-i-cecile
Copy link
Member

Bevy version

The release number or commit hash of the version you're using.

Operating system & version

Windows 10, VSCode, commit: 348e2a3

What you did

#[cfg(test)]
mod tests {
    use bevy::prelude::*;
    #[test]
    fn default_plugin_tests() {
        App::build().add_plugins(DefaultPlugins).run();
    }
}

What you expected to happen

I would be able to spawn Bevy apps within my tests.

What actually happened

Using cargo test fails:

 Caused by:
 process didn't exit successfully: `C:\Users\Alice\Documents\bevy-scratchpad\target\debug\deps\bevy_scratchpad-c846071201aed109.exe tests::minimal_bevy_tests --exact --nocapture` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)

Running just the single test reveals:

thread 'tests::default_plugin_tests' panicked at 'Initializing the event loop outside of the main thread is a significant cross-platform compatibility hazard. If you really, absolutely need to create an EventLoop on a different thread, please use the `EventLoopExtWindows::new_any_thread` function.', C:\Users\Alice\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:136:9

Additional information

This fails for DefaultPlugins but not MinimalPlugins.

#1714 has great guidance on how to test individual systems, but this doesn't suffice for full integration tests (and this failure is frustrating for beginners).

@mockersf suggested that I try running the test using only 1 thread, as described here. Using cargo test -- --test-threads=1 solves the issue, but this is a nuisance to remember to do every time (and I only want to run the main-thread-only tests on the main thread).

@alice-i-cecile alice-i-cecile added the C-Usability A targeted quality-of-life change that makes Bevy easier to use label Mar 22, 2021
@alice-i-cecile
Copy link
Member Author

alice-i-cecile commented Mar 22, 2021

I think what you're trying to do in #1720 can be very painful, as adding DefaultPlugins probably mean opening a window, having it's event loop (error above), taking control of the gpu, ... I think it would be more interesting to define either a TestAppBuilder, or a DefaultTestPlugins with custom configuration for tests rather than trying to start a normal Bevy app

it would be very nice if it's possible but next you'll be in a world of pain for CI 😄

@mockersf on Discord

I agree with this. The actual solution to this problem is likely to define better testing idioms / harnesses for integration testing of Bevy apps.

@alice-i-cecile
Copy link
Member Author

More discussion of this issue on Discord. TL;DR:

  • It would be nice to be able to mock out input events for end-to-end testing.
  • This should be at a smarter level than AutoHotKey to reduce test fragility.
  • Smart input mocking is needed for good accessibility (and TASing!) already.

@mockersf
Copy link
Member

  • It would be nice to be able to mock out input events for end-to-end testing.

You can already

For example, for keyboard, you can send an event KeyboardInput. As Bevy doesn't differentiate between events from winit or from your code, they will be treated the same

pub struct KeyboardInput {
pub scan_code: u32,
pub key_code: Option<KeyCode>,
pub state: ElementState,
}

If you are using a Res<Input<KeyCode>> to detect key presses, this is also updated from the events so it will work too

pub fn keyboard_input_system(
mut keyboard_input: ResMut<Input<KeyCode>>,
mut keyboard_input_events: EventReader<KeyboardInput>,
) {

@alice-i-cecile
Copy link
Member Author

This is now definitely resolved! I have integration tests working here.

@alice-i-cecile
Copy link
Member Author

This is still not fully resolved: DefaultPlugins doesn't play nice, and warnings could be better. Despite that, I think other issues are better for targeted fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-Usability A targeted quality-of-life change that makes Bevy easier to use
Projects
None yet
Development

No branches or pull requests

2 participants