Search by Algolia
How personalization boosts customer engagement
e-commerce

How personalization boosts customer engagement

You land on your favorite retailer’s website, where everything seems to be attractively arranged just for you. Your favorite ...

Jon Silvers

Director, Digital Marketing

What is retail analytics and how can it inform your data-driven ecommerce merchandising strategy?
e-commerce

What is retail analytics and how can it inform your data-driven ecommerce merchandising strategy?

There is such tremendous activity both on and off of retailer websites today that it would be impossible to make ...

Catherine Dee

Search and Discovery writer

8 ways to use merchandising data to boost your online store ROI
e-commerce

8 ways to use merchandising data to boost your online store ROI

New year, new goals. Sounds positive, but looking at your sales data, your revenue and profit aren’t so hot ...

John Stewart

VP, Corporate Communications and Brand

Algolia DocSearch + Astro Starlight
engineering

Algolia DocSearch + Astro Starlight

What is Astro Starlight? If you're building a documentation site, your content needs to be easy to write and ...

Jaden Baptista

Technical Writer

What role does AI play in recommendation systems and engines?
ai

What role does AI play in recommendation systems and engines?

You put that in your cart. How about this cool thing to go with it? You liked that? Here are ...

Catherine Dee

Search and Discovery writer

How AI can help improve your user experience
ux

How AI can help improve your user experience

They say you get one chance to make a great first impression. With visual design on ecommerce web pages, this ...

Jon Silvers

Director, Digital Marketing

Keeping your Algolia search index up to date
product

Keeping your Algolia search index up to date

When creating your initial Algolia index, you may seed the index with an initial set of data. This is convenient ...

Jaden Baptista

Technical Writer

Merchandising in the AI era
e-commerce

Merchandising in the AI era

For merchandisers, every website visit is an opportunity to promote products to potential buyers. In the era of AI, incorporating ...

Tariq Khan

Director of Content Marketing

Debunking the most common AI myths
ai

Debunking the most common AI myths

ARTIFICIAL INTELLIGENCE CAN’T BE TRUSTED, shouts the headline on your social media newsfeed. Is that really true, or is ...

Vincent Caruana

Senior Digital Marketing Manager, SEO

How AI can benefit the retail industry
ai

How AI can benefit the retail industry

Artificial intelligence is on a roll. It’s strengthening healthcare diagnostics, taking on office grunt work, helping banks combat fraud ...

Catherine Dee

Search and Discovery writer

How ecommerce AI is reshaping business
e-commerce

How ecommerce AI is reshaping business

Like other modern phenomena such as social media, artificial intelligence has landed on the ecommerce industry scene with a giant ...

Vincent Caruana

Senior Digital Marketing Manager, SEO

AI-driven smart merchandising: what it is and why your ecommerce store needs it
ai

AI-driven smart merchandising: what it is and why your ecommerce store needs it

Do you dream of having your own personal online shopper? Someone familiar and fun who pops up every time you ...

Catherine Dee

Search and Discovery writer

NRF 2024: A cocktail of inspiration and innovation
e-commerce

NRF 2024: A cocktail of inspiration and innovation

Retail’s big show, NRF 2024, once again brought together a wide spectrum of practitioners focused on innovation and transformation ...

Reshma Iyer

Director of Product Marketing, Ecommerce

How AI-powered personalization is transforming the user and customer experience
ai

How AI-powered personalization is transforming the user and customer experience

In a world of so many overwhelming choices for consumers, how can you best engage with the shoppers who visit ...

Vincent Caruana

Senior Digital Marketing Manager, SEO

Unveiling the future: Algolia’s AI revolution at NRF Retail Big Show
algolia

Unveiling the future: Algolia’s AI revolution at NRF Retail Big Show

Get ready for an exhilarating journey into the future of retail as Algolia takes center stage at the NRF Retail ...

John Stewart

VP Corporate Marketing

How to master personalization with AI
ai

How to master personalization with AI

Picture ecommerce in its early days: businesses were just beginning to discover the power of personalized marketing. They’d divide ...

Ciprian Borodescu

AI Product Manager | On a mission to help people succeed through the use of AI

5 best practices for nailing the ecommerce virtual assistant user experience
ai

5 best practices for nailing the ecommerce virtual assistant user experience

“Hello there, how can I help you today?”, asks the virtual shopping assistant in the lower right-hand corner ...

Vincent Caruana

Senior Digital Marketing Manager, SEO

Add InstantSearch and Autocomplete to your search experience in just 5 minutes
product

Add InstantSearch and Autocomplete to your search experience in just 5 minutes

A good starting point for building a comprehensive search experience is a straightforward app template. When crafting your application’s ...

Imogen Lovera

Senior Product 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