The `ASSUMPTIONS` block documents that Stun Spore has `EFFECT_PARALYZE`.
If Stun Spore did not have that effect it would cause the tests in the file to be skipped. We write our tests like this so that hackers can change the effects of moves without causing tests to fail.
`SINGLE_BATTLE_TEST` defines the name of the test. Related tests should start with the same prefix, e.g. Stun Spore tests should start with "Stun Spore", this allows just the Stun Spore-related tests to be run with:
`GIVEN` initializes the parties, `PLAYER` and `OPPONENT` add a Pokémon to their respective parties. They can both accept a block which further customizes the Pokémon's stats, moves, item, ability, etc.
`WHEN` describes the turns, and `TURN` describes the choices made in a single turn. `MOVE` causes the player to use Stun Spore and adds the move to the Pokémon's moveset if an explicit Moves was not specified.
Pokémon that are not mentioned in a `TURN` use Celebrate.
The test runner rigs the RNG so that unless otherwise specified, moves always hit, never critical hit, always activate their secondary effects, and always roll the same damage modifier.
`SCENE` describes the player-visible output of the battle. In this case `ANIMATION` checks that the Stun Spore animation played, `MESSAGE` checks the paralysis message was shown, and `STATUS_ICON` checks that the opponent's HP bar shows a PRZ icon.
The `ASSUME` commands are documenting the reasons why Stun Spore does not affect Oddish, namely that Stun Spore is a powder move, and Oddish is a Grass-type. These `ASSUME` statements function similarly to the ones in `ASSUMPTIONS` but apply only to the one test.
NOT inverts the meaning of a `SCENE` check, so applying it to `ANIMATION` requires that the Stun Spore animation does not play. `MESSAGE` checks that the message was shown.
The checks in `SCENE` are ordered, so together this says "The doesn't affect message is shown, and the Stun Spore animation does not play at any time before that". Normally you would only test one or the other, or even better, just `NOT STATUS_ICON(opponent, paralysis: TRUE);` to say that Oddish was not paralyzed without specifying the exact outputs which led to that.
### Example 3
As a final example, to test that Meditate works you might:
1. Put a Wobbuffet that knows Meditate and Tackle in your party.
2. Battle a wild Wobbuffet.
3. Use Tackle and note the amount the HP bar reduced.
4. Battle a wild Wobbuffet.
5. Use Meditate and that the stat change animation and message play.
6. Use Tackle and check that the HP bar reduced by more than in 3.
This can be translated to an automated test as follows:
`PARAMETRIZE` causes a test to run multiple times, once per `PARAMETRIZE` block (e.g. once with `raiseAttack = FALSE` and once with `raiseAttack = TRUE`).
The `HP_BAR` command's `captureDamage` causes the change in HP to be stored in a variable, and the variable chosen is `results[i].damage`.
`results[i]` contains all the variables defined at the end of `SINGLE_BATTLE_TEST`, `i` is the current `PARAMETRIZE` index.
`FINALLY` runs after the last parameter has finished, and uses `EXPECT_MUL_EQ` to check that the second battle deals 1.5× the damage of the first battle (with a small tolerance to account for rounding).
You might notice that all the tests check the outputs the player could see rather than the internal battle state. e.g. the Meditate test could have used `gBattleMons[B_POSITION_OPPONENT_LEFT].hp` instead of using `HP_BAR` to capture the damage. This is a deliberate choice, by checking what the player can observe the tests are more robust to refactoring, e.g. if `gBattleMons` got moved into `gBattleStruct` then any test that used it would need to be updated.
### Note on Overworld Tests
The overworld is not available, so it is only possible to test commands which don't affect the overworld itself, e.g. `givemon` can be tested because it only alters `gPlayerParty`, but `addobject` cannot because it affects object events (which aren't loaded).
Causes the test to be skipped if `cond` is false. Used to document any prerequisites of the test, e.g. to test Burn reducing the Attack of a Pokémon we can observe the damage of a physical attack with and without the burn. To document that this test assumes the attack is physical we can use:
Should be placed immediately after any `#includes` and contain any `ASSUME` statements which should apply to the whole file, e.g. to test `EFFECT_POISON_HIT` we need to choose a move with that effect, if we chose to use Poison Sting in every test then the top of `move_effect_poison_hit.c` should be:
`SINGLE_BATTLE_TEST(name, results...)` and `DOUBLE_BATTLE_TEST(name, results...)`
Define single- and double- battles. The names should start with the name of the mechanic being tested so that it is easier to run all the related tests. `results` contains variable declarations to be placed into the `results` array which is available in tests using `PARAMETRIZE` commands.
Marks a test as not passing due to a bug. If there is an issue number associated with the bug it should be included in a comment. If the test passes the developer will be notified to remove `KNOWN_FAILING`.
Checks that the test passes successes/trials. If `tag` is provided, the test is run for each value that the tag can produce. For example, to check that Paralysis causes the turn to be skipped 25/100 times, we can write the following test that passes only if the Pokémon is fully paralyzed and specify that we expect it to pass 25/100 times when `RNG_PARALYSIS` varies:
```
SINGLE_BATTLE_TEST("Paralysis has a 25% chance of skipping the turn")
Note that this mode of PASSES_RANDOMLY makes the tests run very slowly and should be avoided where possible. If the mechanic you are testing is missing its tag, you should add it.
### `GIVEN`
```
Given {
...
}
```
Contains the initial state of the parties before the battle.
Groups the choices made by the battlers on a single turn. If Speeds have not been explicitly specified then the order of the `MOVE` commands in the `TURN` will be used to infer the Speeds of the Pokémon, e.g.:
Used when the battler chooses to use an item from the Bag. The item ID (e.g. ITEM_POTION) must be specified, and party index and move slot if applicable, e.g:
Contains code to run after the battle has finished. If the test is using `PARAMETRIZE` commands then `EXPECT` commands between the results should go here. Is also occasionally used to check the internal battle state when checking the behavior via a `SCENE` is too difficult, verbose, or error-prone.
### `FINALLY`
```
...
} FINALLY {
...
}
```
Contains checks to run after all `PARAMETERIZE` commands have run. Prefer to write your checks in `THEN` where possible, because a failure in `THEN` will be tagged with which parameter it corresponds to.