Testing
Learn how we test our code internally and how you should test integration with EUI components to ensure good test coverage and easy maintainability.
How we test our components
We maintain a large amount of integration and end-to-end tests suites for every component we develop. They ensure high coverage of most paths within our components, including accessibility features, and lets us know whenever we change something that may affect your applications.
Internally, we use Enzyme and React Testing Library for integration testing, Cypress for end-to-end component testing, as well as static code analysis and type checking tools that run automatically on every pull request. You can find them all in our GitHub repository.
All of these tests, including a manual code review and QA steps must pass before the changes are merged to confirm they're up to our standards.
How should you test views using EUI components?
Testing integration with 3rd-party UI libraries like EUI is slightly different from testing first-party components. In general, just like with any other dependency, you should not test implementation details like the exact DOM structure or class names. They're likely to change between versions and usually don't prove a component works correctly anyway, so it's best to skip these.
Instead, you should focus on testing your code and the integration with EUI components first.
Depending on your testing stack, integration tests might be written using React Testing Library (RTL),
and are meant to be low-level tests of components working together as expected. For example, if your component fetches
and displays processed data a certain way whenever an <EuiButton />
is clicked, you should write
a test that simulates a click on that button and verifies the data is actually fetched and displayed the way
you expect it to. Doing this will confirm your code integrates with <EuiButton />
correctly by passing
the right onClick
handler, and so that your handler function fetches and updates the data to display the right way.
On top of that, we also recommend writing end-to-end (e2e) tests that go through the flow just like a real user would. In addition to testing what integration tests do, they ensure a browser loads and executes your code properly as a whole, reacts to real user actions, makes needed network and API calls, and way more. You can use frameworks like Cypress, Selenium, Playwright, and more to write end-to-end tests for your application.
When written properly, integration and end-to-end tests will validate if the code you're shipping actually works for end users, and that the changes you introduce over time don't break the application. This means you can iterate faster and spend less time on manual testing.
Writing good tests isn't easy. This is why we've prepared a set of general and component-specific guidelines to help you in that process, and we strongly encourage you to read them. In case these aren't enough, we're here to help! Please reach out to us by opening a GitHub issue or discussion.
If you're an Elastic employee, we recommend reaching out on the #eui Slack channel first.
Choosing the right selectors
Whenever writing any kind of UI tests, choosing right selectors is the key to making tests reliable long-term.
We recommend using the data-test-subj
attributes (e.g., [data-test-subj="comboBoxSearchInput"]
),
ARIA role
attributes (e.g., [role="dialog"]
),
and other semantic queries for selectors whenever possible
to ensure they reference the same underlying element between versions.
You can find the list of available data-test-subj
and other attributes as well as what semantic query selectors
we recommend to use in component-specific testing documentation pages.
If you need to use a custom, non-semantic selector (e.g., div > span.title
or span:first-child
)
that's not a one-off, please open a GitHub issue, so we can add it,
or even better so - try adding it yourself and contribute to EUI by opening a pull request! 🎉