The Art of Unit Testing: with examples in JavaScript. 3 Ed

The Art of Unit Testing: with examples in JavaScript. 3 Ed

The Art of Unit Testing: with examples in JavaScript. 3 Ed
Автор: Khorikov Vladimir, Osherove Roy
Дата выхода: 2024
Издательство: Manning Publications Co.
Количество страниц: 289
Размер файла: 2,8 МБ
Тип файла: PDF
Добавил: codelibs
 Проверить на вирусы  Дополнительные материалы 

The Art of Unit Testing, Third Edition....1

Praise for the second edition....3

contents....9

foreword to the second edition....16

foreword to the first edition....18

preface....20

acknowledgments....22

about this book....23

Whats new in the third edition....23

Who should read this book....24

How this book is organized: A road map....24

Code conventions and downloads....25

Software requirements....25

liveBook discussion forum....25

Other projects by Roy Osherove....26

Other projects by Vladimir Khorikov....26

about the authors....27

about the cover illustration....28

Part 1Getting started....29

1 The basics of unit testing....31

1.1 The first step....33

1.2 Defining unit testing, step by step....33

1.3 Entry points and exit points....34

1.4 Exit point types....39

1.5 Different exit points, different techniques....40

1.6 A test from scratch....40

1.7 Characteristics of a good unit test....43

1.7.1 What is a good unit test?....43

1.7.2 A unit test checklist....44

1.8 Integration tests....45

1.9 Finalizing our definition....49

1.10 Test-driven development....50

1.10.1 TDD: Not a substitute for good unit tests....52

1.10.2 Three core skills needed for successful TDD....53

Summary....54

2 A first unit test....56

2.1 Introducing Jest....57

2.1.1 Preparing our environment....57

2.1.2 Preparing our working folder....57

2.1.3 Installing Jest....58

2.1.4 Creating a test file....58

2.1.5 Executing Jest....59

2.2 The library, the assert, the runner, and the reporter....61

2.3 What unit testing frameworks offer....62

2.3.1 The xUnit frameworks....64

2.3.2 xUnit, TAP, and Jest structures....64

2.4 Introducing the Password Verifier project....65

2.5 The first Jest test for verifyPassword....65

2.5.1 The Arrange-Act-Assert pattern....66

2.5.2 Testing the test....67

2.5.3 USE naming....67

2.5.4 String comparisons and maintainability....68

2.5.5 Using describe()....68

2.5.6 Structure implying context....69

2.5.7 The it() function....70

2.5.8 Two Jest flavors....70

2.5.9 Refactoring the production code....71

2.6 Trying the beforeEach() route....73

2.6.1 beforeEach() and scroll fatigue....75

2.7 Trying the factory method route....77

2.7.1 Replacing beforeEach() completely with factory methods....78

2.8 Going full circle to test()....80

2.9 Refactoring to parameterized tests....80

2.10 Checking for expected thrown errors....83

2.11 Setting test categories....84

Summary....85

Part 2Core techniques....87

3 Breaking dependencies with stubs....89

3.1 Types of dependencies....90

3.2 Reasons to use stubs....92

3.3 Generally accepted design approaches to stubbing....94

3.3.1 Stubbing out time with parameter injection....94

3.3.2 Dependencies, injections, and control....96

3.4 Functional injection techniques....97

3.4.1 Injecting a function....97

3.4.2 Dependency injection via partial application....98

3.5 Modular injection techniques....98

3.6 Moving toward objects with constructor functions....101

3.7 Object-oriented injection techniques....102

3.7.1 Constructor injection....102

3.7.2 Injecting an object instead of a function....104

3.7.3 Extracting a common interface....107

Summary....109

4 Interaction testing using mock objects....111

4.1 Interaction testing, mocks, and stubs....112

4.2 Depending on a logger....113

4.3 Standard style: Introduce parameter refactoring....115

4.4 The importance of differentiating between mocks and stubs....116

4.5 Modular-style mocks....117

4.5.1 Example of production code....118

4.5.2 Refactoring the production code in a modular injection style....119

4.5.3 A test example with modular-style injection....120

4.6 Mocks in a functional style....120

4.6.1 Working with a currying style....120

4.6.2 Working with higher-order functions and not currying....121

4.7 Mocks in an object-oriented style....122

4.7.1 Refactoring production code for injection....122

4.7.2 Refactoring production code with interface injection....124

4.8 Dealing with complicated interfaces....126

4.8.1 Example of a complicated interface....126

4.8.2 Writing tests with complicated interfaces....127

4.8.3 Downsides of using complicated interfaces directly....128

4.8.4 The interface segregation principle....129

4.9 Partial mocks....129

4.9.1 A functional example of a partial mock....129

