diff --git a/examples/README.md b/examples/README.md
index 1517576593..231451ce4b 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -47,6 +47,7 @@ git checkout v0.4.0
- [Reflection](#reflection)
- [Scene](#scene)
- [Shaders](#shaders)
+ - [Tests](#tests)
- [Tools](#tools)
- [UI (User Interface)](#ui-user-interface)
- [Window](#window)
@@ -130,8 +131,8 @@ Example | File | Description
Example | File | Description
--- | --- | ---
-`log_diagnostics` | [`diagnostics/log_diagnostics.rs`](./diagnostics/log_diagnostics.rs) | Add a plugin that logs diagnostics to the console
`custom_diagnostic` | [`diagnostics/custom_diagnostic.rs`](./diagnostics/custom_diagnostic.rs) | Shows how to create a custom diagnostic
+`log_diagnostics` | [`diagnostics/log_diagnostics.rs`](./diagnostics/log_diagnostics.rs) | Add a plugin that logs diagnostics to the console
## ECS (Entity Component System)
@@ -197,6 +198,12 @@ Example | File | Description
`shader_custom_material` | [`shader/shader_custom_material.rs`](./shader/shader_custom_material.rs) | Illustrates creating a custom material and a shader that uses it
`shader_defs` | [`shader/shader_defs.rs`](./shader/shader_defs.rs) | Demonstrates creating a custom material that uses "shaders defs" (a tool to selectively toggle parts of a shader)
+## Tests
+
+Example | File | Description
+--- | --- | ---
+`how_to_test_systems` | [`../tests/how_to_test_systems.rs`](../tests/how_to_test_systems.rs) | How to test systems with commands, queries or resources
+
## Tools
Example | File | Description
diff --git a/tests/how_to_test_systems.rs b/tests/how_to_test_systems.rs
new file mode 100644
index 0000000000..b70807aafa
--- /dev/null
+++ b/tests/how_to_test_systems.rs
@@ -0,0 +1,97 @@
+use bevy::prelude::*;
+
+#[derive(Default)]
+struct Enemy {
+ hit_points: u32,
+}
+
+fn despawn_dead_enemies(mut commands: Commands, enemies: Query<(Entity, &Enemy)>) {
+ for (entity, enemy) in enemies.iter() {
+ if enemy.hit_points == 0 {
+ commands.entity(entity).despawn_recursive();
+ }
+ }
+}
+
+fn hurt_enemies(mut enemies: Query<&mut Enemy>) {
+ for mut enemy in enemies.iter_mut() {
+ enemy.hit_points -= 1;
+ }
+}
+
+fn spawn_enemy(mut commands: Commands, keyboard_input: Res>) {
+ if keyboard_input.just_pressed(KeyCode::Space) {
+ commands.spawn().insert(Enemy { hit_points: 5 });
+ }
+}
+
+#[test]
+fn did_hurt_enemy() {
+ // Setup world
+ let mut world = World::default();
+
+ // Setup stage with our two systems
+ let mut update_stage = SystemStage::parallel();
+ update_stage.add_system(hurt_enemies.system().before("death"));
+ update_stage.add_system(despawn_dead_enemies.system().label("death"));
+
+ // Setup test entities
+ let enemy_id = world.spawn().insert(Enemy { hit_points: 5 }).id();
+
+ // Run systems
+ update_stage.run(&mut world);
+
+ // Check resulting changes
+ assert!(world.get::(enemy_id).is_some());
+ assert_eq!(world.get::(enemy_id).unwrap().hit_points, 4);
+}
+
+#[test]
+fn did_despawn_enemy() {
+ // Setup world
+ let mut world = World::default();
+
+ // Setup stage with our two systems
+ let mut update_stage = SystemStage::parallel();
+ update_stage.add_system(hurt_enemies.system().before("death"));
+ update_stage.add_system(despawn_dead_enemies.system().label("death"));
+
+ // Setup test entities
+ let enemy_id = world.spawn().insert(Enemy { hit_points: 1 }).id();
+
+ // Run systems
+ update_stage.run(&mut world);
+
+ // Check resulting changes
+ assert!(world.get::(enemy_id).is_none());
+}
+
+#[test]
+fn spawn_enemy_using_input_resource() {
+ // Setup world
+ let mut world = World::default();
+
+ // Setup stage with a system
+ let mut update_stage = SystemStage::parallel();
+ update_stage.add_system(spawn_enemy.system());
+
+ // Setup test resource
+ let mut input = Input::::default();
+ input.press(KeyCode::Space);
+ world.insert_resource(input);
+
+ // Run systems
+ update_stage.run(&mut world);
+
+ // Check resulting changes, one entity has been spawned with `Enemy` component
+ assert_eq!(world.query::<&Enemy>().iter(&world).len(), 1);
+
+ // Clear the `just_pressed` status for all `KeyCode`s
+ world.get_resource_mut::>().unwrap().clear();
+
+ // Run systems
+ update_stage.run(&mut world);
+
+ // Check resulting changes, no new entity has been spawned
+ assert_eq!(world.query::<&Enemy>().iter(&world).len(), 1);
+}