@testing-library

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

 

 


HackYourFuture Copenhagen · November 20, 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 via 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

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

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