Table of contents : Table of Contents About the Author About the Technical Reviewer Acknowledgments Foreword Introduction Chapter 1: Creating a Barebones Test Runner What Is an Entrypoint? The First Stage of Automated Test Enlightenment The Second Stage of Automated Test Enlightenment The Inner Workings of a Unit Test Runner The Third Stage of Automated Test Enlightenment Cloning the Project Repository Creating an NPM Project for the Test Runner Setting Package Configuration Creating the Test Runner Entrypoint Making the Package Available for Use Using the Sample Application Project npm unlink Update the Test Runner to Run Our Test Suite Verify That It Works by Breaking a Test Catch Exceptions from the Await Call Committing to Git Discussion Questions Summary Chapter 2: Building a Function to Represent a Test Case The it Function Common Test Verbs Using the it Function to Group and Describe Test Cases Handling Exceptions Printing Test Descriptions Support CI with Correct Exit Codes Summarizing a Test Run Exercises Summary Chapter 3: Grouping Tests The Basics of Unit Test Organization A Starting Point for describe Rethinking Test Output Printing a Pass/Fail Response for Each Test Ending a Test Report with Test Failure Details Saving Test Context Information Supporting Nested describe Blocks Exercises Summary Chapter 4: Promoting Conciseness with Shared Setup and Teardown The Arrange, Act, Assert Pattern Arrange Act Assert Why Is This Pattern Important? Introducing the beforeEach Function Applying beforeEach Blocks to Our Test Refactoring describeStack to an Object Defining beforeEach Updating the Sample Application Defining afterEach Generalizing beforeEach Generalizing invokeBefores Exercise Discussion Question Summary Chapter 5: Improving Legibility with Expectations and Matchers Using Matchers for Clarity and Reuse Building the First Matcher: toBeDefined Creating an Error Subtype Allowing Multiple Failures per Test Making a Mess Testing Your Solution Exercises Discussion Questions Summary Chapter 6: Formatting Expectation Errors Utilizing Stack Traces with Testing Workflows Building stackTraceFormatter Joining Up Our Formatter with the Runner Exercises Discussion Questions Summary Chapter 7: Automatically Discovering Test Files Development Workflows and Test Runners What About Watch Mode? Discovering Files Running a Single File Exercises Discussion Question Summary Chapter 8: Focusing on Specific Tests The Refactor Workflow Introducing a Parse Step Implementing the Parse Phase Parsing the describe Function Adding the it Function Adding the beforeEach and afterEach Functions Implementing the Run Phase The Global currentTest Variable Updating the Runner Moving the expect Function Adding the Focus Functions Filtering Tests Exercises Discussion Question Summary Chapter 9: Supporting Asynchronous Tests Event Loops in Runtime Environments Synchronicity and the Test Runner Waiting for Promise Completion Testing It Out Catching Exceptions Timing Out Tests After a Period of Time with the it.timesOutAfter Modifier Testing It Out Exercise Discussion Questions Summary Chapter 10: Reporting The Observer Pattern, in a Half-Baked Style Adding an Event Dispatcher Dispatching a Begin Suite Event Dispatching a Test Finished Event Adding finishedTestRun Getting Rid of Failures and Successes Exercises Summary Chapter 11: Shared Examples Methods of Reuse Implementing a Shared Example Repository Importing Shared Examples Exercise Discussion Questions Summary Chapter 12: Tagging Tests Another Way of Slicing Tests Thinking Through Design Options Jest’s Approach Supporting Polymorphic Calls to Test Functions Filtering Test Runs Using the tags Property Reading Tags from the Process Arguments Adding Tags to the Sample Application Exercises Discussion Question Summary Chapter 13: Skipping Tests Taming the Test Runner Adding the it.skip Modifier Testing It Out Supporting Empty-Body describe and it Calls Exercises Discussion Question Summary Chapter 14: Randomizing Tests Test Runner Use Cases Randomizing Tests in CI Environments Randomizing Tests on Developer Machines Adding the Flag Testing It Out Exercises Discussion Question Summary Chapter 15: Deep Equality and Constraining Matchers How Are Constraining Functions Useful? Implementing the equals Function Checking if Two Arrays Have Equal Size Checking if Two Objects Have Equal Keys Recursively Checking Element Equality Implementing the contains Constraint Exercises Discussion Questions Summary Chapter 16: Test Doubles How Are Test Doubles Useful? Spies and Stubs Adding the New Tests Implementing the spy Function Implementing the toBeCalledWith Matcher Exercises Discussion Questions Summary Chapter 17: Module Mocks How Are Module Mocks Useful? The Module Mock API Implementing the Mock Registry Implementing the Node Loader Adding the New Bin Script Bypassing the Module Cache Creating a Forwarding Reporter Defining the Worker Thread Entrypoint Updating the Test Runner to Use Worker Threads Changing Reported Test Objects to Be Serializable Exercises Discussion Question Summary