Overview
Where, Why, How?
The preferred method of identifying objects within a test is via the testID
prop that is commonly seen on the majority of our components. We can technically get by without referencing components via test ID, but for readability and ease of use, this is the optimal method in both unit and E2E testing environments. There are a variety of points to consider regarding test ID and their usage:
- We're shifting to a Page Object Model design pattern for test ID moving forward. Rather than naming each test ID on the component itself, you should instead declare them as a
constant
inside of anenum
within their own file, grouping ID based on context area. These should then be imported into the file that you need the ID for, instead of just inserting the ID as a string within the prop. Using a POM helps to ensure that changes to one ID will be respected amongst all of its usages, and makes the task of finding ID themselves a lot less tiresome. - These
enum
should live within<feature/component>/utils/test-id/yourTestIdFile.ts
of each feature/component that they relate to. The idea behind a universal location per component is to ensure that they can be found easily regardless of where you are in app. Keep in mind that when importing a test ID file into a test, you will have to reference the file itself, and not the barrel file:
Eg. You will need to use:
import { featureTestIds } from '@app/features/group-mode/utils/testIds';
Instead of:
import { featureTestIds } from '@feature/group-mode';
- Test ID should be unique in name where it is feasible for you to do so. Trying to match elements based on test ID when multiple exist in the render tree can often lead to issues, and attempting to filter through a list of test ID that have duplicate names via index leads to poor readability with what a test is trying to achieve.
- Test ID naming convention should be in
kebab-case
. Our original convention wassnake_case
, but we are making an active effort to align all ID on the platform to kebab moving forward. If you have time when writing your test, please update those that you can that are associated with the test that you are writing. Please keep in mind when doing so that what you alter will likely have a ripple effect on a variety of different tests that are dependent on the ID you've changed. Check thoroughly for other usages of what you change before proceeding, particularly regarding unit tests. - Test ID should be named appropriately for the context they exist within. Try and include the feature/component name within the ID so that it can be easily recognised by anyone that has to use it.
- Avoid stuttering when declaring your
constant
within theenum
file. Theenum
itself provides context for what the test ID relates to, so you don't have to declare theconstant
in a manner that also reflects the context area. Eg. Yourenum
is namedPreferenceCentreTestId
, so if you needed an ID for some text in that context area, rather than naming theconstant
within itPreferenceCentreToggleText
, resulting in a complete ID when imported ofPreferenceCentreTestId.PreferenceCentreToggleText
, you would just name yourconstant
asToggleText
, so that your full ID isPreferenceCentre.ToggleText
. Your string for the test ID itself should still be context sensitive (preference-centre-toggle-text). - When your ID is dependent on other data before it can be generated (Eg. You have a list of items, and want each item to have a test ID prefix that is identical, but a suffix that differs to make them unique), avoid generating a test ID name based on an index. Indexes can change as the data shifts, causing your ID names to shift as well, resulting in unnecessary re-renders of a component/screen that can easily be avoided by instead using something static to identify each item (A transaction ID? An item's name? Check what you have available when writing).