@testing-library

Or, how I learned to stop worrying about the DOM.

 

 


NewStore · August 11, 2020

Luís Rodrigues

 

goblindegook.com

Twitter @goblindegook

Testing the frontend
with confidence.

Browser Tests

  • Convenient
  • Fast
  • Maintainable
  • Robust

React + Enzyme

  • Convenient
  • Fast
  • Maintainable
  • Robust

Shallow rendering.

Diagram of a form component with a file upload subcomponent with side effects.
Diagram of a shallow rendered form component, the file upload subcomponent's effects aren't trigger.

Too easy to test implementation details.

  • Shallow rendering.
  • Querying by component name or properties.
  • Component instance state inspection.
  • Testing only with the browser.
  • Testing implementation details.

Slow

↕

Fast

Expensive

↕

Cheap

Cooperation

↕

Single responsibility

Big picture

↕

Detail

Loose

↕

Precise

Easy to refactor

↕

Hard to refactor

Hard to debug

↕

Easy to debug

The messy middle

“Write tests. Not too many. Mostly integration.”

Guillermo Rauch

“Integrated tests are a scam.”

J.B. Rainsberger

A unit test must run in isolation.

A unit test must be fast.

A unit test must focus on a ‘small’ part of the system.

Testing from the outside-in.

While writing tests, I focus on visible behaviour, not...

  • ...what subcomponents I’m going to need.
  • ...how they’re implemented.
  • ...who implements them.

Fake it till you break it

“Mocking is a code smell.”

Eric Elliot
  • 100% code coverage.
  • All tests are green.
  • The application is still broken.

You don’t need to test third-party components.

But maybe you should.

“The more your tests resemble the way your software is used, the more confidence they can give you.”

Kent C. Dodds

@testing-library

Like a browser test, but not

An API that mimics user interaction.

Less this


            $('div.login .btn-primary + a').click()
					

More this


							fireEvent.click(screen.getByText(/recover password/i))
          

get
getAll

query
queryAll

find
findAll

+

ByRole()
ByLabelText()
ByPlaceholderText()
ByText()
ByDisplayValue()
ByAltText()
ByTitle()

  1. getByRole()
  2. getByLabelText()
  3. getByPlaceholderText()
  4. getByText()
  5. getByDisplayValue()
  6. getByAltText()
  7. getByTitle()

Escape hatch

getByTestId()

React


            
					

Plain HTML


            
					

What you get back is DOM nodes.


							fireEvent.click(screen.getByText('Click me!'))
					

						
          

Encourages not testing implementation details.

Promotes good accessibility practices.

Concise and lightweight.
testing-playground.com

Frameworks

  • React (Native)
  • Vue
  • Angular
  • Preact
  • Svelte

Upgrades your testing tools

  • Cypress
  • Puppeteer
  • TestCafe
  • Delightful user-centric API.
  • Discourages testing implementation details.
  • Promotes creating accessible frontends.

Learn the tradeoffs.

Test with confidence.

That is all.

Thank you

 

goblindegook.com

Twitter @goblindegook