'How to test system that requires Time resource?
I want to write tests for system that moves entities and detects collisions, system uses Res<Time>
to ensure that entities move with constant speed. I was trying to write test following this example, but it doesn't use Time. My test creates world and inserts two entities and tries to run my system.
let mut world = World::default();
/* here insert entities into world */
let mut update_stage = SystemStage::parallel();
update_stage.add_system(move_system);
It doesn't insert Time resource so unsurprisingly running it ends with
panicked at 'Resource requested by io_project::move_system::move_system does not exist: bevy_core::time::time::Time'
World
has method insert_resource()
but I wasn't able to figure out if I can use it to insert Time
resource.
I was also wondering if it would be possible to use some kind of ''fake'' time, meaning that instead of checking how much time really passed I would call something like time.pass_seconds(1.)
. This would be useful to simulate very high or low framerate and create more consistent results.
I am using bevy 0.6.1
Solution 1:[1]
In the source code (https://github.com/bevyengine/bevy/blob/main/crates/bevy_core/src/time/time.rs) there's an example which covers adding the Time resource for tests, as well as simulating time passing.
I've included it below for quick reference:
# use bevy_core::prelude::*;
# use bevy_ecs::prelude::*;
# use bevy_utils::Duration;
# fn main () {
# test_health_system();
# }
struct Health {
// Health value between 0.0 and 1.0
health_value: f32,
}
fn health_system(time: Res<Time>, mut health: ResMut<Health>) {
// Increase health value by 0.1 per second, independent of frame rate, but not beyond 1.0
health.health_value = (health.health_value + 0.1 * time.delta_seconds()).min(1.0);
}
// Mock time in tests
fn test_health_system() {
let mut world = World::default();
let mut time = Time::default();
time.update();
world.insert_resource(time);
world.insert_resource(Health { health_value: 0.2 });
let mut update_stage = SystemStage::single_threaded();
update_stage.add_system(health_system);
// Simulate that 30 ms have passed
let mut time = world.resource_mut::<Time>();
let last_update = time.last_update().unwrap();
time.update_with_instant(last_update + Duration::from_millis(30));
// Run system
update_stage.run(&mut world);
// Check that 0.003 has been added to the health value
let expected_health_value = 0.2 + 0.1 * 0.03;
let actual_health_value = world.resource::<Health>().health_value;
assert_eq!(expected_health_value, actual_health_value);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |