Automated Testing with Styled Components
Styled Components can be great but there are some drawbacks as well. One of these drawbacks is automated testing is difficult due to the compile process of styled components.
TLDR:
Add a className attribute
Add and id attribute
Add a custom data attribute
The Problem
When Styled Components are rendered they have encoded names due to how they are compiled. That means you will find components with class names that look something like “iBnfBx“ cause that makes sense right? These names change every time they are compiled as well. This makes it hard to debug and even harder to write automated tests for.
Solutions
There are 3 easy solutions to this issue.
Add a className attribute
Add an id attribute
Add a custom data attribute
Adding a className Attribute
The first option is to add a class name attribute to your component. When you add a className attribute that class name will not be changed when the application is compiled. so you component would look something like this:
<TestComponent className="testComponentClass" />
This is a popular way to add things for test targeting and one that a lot of QA automation testers are used to using. This is also a great option if you want to be able to grab multiple components all at once as you can have multiple components with the same class name. This does mean however that another dev can easily add a class name to another component that is the same as yours which would then cause issues in your tests since it would then be targeting a component it wasn’t supposed to be testing. One way to combat that problem is to use ids.
Adding an id Attribute
The second option is to add an id attribute to your component. This will also not be changed when an application is compiled. Your component would look something like this:
<TestComponent id="testComponentId"/>
This is another popular way for test targeting a lot of QA automation testers are used to using this as well. This is a great option if you want to make sure that no other component would be targeted as you can only have on component with that id. This give a little more security that you are testing what you should be. It is also easy to add programmatically if your components are based on data that is being returned. For instance if you had a table that has rows of data from a database you can give each row an id easily based on the data’s id from the database. You can do this with className as well this structure just lends more to an id attribute. This however does not lend well to targeting multiple things. In this case to target multiple things you would have to create an array of different ids rather than targeting one name. If you are implementing id programmatically this can also make testing difficult as they will not be the same every time so that is something to keep in mind as well. It is still definitely doable it just depends on what you are testing
Adding a Custom Data Attribute
The last easy option is to add a custom data attribute. This can be named pretty much whatever you want but I usually go with “data-test”. You component would look something like this:
<TestComponent data-test="testComponent"/>
This is a less popular use as people don’t usually need them since their ids and class names they need for styling don’t usually change when they are compiled. However it is a solid choice to be considered. It acts like a lot like a class name. It as the same pros and cons but also has the added pro that it add a separation of concerns. You don’t need this for anything other than testing and using this option makes that obvious. It also makes it easier for the tester to know what to target for each thing rather than trying to look for a specific class that they can target.
They each have their pros and cons so you can make your own decision which works best for you and your team. I personally like the custom data attribute as this makes it obvious that the name is used for testing and nothing else and makes it easy for the person writing the tests to know what to target.
I hope this helps you weigh your options! happy coding!