4.9.2 An object-oriented partial mock example....130

Summary....131

5 Isolation frameworks....132

5.1 Defining isolation frameworks....133

5.1.1 Choosing a flavor: Loose vs. typed....133

5.2 Faking modules dynamically....134

5.2.1 Some things to notice about Jests API....136

5.2.2 Consider abstracting away direct dependencies....137

5.3 Functional dynamic mocks and stubs....137

5.4 Object-oriented dynamic mocks and stubs....138

5.4.1 Using a loosely typed framework....138

5.4.2 Switching to a type-friendly framework....140

5.5 Stubbing behavior dynamically....142

5.5.1 An object-oriented example with a mock and a stub....142

5.5.2 Stubs and mocks with substitute.js....144

5.6 Advantages and traps of isolation frameworks....145

5.6.1 You dont need mock objects most of the time....146

5.6.2 Unreadable test code....146

5.6.3 Verifying the wrong things....146

5.6.4 Having more than one mock per test....147

5.6.5 Overspecifying the tests....147

Summary....147

6 Unit testing asynchronous code....149

6.1 Dealing with async data fetching....150

6.1.1 An initial attempt with an integration test....151

6.1.2 Waiting for the act....152

6.1.3 Integration testing of asyncawait....152

6.1.4 Challenges with integration tests....153

6.2 Making our code unit-test friendly....153

6.2.1 Extracting an entry point....154

6.2.2 The Extract Adapter pattern....159

6.3 Dealing with timers....166

6.3.1 Stubbing timers out with monkey-patching....166

6.3.2 Faking setTimeout with Jest....167

6.4 Dealing with common events....169

6.4.1 Dealing with event emitters....169

6.4.2 Dealing with click events....170

6.5 Bringing in the DOM testing library....172

Summary....173

Part 3The test code....175

7 Trustworthy tests....177

7.1 How to know you trust a test....178

7.2 Why tests fail....178

7.2.1 A real bug has been uncovered in the production code....179

7.2.2 A buggy test gives a false failure....179

7.2.3 The test is out of date due to a change in functionality....180

7.2.4 The test conflicts with another test....180

7.2.5 The test is flaky....181

7.3 Avoiding logic in unit tests....181

7.3.1 Logic in asserts: Creating dynamic expected values....181

7.3.2 Other forms of logic....183

7.3.3 Even more logic....184

7.4 Smelling a false sense of trust in passing tests....184

7.4.1 Tests that dont assert anything....185

7.4.2 Not understanding the tests....185

7.4.3 Mixing unit tests and flaky integration tests....186

7.4.4 Testing multiple exit points....186

7.4.5 Tests that keep changing....188

7.5 Dealing with flaky tests....189

7.5.1 What can you do once youve found a flaky test?....191

7.5.2 Preventing flakiness in higher-level tests....191

Summary....192

8 Maintainability....193

8.1 Changes forced by failing tests....194

8.1.1 The test is not relevant or conflicts with another test....194

8.1.2 Changes in the production codes API....194

8.1.3 Changes in other tests....197

8.2 Refactoring to increase maintainability....201

8.2.1 Avoid testing private or protected methods....201

8.2.2 Keep tests DRY....203

8.2.3 Avoid setup methods....203

8.2.4 Use parameterized tests to remove duplication....204

8.3 Avoid overspecification....205

8.3.1 Internal behavior overspecification with mocks....205

8.3.2 Exact outputs and ordering overspecification....207

Summary....211

Part 4Design and process....213

9 Readability....215

9.1 Naming unit tests....216

9.2 Magic values and naming variables....217

9.3 Separating asserts from actions....218

9.4 Setting up and tearing down....219

Summary....220

10 Developing a testing strategy....222

10.1 Common test types and levels....223

10.1.1 Criteria for judging a test....224

10.1.2 Unit tests and component tests....224

10.1.3 Integration tests....225

10.1.4 API tests....226

10.1.5 E2EUI isolated tests....226

10.1.6 E2EUI system tests....227

10.2 Test-level antipatterns....227

10.2.1 The end-to-end-only antipattern....227

10.2.2 The low-level-only test antipattern....230

10.2.3 Disconnected low-level and high-level tests....232

10.3 Test recipes as a strategy....233

10.3.1 How to write a test recipe....233

10.3.2 When do I write and use a test recipe?....235

10.3.3 Rules for a test recipe....235

10.4 Managing delivery pipelines....236

10.4.1 Delivery vs. discovery pipelines....236

10.4.2 Test layer parallelization....237

Summary....239

11 Integrating unit testing into the organization....241

11.1 Steps to becoming an agent of change....241

11.1.1 Be prepared for the tough questions....242

11.1.2 Convince insiders: Champions and blockers....242

