Live data from Hacker News

Idiomatic React Testing Patterns

gist.github.com

11–20 of 28 posts

Re: Idiomatic React Testing Patterns

#11

I've found the best testing pattern is to test the interface of the component, not the implementation. This means treating the component as an opaque function with inputs (props) and outputs (the rendered result). Your tests just need to that verify that different prop values result in the DOM changes or callbacks that you expect.

Do you use any tools to make the assertions on the resulting DOM simpler?

What about any components that maintain internal state; do you just step them through the states and assert the DOM state as well?

Re: Idiomatic React Testing Patterns

#12

I've found the best testing pattern is to test the interface of the component, not the implementation. This means treating the component as an opaque function with inputs (props) and outputs (the rendered result). Your tests just need to that verify that different prop values result in the DOM changes or callbacks that you expect.

Agree 100%. However if you are using component state you will need to test how interactions impact rendering output on the next render pass. I wouldn't consider that implementation detail since you are only asserting against render output.

In the case of testing instance methods, this is definitely a special edge-case scenario, but actually one of the main reasons I put this together. They inevitably happen, but are rare and I tend to forget how to set those tests up.

To give you an idea of how we use this: our application is a "website designer" where the preview is rendered inside an iframe. We use a react component to push CSS changes directly into the iframe via document.styleSheets. Using instance method testing allows us to test the main output results of this functionality without having to render real iframes pointing to external server in our tests.

Re: Idiomatic React Testing Patterns

#13

In my experience, as long as you have a well tested data model and use proptypes/Flow/TypeScript, testing the components themselves becomes almost entirely irrelevant. However, I can see the utility of component testing if I were wrapping something like Ace editor or a jQuery plugin or something of that nature.

Do you use anything like Redux? When writing Redux state reducers and actions, it all seems so... simple. There's a lot of code like `return { ...currentState, newProp }` which seems too silly to test.

Re: Idiomatic React Testing Patterns

#14

I've found the best testing pattern is to test the interface of the component, not the implementation. This means treating the component as an opaque function with inputs (props) and outputs (the rendered result). Your tests just need to that verify that different prop values result in the DOM changes or callbacks that you expect.

I prefer this style of component test and tend to bring in jQuery as a test dependency to remove some of the complexity of the assertions (I'm not always up to date on the current DOM APIs).

I find the instance method unit test a bit unsatisfying. I'm not going to call an instance method of a component from outside of that component (maybe someone else is doing this - I'm just not sure what the use case is), so why would I do that in my test? I want to integrate through the instance method by poking at the DOM rather than calling the method directly.

Re: Idiomatic React Testing Patterns

#15

In my experience, as long as you have a well tested data model and use proptypes/Flow/TypeScript, testing the components themselves becomes almost entirely irrelevant. However, I can see the utility of component testing if I were wrapping something like Ace editor or a jQuery plugin or something of that nature.

Do you use anything like Redux? When writing Redux state reducers and actions, it all seems so... simple. There's a lot of code like `return { ...currentState, newProp }` which seems too silly to test.

I often leave off tests for strictly "synchronous" actions like `return { ...currentState, newProp }`. Most of my tests are for confirming that the right paths are taken for actions that trigger one or more async operations to ensure correct failure case handling.

Re: Idiomatic React Testing Patterns

#16

In my experience, as long as you have a well tested data model and use proptypes/Flow/TypeScript, testing the components themselves becomes almost entirely irrelevant. However, I can see the utility of component testing if I were wrapping something like Ace editor or a jQuery plugin or something of that nature.

Do you use anything like Redux? When writing Redux state reducers and actions, it all seems so... simple. There's a lot of code like `return { ...currentState, newProp }` which seems too silly to test.

JS tests like this are so stupid cheap that we still write them for even the most basic test. Not sure I'm convinced it's worth it yet and I might regret it the first time we refactor a larger reducer.

Re: Idiomatic React Testing Patterns

#17
post #9

From what Dan Abramov has been posting on Twitter recently, findDOMNode() is in the process of being deprecated, so rather than writing const component = ReactDOM.findDOMNode(TestUtils.renderIntoDocument( )); we should be writing let node; const component = TestUtils.renderIntoDocument( node = n}/> ); https://gist.github.com/gaearon/7f0e03d3028016bfabfad641720d...

Good to know, will update the examples when I have time. Not sure I'm a big fan of it though, doesn't seem as clear to a React noob what is going on with ref?

Re: Idiomatic React Testing Patterns

#18

In my experience, as long as you have a well tested data model and use proptypes/Flow/TypeScript, testing the components themselves becomes almost entirely irrelevant. However, I can see the utility of component testing if I were wrapping something like Ace editor or a jQuery plugin or something of that nature.

[deleted]

Re: Idiomatic React Testing Patterns

#19

In my experience, as long as you have a well tested data model and use proptypes/Flow/TypeScript, testing the components themselves becomes almost entirely irrelevant. However, I can see the utility of component testing if I were wrapping something like Ace editor or a jQuery plugin or something of that nature.

If your application has few or very simple interactions then this may make sense. If it does have complex interactions (I consider a text input updating a model field as complex) then I think tests are necessary, especially if working with a team. You want to know when you break things.

This becomes even more important if you're developing generic UI components that may be re-used in different scenarios throughout your app or company. These types of library components need to be well tested as they often have more complex interactions and are going to be used in potentially very different ways.

Re: Idiomatic React Testing Patterns

#20
It can be very helpful to define all the different states (as props) for the set of components you're building. The data can be static or the result of dynamic calls to API endpoints (both approaches have benefits and trade-offs). For instance, if you're building a page with a list of items and at most 10 should be shown at a time, you could define the empty state (0 items), the half-full (1-10 items) and the overloaded state (11+ items, requiring pagination). Then you can implement the actual UI.

When this is done (and you're happy with the way it looks), you can make your test suite iterate over each of the different states and capture a screenshot of the UI. When something changes, you will know (the test suite should diff it). This approach is obviously mostly for presentation rather than functionality.

The benefits are not limited to testing, this is also very helpful in development, since you could switch between different states very quickly without having to constantly change URLs (for different API results). One method is using a dropdown overlay (only present in the development build). It's also very helpful during code review.

Post reply on HN