Why testing your assistant?For more information E2E testing, see the
E2E testing product documentation.
tests directory of your project. The name of the file
should be e2e_test_cases.yml. You can also create a subdirectory inside the tests directory and place your test case
YAML files there. These files will be automatically discovered and run by Rasa, however you need to provide
the path to the subdirectory as positional argument to the rasa test e2e command.
Each input file must contain the test_cases key. The value of this key is a list of test cases.
Each test case must include a name given to the test_case key and a list of test steps given to the steps key.
A step can be either one of the following:
user: refers to a user’s message.bot: denotes a textual response generated by the bot.utter: refers to a bot response name as defined in the domain file.slot_was_set: indicates the successful setting of a slot, and depending on how it’s defined:- if a slot name is provided, e.g.
my_slot: checks that a slot with the given name is set. - if a key-value pair is provided, e.g.
my_slot: value: checks that a slot with the given name is set with the expected value.
- if a slot name is provided, e.g.
slot_was_not_set: specifies the failure to set a slot, and depending on the defenition:- if a slot name is provided, e.g.
my_slot: checks that a slot with the given name is not set. - if a key-value pair is provided, e.g.
my_slot: value: checks that a slot with the given name is not set or that its value differs from the expected value.
- if a slot name is provided, e.g.
user, bot, utter and slot_was_set steps can be used in a test case:
tests/e2e_test_cases.yml
user step, you can specify multiple expected events. Any additional events that are found
are ignored and do not cause the test to fail.
Slots
Slots can be specified as a list of either string values (representing the slot name) or of slot name and slot value pairs. If the slot is specified as a key-value pair, the the values are also compared. If the slot step contains only the slot name, it is asserted that the slot was either set (when usingslot_was_set step) or not (when using slot_was_not_set step).
tests/e2e_test_cases.yml
slot_was_set or slot_was_not_set
steps, you can indicate only a subset of slots that you want to check.
You can think of slot_was_not_set as an inverse of slot_was_set and when specifing a slot_was_not_set step
it looks for the absence of the SlotSet event in the tracker store but only for that particular user step not globally
(more at order of test steps).
Fixtures for Pre-Filled Slots
Using fixtures is an optional feature that enables the pre-filling of slots, ensuring specific context before individual test cases are run. You can define fixtures in either:- Test case files — using the
fixtureskey at the top level of a test case YAML file (e.g.e2e_test_cases.yml). - Conftest files — using the same
fixtureskey in aconftest.ymlorconftest.yamlfile at the root of your test tree or in any subfolder (see Conftest-style fixture hierarchy).
fixtures key.
Consider the following example, which includes a test case file with fixtures and two test cases that leverage these fixtures:
tests/fixture-tests.yml
action_session_start action and before the first step is executed by the test runner.
Conftest-style fixture hierarchy
You can define fixtures in conftest files (conftest.yml or conftest.yaml) so that all e2e tests under a given path see them, without repeating definitions in every test file.
Fixtures defined in tests/conftest.yml are visible to all test files under tests/.
- Folder conftest — Place a conftest file in a subfolder (e.g.
tests/admin/conftest.yml). Fixtures in a subfolder are visible to test files in that folder and its subfolders (e.g.tests/admin/foo.yml,tests/admin/bar/baz.yml).
Single-file run and fixture resolution
When you pass a single test file torasa test e2e (e.g. rasa test e2e tests/admin/foo.yml), the runner still resolves fixtures from the full hierarchy: it loads conftest files from the root of the test tree and from every folder along the path to that file. For example, for tests/admin/foo.yml it will load tests/conftest.yml and tests/admin/conftest.yml if they exist, and merge their fixtures (with override semantics) before running the tests in foo.yml.
So a run with a single file sees the same set of fixtures as when that file is run as part of the full suite (e.g. rasa test e2e tests/). You do not need to copy or re-define fixtures into the single file just to run it in isolation; fixture resolution is the same in both cases.
Example layout:
tests/conftest.yml
tests/ can then reference default_user in their test cases without defining it locally.
Fixture override semantics
Fixtures are resolved in a fixed order; a definition that appears later in the hierarchy overrides one with the same name from a parent scope:- Root — Fixtures from the root conftest (e.g.
tests/conftest.yml). - Folder — Fixtures from folder-level conftest files along the path to the test file (closer folders override parent folders).
- File — Fixtures defined in the test case file itself.
- Within a single file — Duplicate fixture names are not allowed. The runner reports an error if the same fixture name appears more than once in one file (test case file or conftest).
- Across files — The same fixture name in different files is allowed: the definition that wins is the one closest to the test file (file > folder conftest > root conftest).
Mocking Datetime in LLM Prompts
New in 3.15The
mocked_datetime slot for testing datetime-aware LLM components is available starting from Rasa 3.15.CompactLLMCommandGenerator,
SearchReadyLLMCommandGenerator,
EnterpriseSearchPolicy, and ReAct sub-agents),
you can use the mocked_datetime slot to provide a fixed datetime value for deterministic testing.
The mocked_datetime slot is a built-in slot that, when set in a fixture, overrides the actual current time for all datetime-aware components during that test case execution.
This ensures that tests are deterministic and don’t depend on when they are run, and that the datetime context included in LLM prompts is consistent across test runs.
Format Requirements
Themocked_datetime slot value must be provided as a string in ISO 8601 format. The following formats are supported:
-
ISO 8601 with timezone (recommended)
- Format:
YYYY-MM-DDTHH:MM:SS±HH:MM - Example:
"2025-01-15T14:30:45+00:00"# UTC - Example:
"2025-01-15T14:30:45-05:00"# EST - Example:
"2025-12-25T14:45:30+02:00"# CEST
- Format:
-
ISO 8601 naive (converted to UTC)
- Format:
YYYY-MM-DDTHH:MM:SS - Example:
"2025-01-15T14:30:45"
- Format:
-
Date only (time set to 00:00:00 UTC)
- Format:
YYYY-MM-DD - Example:
"2025-01-15"
- Format:
-
Space-separated (converted to UTC)
- Format:
YYYY-MM-DD HH:MM:SS - Example:
"2025-01-15 14:30:45"
- Format:
Example Usage
tests/datetime-tests.yml
Validation
The e2e test runner validates themocked_datetime value before test execution. If the value is invalid (not a string, wrong format, or invalid date/time), a ValidationError is raised with a clear error message indicating the expected format.
Invalid examples:
When to Use
Use themocked_datetime slot when:
- Testing datetime-dependent behavior (e.g., “today”, “tomorrow”, “next week”)
- Testing timezone-specific functionality
- Ensuring deterministic test results regardless of when tests are run
- Testing edge cases (midnight, year boundaries, etc.)
The
mocked_datetime slot only affects components that have include_date_time enabled. If a component has include_date_time: false, it will not use the mocked datetime value.Metadata on User Messages
This feature is only relevant when you have used custom connectors with your assistant and have passed extra information from your front end in your custom actions using themetadata key of your user message and want to properly test the conversation flow based on the metadata provided at runtime.
Please see the Metadata on messages section of the custom connectors documentation for more information.
Using Metadata is an optional feature that enables the testing of interactions that are dynamically influenced by external metadata
such as API response headers, middleware communications, or other contextual information.
The metadata key at the top level of your test case configuration consists of a list of metadata names, each of which must be unique.
These metadata names correspond to key-value pairs of metadata. When all user steps in a test case need predefined metadata,
you can reference the metadata name within the test case definition by adding it to the metadata key.
In addition to this, you can also use the metadata key in each user step to provide additional metadata.
This will merge with the test case level metadata before being passed to the UserMessage object.
In case of a conflict between the metadata provided in the user step and that of the test case during a merge operation,
the
user step metadata takes precedence and will override the one provided by the test case.tests/metadata-tests.yml
test_standard_booking test case will have only the metadata user_info with the exception of the third user step,
which will have the metadata device_info in addition to the user_info metadata.
Also, only the first user step in the test_mood_great test case will have the user_info metadata, while other user steps have no metadata.
Stubbing Custom Actions
You can stub regular custom actions in your test cases by defining thestub_custom_actions key at the top level of your test case file.
This allows you to simulate the execution of a custom action without actually running the action server.
The stub_custom_actions key consists of a dictionary of custom action names that you want to stub.
The value of each custom action name is a dictionary of expected events and responses.
This represents what the custom action would return and must follow the same format that the action server would return.
For example:
stub-tests.yml
test_case_id::action_name for the custom action name to differentiate between these stubs.
For example:
stub-multiple-tests.yml
The current version of the stubbing feature does not support the stubbing
of slot validation custom actions.
Limitations
End-to-end testing is a powerful tool for conducting thorough assessments of your conversational AI system. However, it does come with certain limitations that are important to consider. These limitations are as follows:Dependency on events and the tracker store
End-to-end testing heavily relies on the availability of specific event types in the tracker store. In particular, it requires the presence of events such asBotUttered, UserUttered, and SlotSet to execute tests effectively.
If your test scenario involves actions or events that do not generate these specific events,
the testing algorithm is not able to evaluate them.
Order of test steps and events
It is essential to structure your test cases to closely mimic real conversations to avoid potential issues. The test runner works by running theuser steps and capturing the events generated by the bot from the tracker store,
after which it will compare the events generated by the bot with the expected events be it bot or slot test steps.
It’s best to avoid creating test cases with mupltiple user steps followed by bot events, as it will only evaluate events created from the last user step.
faulty-tests.yml
bot, utter and slot steps which follow a user step is not important.
The test case will pass as long as the bot, utter and slot events are executed after the user step.
Testing the start of a conversation
The evaluation of actual events against the defined expected test steps begins after theaction_session_start action and it’s advisable to start the test with a user step.
However it is possible to test before the first user utterance when the action_session_start has been customized.
tests/e2e_test_cases.yml