11.1.3 Identify possible starting points....243

11.2 Ways to succeed....244

11.2.1 Guerrilla implementation (bottom-up)....245

11.2.2 Convincing management (top-down)....245

11.2.3 Experiments as door openers....245

11.2.4 Get an outside champion....246

11.2.5 Make progress visible....247

11.2.6 Aim for specific goals, metrics, and KPIs....248

11.2.7 Realize that there will be hurdles....250

11.3 Ways to fail....250

11.3.1 Lack of a driving force....251

11.3.2 Lack of political support....251

11.3.3 Ad hoc implementations and first impressions....251

11.3.4 Lack of team support....252

11.4 Influence factors....252

11.5 Tough questions and answers....254

11.5.1 How much time will unit testing add to the current process?....254

11.5.2 Will my QA job be at risk because of unit testing?....255

11.5.3 Is there proof that unit testing helps?....256

11.5.4 Why is the QA department still finding bugs?....256

11.5.5 We have lots of code without tests: Where do we start?....256

11.5.6 What if we develop a combination of software and hardware?....257

11.5.7 How can we know we dont have bugs in our tests?....257

11.5.8 Why do I need tests if my debugger shows that my code works?....257

11.5.9 What about TDD?....257

Summary....257

12 Working with legacy code....259

12.1 Where do you start adding tests?....260

12.2 Choosing a selection strategy....262

12.2.1 Pros and cons of the easy-first strategy....262

12.2.2 Pros and cons of the hard-first strategy....262

12.3 Writing integration tests before refactoring....263

12.3.1 Read Michael Feathers book on legacy code....264

12.3.2 Use CodeScene to investigate your production code....264

Summary....264

appendixMonkey-patching functions and modules....266

A.1 An obligatory warning....266

A.2 Monkey-patching functions, globals, and possible issues....267

A.2.1 Monkey-patching a function the Jest way....269

A.2.2 Jest spies....269

A.2.3 spyOn with mockImplementation()....269

A.3 Ignoring a whole module with Jest is simple....270

A.4 Faking module behavior in each test....271

A.4.1 Stubbing a module with vanilla require.cache....272

A.4.2 Stubbing custom module data with Jest is complicated....274

A.4.3 Avoid Jests manual mocks....275

A.4.4 Stubbing a module with Sinon.js....275

A.4.5 Stubbing a module with testdouble....276

index....279

Symbols....279

A....279

B....280

C....280

D....280

E....281

F....281

G....282

H....282

I....282

J....282

K....283

L....283

M....283

N....284

O....284

P....284

Q....285

R....285

S....285

T....286

U....287

V....288

W....288

X....288

Unit testing is more than just a collection of tools and practices—it’s a state of mind! This bestseller reveals the master’s secrets for delivering robust, maintainable, and trustworthy code.Thousands of developers have learned to hone their code quality under the tutelage of The Art of Unit Testing. This revised third edition updates an international bestseller to reflect modern development tools and practices, as well as to cover JavaScript.

Inside The Art of Unit Testing, Third Edition you will learn how to:

  • Create readable, maintainable, and trustworthy tests
  • Work with fakes, stubs, mock objects, and isolation frameworks
  • Apply simple dependency injection techniques
  • Refactor legacy code with confidence
  • Test both frontend and backend code

Effective unit tests streamline your software development process and ensure you deliver consistent high-quality code every time. With practical examples in JavaScript and Node, this hands-on guide takes you from your very first unit tests all the way to comprehensive test suites, naming standards, and refactoring techniques. You’ll explore test patterns and organization, working with legacy code and even “untestable” code. The many tool-agnostic examples are presented in JavaScript and carefully designed so that they apply to code written in any language.

About the technology

The art of unit testing is more than just learning the right collection of tools and practices. It’s about understanding what makes great tests tick, finding the right strategy for each unique situation, and knowing what to do when the testing process gets messy. This book delivers insights and advice that will transform the way you test your software.

About the book

The Art of Unit Testing, Third Edition shows you how to create readable and maintainable tests. It goes well beyond basic test creation into organization-wide test strategies, troubleshooting, working with legacy code, and “merciless” refactoring. You’ll love the practical examples and familiar scenarios that make testing come alive as you read. This third edition has been updated with techniques specific to object-oriented, functional, and modular coding styles. The examples use JavaScript.

What's inside

  • Deciding on test types and strategies
  • Test Entry & Exit Points
  • Refactoring legacy code
  • Fakes, stubs, mock objects, and isolation frameworks
  • Object-Oriented, Functional, and Modular testing styles

About the reader

Examples use JavaScript, TypeScript, and Node.js.


Похожее:

Список отзывов:

Нет отзывов к книге.