Search by Algolia
An introduction to transformer models in neural networks and machine learning
ai

An introduction to transformer models in neural networks and machine learning

What do OpenAI and DeepMind have in common? Give up? These innovative organizations both utilize technology known as transformer models ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

What’s the secret of online merchandise management? Giving store merchandisers the right tools
e-commerce

What’s the secret of online merchandise management? Giving store merchandisers the right tools

As a successful in-store boutique manager in 1994, you might have had your merchandisers adorn your street-facing storefront ...

Catherine Dee

Search and Discovery writer

New features and capabilities in Algolia InstantSearch
engineering

New features and capabilities in Algolia InstantSearch

At Algolia, our business is more than search and discovery, it’s the continuous improvement of site search. If you ...

Haroen Viaene

JavaScript Library Developer

Feature Spotlight: Analytics
product

Feature Spotlight: Analytics

Analytics brings math and data into the otherwise very subjective world of ecommerce. It helps companies quantify how well their ...

Jaden Baptista

Technical Writer

What is clustering?
ai

What is clustering?

Amid all the momentous developments in the generative AI data space, are you a data scientist struggling to make sense ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

What is a vector database?
product

What is a vector database?

Fashion ideas for guest aunt informal summer wedding Funny movie to get my bored high-schoolers off their addictive gaming ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

Unlock the power of image-based recommendation with Algolia’s LookingSimilar
engineering

Unlock the power of image-based recommendation with Algolia’s LookingSimilar

Imagine you're visiting an online art gallery and a specific painting catches your eye. You'd like to find ...

Raed Chammam

Senior Software Engineer

Empowering Change: Algolia's Global Giving Days Impact Report
algolia

Empowering Change: Algolia's Global Giving Days Impact Report

At Algolia, our commitment to making a positive impact extends far beyond the digital landscape. We believe in the power ...

Amy Ciba

Senior Manager, People Success

Retail personalization: Give your ecommerce customers the tailored shopping experiences they expect and deserve
e-commerce

Retail personalization: Give your ecommerce customers the tailored shopping experiences they expect and deserve

In today’s post-pandemic-yet-still-super-competitive retail landscape, gaining, keeping, and converting ecommerce customers is no easy ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

Algolia x eTail | A busy few days in Boston
algolia

Algolia x eTail | A busy few days in Boston

There are few atmospheres as unique as that of a conference exhibit hall: the air always filled with an indescribable ...

Marissa Wharton

Marketing Content Manager

What are vectors and how do they apply to machine learning?
ai

What are vectors and how do they apply to machine learning?

To consider the question of what vectors are, it helps to be a mathematician, or at least someone who’s ...

Catherine Dee

Search and Discovery writer

Why imports are important in JS
engineering

Why imports are important in JS

My first foray into programming was writing Python on a Raspberry Pi to flicker some LED lights — it wasn’t ...

Jaden Baptista

Technical Writer

What is ecommerce? The complete guide
e-commerce

What is ecommerce? The complete guide

How well do you know the world of modern ecommerce?  With retail ecommerce sales having exceeded $5.7 trillion worldwide ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

Data is king: The role of data capture and integrity in embracing AI
ai

Data is king: The role of data capture and integrity in embracing AI

In a world of artificial intelligence (AI), data serves as the foundation for machine learning (ML) models to identify trends ...

Alexandra Anghel

Director of AI Engineering

What are data privacy and data security? Why are they  critical for an organization?
product

What are data privacy and data security? Why are they critical for an organization?

Imagine you’re a leading healthcare provider that performs extensive data collection as part of your patient management. You’re ...

Catherine Dee

Search and Discovery writer

Achieving digital excellence: Algolia's insights from the GDS Retail Digital Summit
e-commerce

Achieving digital excellence: Algolia's insights from the GDS Retail Digital Summit

In an era where customer experience reigns supreme, achieving digital excellence is a worthy goal for retail leaders. But what ...

Marissa Wharton

Marketing Content Manager

AI at scale: Managing ML models over time & across use cases
ai

AI at scale: Managing ML models over time & across use cases

Just a few years ago it would have required considerable resources to build a new AI service from scratch. Of ...

Benoit Perrot

VP, Engineering

How continuous learning lets machine learning  provide increasingly accurate predictions and recommendations
ai

How continuous learning lets machine learning provide increasingly accurate predictions and recommendations

What new data points have you learned lately? Learning is never ending (hence the phrase “lifelong learning”), so chances are ...

Vincent Caruana

Sr. SEO Web Digital Marketing Manager

Looking for something?

facebookfacebooklinkedinlinkedintwittertwittermailmail

React was designed to solve one problem—how to build applications with data that changes over time. Considering the as-you-type search experience offered by Algolia wherein whole results pages, hits and refinement links alike, are updated at each keystroke, React was the obvious choice when we needed a tool to build out our new library of UI widgets: instantsearch.js.

We quickly struggled, however, with the unit test best practices for React components. We jumped from Github issues in facebook/react to blog posts and discuss.reactjs.org but couldn’t find a clear unit testing strategy.

Now that we’re happy with our testing stack, we wanted to share it with the community to hopefully make your testing process a bit easier. Feel free to also check out the unit testing tips we shared a few months ago.

