📕
Dan Fitz's Notes
  • README
  • Ai
    • Supervised Machine Learning
      • Introduction To Machine Learning
      • Regression With Multiple Input Variables
      • Classification
  • Csharp
    • C Sharp Advanced
      • Generics
      • Delegates
      • Lambda Expressions
      • Events
    • C Sharp Fundamentals
      • Intro To C
      • Primitive Types And Expressions
      • Non Primitive Types
      • Control Flow
      • Arrays And Lists
      • Working With Dates
      • Working With Text
      • Working With Files
      • Debugging Applications
    • C Sharp Intermediate
      • Classes
      • Association Between Classes
      • Inheritance
      • Polymorphism
      • Interfaces
  • Java
    • Inheritance Data Structures Java
      • Inheritance Polymorphism Using Overriding And Access Modifiers
      • Abstract Classes And Debugging
      • File I O And Exceptions
      • Collections Maps And Regular Expressions
    • Intro To Java
      • Introduction To Java Classes And Eclipse
      • Unit Testing Arrays And Array Lists
      • Static Variables Methods And Polymorphism Using Overloading
  • Javascript
    • Algorithms Data Structures
      • Big O Notation
      • Analyzing Performance Of Arrays And Objects
      • Problem Solving Approach
      • Problem Solving Patterns
      • Recursion
      • Searching Algorithms
      • Bubble Selection And Insertion Sort
      • Merge Sort
      • Quick Sort
      • Radix Sort
      • Data Structures Introduction
      • Singly Linked Lists
      • Doubly Linked Lists
      • Stacks And Queues
      • Binary Search Trees
      • Tree Traversal
      • Binary Heaps
    • Complete Nodejs
      • Understanding Node.js
      • REST AP Is And Mongoose
      • API Authentication And Security
      • Node.js Module System
      • File System And Command Line Args
      • Debugging Node.js
      • Asynchronous Node.js
      • Web Servers
      • Accessing API From Browser
      • Application Deployment
      • Mongo DB And Promises
    • Complete React Native
      • Working With Content
      • Building Lists
      • Navigating Users Between Screens
      • State Management
      • Handling Screen Layout
      • Setting Up An App
      • More On Navigation
      • Advanced Statement Management With Context
      • Building A Custom Express API
      • In App Authentication
    • Epic React
      • React Fundamentals
      • React Hooks
      • Advanced React Hooks
      • Advanced React Patterns
      • React Performance
    • Fireship Firestore
      • Firestore Queries And Data Modeling Course
      • Model Relational Data In Firestore No SQL
    • Functional Light Javascript
      • Intro
      • Function Purity
      • Argument Adapters
      • Point Free
      • Closure
      • Composition
      • Immutability
      • Recursion
      • List Operations
      • Transduction
      • Data Structure Operations
      • Async
    • Js Weird Parts
      • Execution Contexts And Lexical Environments
      • Types And Operators
      • Objects And Functions
      • Object Oriented Java Script And Prototypal Inheritance
      • Defining Objects
    • Mastering Chrome Dev Tools
      • Introduction
      • Editing
      • Debugging
      • Networking
      • Auditing
      • Node.js Profiling
      • Performance Monitoring
      • Image Performance
      • Memory
    • React Complete Guide
      • What Is React
      • React Basics
      • Rendering Lists And Conditionals
      • Styling React Components
      • Debugging React Apps
      • Component Deep Dive
      • Building A React App
      • Reaching Out To The Web
      • Routing
    • React Testing
      • Intro To Jest Enzyme And TDD
      • Basic Testing
      • Redux Testing
      • Redux Thunk Testing
    • Serverless Bootcamp
      • Introduction
      • Auction Service Setup
      • Auction Service CRUD Operations
      • Auction Service Processing Auctions
    • Testing Javascript
      • Fundamentals Of Testing
      • Static Analysis Testing
      • Mocking Fundamentals
      • Configuring Jest
      • Test React Components With Jest And React Testing Library
    • Typescript Developers Guide
      • Getting Started With Type Script
      • What Is A Type System
      • Type Annotations In Action
      • Annotations With Functions And Objects
      • Mastering Typed Arrays
      • Tuples In Type Script
      • The All Important Interface
      • Building Functionality With Classes
    • Web Performance With Webpack
      • Intro
      • Code Splitting
      • Module Methods Magic Comments
  • Other
    • Algo Expert
      • Defining Data Structures And Complexity Analysis
      • Memory
      • Big O Notation
      • Logarithm
      • Arrays
      • Linked Lists
      • Hash Tables
      • Stacks And Queues
      • Strings
      • Graphs
      • Trees
    • Aws Solutions Architect
      • AWS Fundamentals IAM EC 2
    • Fundamentals Math
      • Numbers And Negative Numbers
      • Factors And Multiples
      • Fractions
    • Mysql Bootcamp
      • Overview And Installation
      • Creating Databases And Tables
      • Inserting Data
      • CRUD Commands
      • The World Of String Functions
      • Refining Our Selections
      • The Magic Of Aggregate Functions
    • Random Notes
      • Understanding React Hooks
  • Python
    • Data Analysis Using Python
      • Loading Querying And Filtering Data Using The Csv Module
      • Loading Querying Joining And Filtering Data Using Pandas
      • Summarizing And Visualizing Data
    • Intro To Python
      • Course Introduction Intro To Programming And The Python Language Variables Conditionals Jupyter Notebook And IDLE
      • Intro To Lists Loops And Functions
      • More With Lists Strings Tuples Sets And Py Charm
      • Dictionaries And Files
