12

The philosophy behind the react-testing-library makes sense to me, but I am struggling to apply it to css properties.

For example, let's say I have a simple toggle component that shows a different background color when clicked:

import React, { useState } from "react";
import "./Toggle.css";

const Toggle = () => {
  const [ selected, setSelected ] = useState(false);
  return (
    <div className={selected ? "on" : "off"} onClick={() => setSelected(!selected)}>
      {selected ? "On" : "Off"}
    </div>
  );
}

export default Toggle;
.on {
  background-color: green;
}

.off {
  background-color: red;
}

How should I test this component? I wrote the following test, which works for inline component styles, but fails when using css classes as shown above.

import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import Toggle from "./Toggle";

const backgroundColor = (element) => window.getComputedStyle(element).backgroundColor;

describe("Toggle", () => {
  it("updates the background color when clicked",  () => {
    render(<Toggle />);
    fireEvent.click(screen.getByText("Off"));
    expect(backgroundColor(screen.getByText("On"))).toBe("green");
  });
});

2 Answers 2

4

So that's not what unit or integration test frameworks do. They only test logic.

If you want to test styling then you need an end-to-end/snapshot testing framework like Selenium.

Sign up to request clarification or add additional context in comments.

2 Comments

This react-testing-library example test asserts that a button is disabled. I don't see much of a difference between that assertion and the one I'm doing - do you? I would not test most styling in my unit/integration tests, but the example in my question feels different to me. Do you have any recommended reading on this topic?
There's a huge different, actually. Checking for disabled is checking for an attribute being added -- this is logic. What you're trying to do is check non-inline style. If you would not test your styling in your unit/integration tests, why are you trying to see if an element is green? That's a styling test. While you can test inline style, that is because it is styles attached to the element via attribute. CSS requires a browser-like environment of matching a style sheet to the HTML. This is just basic HTML/CSS stuff. Unless you load the CSS (which a unit test won't) the style can't be found.
0

For making sure the styling is okay, I prefer snapshot testing. How about firing the event and taking snapshots for both states/cases. Here is what it would look like:

import React from 'react'
import {render} from '@testing-library/react'

 it('should take a snapshot when button is toggled', () => {
    const { asFragment } = render(<App />)
    // Fire the event 
    expect(asFragment(<App />)).toMatchSnapshot()
   })
});

2 Comments

That gives me the css class name, but it does not allow me to check the underlying css properties. Here is the snapshot I got: <DocumentFragment><div class="on">On</div></DocumentFragment>
Personally I would be okay with just testing if that class is set to on since what I am really testing is if there is a theme change on toggle. Tomorrow if the on class styling changes and I want a red instead of a green, it shouldn't break the test for the toggle logic. But as mentioned here stackoverflow.com/questions/47550435/… and by Devildude, you might have to use inlline styles or a css in js library to get the styles showing up in the snapshot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.