How to test a React component

Before digging into the whole testing stack, how do we test a React component?

2015-10-20-140040_836x437_scrot

If you search for “React unit testing”, you’ll quickly find the popular React discussion—What’s the preferred way to test React.js components? In the thread, React developer Ben Alpert advises testing React components using a technique known as shallow rendering.

Here’s an example of a Button and a Label component tested with mocha:

And here is the output when you run it:

2015-10-20-150031_890x197_scrotWhat about failing test cases? Let’s make it fail by changing our test:

2015-10-20-150207_1061x621_scrotNot too bad. Shallow rendering provides a way to render a React element only one level deep. This means that if you have children elements (like Label in our Button), it will not trigger their render methods. Very nice for unit testing!

The shallow rendering technique is simple to use and well suited for unit testing as it takes a React Element as INPUT and produces a React Element as OUTPUT.

There are other techniques available, but this is the currently recommended one and we expect (?) the React team to develop more tools around it in the future.

But wait, it’s not over! Did you see that diff? You passed some nice expected JSX (<div><Label name=”Marie” /></div>), and all you got was a weird object output diff.

This is because JSX is transpiled to a React.createElement call that then returns a React element (a JavaScript object). So when doing expect(something).toEqual(somethingElse), you are just comparing two JavaScript objects.

It would be better to get something like this:

2015-10-20-152034_977x396_scrotLet’s make it happen! OK, we need a bit of tooling to get there.

What is the rackt team using?

After we found out about shallow rendering, we needed a good stack to make assertions and run the tests. We decided to have a look at what rackt, the Github org responsible for react-router and redux (two very popular react libraries) was using. After all, the closer you are to the tools of your community, the easier it is to get contributions.

The rackt team is using mochajs/mocha to run the tests and mjackson/expect to write assertions. They also follow the facebook/jest convention of putting tests next to the files they are testing:

2015-10-20-154505_742x439_scrot

Introducing expect-jsx

After choosing mjackson/expect as our assertion library and mochajs/mocha as our test runner, we wanted better JSX diffs instead of long object diffs when our tests were failing.

We asked the React community how to do this and got some great feedback. In fact, another assertion library already did it—bruderstein/unexpected-react-shallow. alexlande/react-to-jsx was also a candidate for implementing the JSX string diff in the expect assertion library.

Unfortunately, those libraries were not meeting our expectations. So…we built algolia/expect-jsx.

Let’s enhance our previous test with this new module:

expect-jsx transforms the passed React elements to JSX strings to nicely compare them. This seems a rather naive approach, but this is completely OK for unit testing.

Using expect-jsx will save you a good amount of time and spare you from having to write things like  expect(result.props.children[0].props.children.className).toEqual(‘U mad?’);

expect-jsx is based on algolia/react-element-to-jsx-string. This means that if you’re using tape, chaijs or jasmine, you can easily build the same assertions goodness within a day and publish it to npm.

Since we released react-element-to-jsx-string, developers have implemented JSX diff in multiple assertion libraries:

Warning: If you use Karma runner to launch mocha tests within browsers, you will not have any nice object or string diff. This is currently an issue in the html-reporter.

Simulating events like onClick

As of today, the shallow rendering technique does not support simulating clicks using React test utilities Simulate.

This means you have to resort to directly calling the underlying function of your handlers props. Doing so doesn’t introduce any test-specific nonsense, as it’s the same thing Simulate would do in the end.

Let’s change our Button component to illustrate this:

Our test now looks like:

As you can see on line 24, we’re just calling the props.onClick handler directly to check that our custom handler has been called properly. Easy, right?

Well, that’s the way we unit test our component handlers. If you have a better solution, leave it in the comments!

Testing using references

Shallow rendering does not have access to any references you may have defined in your Component, so you cannot use them when testing with the shallow rendering technique. This is being investigated by the React team.

In the meantime test your refs dependent Components using the standard Test Utilities.

npm run test:watch

At Algolia, we try to minimize the entry cost to a project for any developer. All projects have an npm run test:watch task that we can use to TDD with a rapid feedback loop.

You can easily get one by adding the following to your package.json:

Your development workflow will then look like this:

lol

Where to go from here?

The whole code used in this article can be found at algolia/react-test-boilerplate.

If you need some DOM features in your tests, check out tmpvar/jsdom and rstacruz/mocha-jsdom.

If you need to run your tests in real browsers, you can use karma-runner or defunctzombie/zuul coupled with Sauce Labs or Browser Stack.

If you liked this post and are interested in a follow-up article about those subjects, leave a comment or tweet @algolia.

Happy coding!

Learn more

Update November 02 2015

We did a talk about this at ReactJS Paris, here are the slides:

Sources

About the author
Vincent Voyer

Engineering Manager

githublinkedintwitter

Start building for free

Create a full-featured search experience in no time.

Get started
Start building for free

Recommended Articles

Powered byAlgolia Algolia Recommend

How we updated our JS libraries for React Native
engineering

Alexandre Stanislawski

Harnessing API’s with React: a different approach
engineering

Alexandre Stanislawski

How to improve site search with Algolia A/B testing
e-commerce

Loise Mercier