Powered by GitBook
On this page
  • Intro to Jest, Enzyme, and TDD
  • Test-Driven Development
  • Jest
  • Enzyme
  • Types of Test
  • Testing Tradeoffs
  1. Javascript
  2. React Testing

Intro To Jest Enzyme And TDD

Course outline:

  1. Intro to Jest and Enzyme

  2. Testing a simple React app (just using state)

  3. Redux

  • Testing connected Redux components

  • Testing action creators and reducers

  1. Testing Redux Thunk and Axios>

  2. Testing Redux Props and Action Creator Calls

  3. Hooks and Context (no redux)

  • Testing useState, useEffect, and useReducer

  • Testing simple context (app-level state)

  • Testing context with embedded state from provider

Intro to Jest, Enzyme, and TDD

The goal of this course is to teach you how to write unit and integration tests for React, Redux, hooks, and contexts using Jest and Enzyme.

react: 16.9.0

jest: 24.8.0

enzyme: 3.10.0

redux: 4.0.4

react-redux: 7.1.1

Test-Driven Development

The basic idea behind test-driven development is to write tests before the code.

This involves 3 steps:

  1. Write a shell function that you can call in your tests but which doesn't do anything.

  2. Write tests. By default, when you run them, you want them all to fail.

  3. Write the code that, one by one, make your tests pass.

This is also known as red-green testing: start all your tests in a red state and move them to green.

Pro tip: Always be suspicious of tests that you've never seen fail. You want to see that a test can fail.

Benefits of TDD

  1. Without TDD, any time you make changes, there's work you have to do to re-test the changes. With TDD, tests are already made for you, and you juse re-run them for free.

  2. You write better code.

  • Code is planned before written.

  • Code doesn't need to be refactored to be made testable. It's already written with testing in mind.

  • Fewer bugs because they're caught sooner.

  • You also take advantage of regression testing: the fact that old tests get re-run every time you make changes.

  • You have high code coverage--the percentage of source code that gets executed during testing--and therefore low chances of bugs slipping by undetected.

Jest

Watch mode

Adding a --watch flag when running jest keeps it running. Any time you make changes, it will re-run the relevant tests automatically in the terminal.

Note: Jest watches for changes based on changes since your last commit. That means it doesn't re-run every test but only the tests tied to the uncommitted files.

Test files

By default, jest knows a file is a test file if it ends with .test.js.

The basic structure of a test is this:

test('message about what you expect', () => {
  expect(a).toEqual(b) // jest assertion
})

test('this test will fail', () => {
  throw new Error
})

Jest determines a test to be a failure if an error is thrown during the execution of the callback.

Enzyme

Enzyme creates a virtual DOM for testing, which you need if you'll be doing testing without a browser.

Using ReactDOM under the hood, enzyme exposes an API with the following features:

  • jQuery-style selectors

  • Simulate simple events (examples: click, blur)

  • Shallow rendering: renders components one level deep at the parent with empty placeholders for children

    • Important to isolate your tests to the component itself (and not its children)

  • Access to props and state of component

Configuration

Enzyme with react and jest requires enzyme, enzyme-adapter-react-16 (if v16), and jest-enzyme.

Then you configure enzyme:

import Enzyme from 'enzyme'
import EnzymeAdapter from 'enzyme-adapter-react-16'

// Now Enzyme knows it's dealing with react
Enzyme.configure({ adapter: new EnzymeAdapter() })

How to test

To render a component, you use the shallow function, which returns what's called a shallow wrapper:

import { shallow } from 'enzyme'

test('jest test', () => {
  const wrapper = shallow(<Component />)

  // Prints a string representation of the virtual DOM
  console.log(wrapper.debug())
})

Types of Test

  • Unit tests test one particular piece of code (usually a function), making it very modular and isolated

  • Integration tests test how multiple units work together

  • Acceptance or end-to-end tests test how a user would actually interact with the app from start to finish

With jest and enzyme, this course focuses on unit tests and integration tests.

Testing Tradeoffs

When making tests, you want to keep these 2 goals in mind:

  1. Tests should be easy to maintain

  2. Failed tests should be easy to diagnose

Maintainability

In particular, tests should test behaviour, not implementation. That means when we refactor code, we usually don't have to rewrite the tests. Tests that have to be rewritten on refactor are called brittle.

For example, say that you want to test that an increment button increments a counter when clicked. Testing implementation might be testing if a particular function is invoked on button click. Testing behaviour would be testing if the button click displays an updated value in the DOM.

Easy diagnosis

Suppose that you're testing a shopping cart form where users can build their own custom t-shirt order: t-shirt style, size, colour, quantity, etc. A difficult-to-diagnose test would test the full results of the form after submission. However, this only tells you that something went wrong, but which step exactly? Now you have to spend time investigating. In contrast, an easy-to-diagnose test might check the internal state after each user action.

Tradeoffs

There is an innate tension between maintainability and easy diagnosis:

  • In order to easily diagnose what went wrong, your tests need to be more granular, which makes your tests focus more on implementation like function calls or state.

  • On the other hand, in order to minimize how often tests need to be refactored, you need to make your tests broad, which makes it harder to spot exactly what caused failure.

PreviousReact TestingNextBasic Testing

Last updated 3 years ago