A
acceptance tests
component-level 317-328
end-to-end tests vs. 44-45
act step 27, 40, 259, 429
actions
application actions 425-429
sequencing 413-417
addons property 321, 324, 326
afterAll hook 35, 42, 63, 151
APIs
backend application testing 152-160
end-to-end testing of HTTP APIs 39-43
frontend application testing of browser APIs 217-234
History API integrations 221-234
localStorage integrations 217-221
stubbing API requests 437-440
app.close 42
app.listen 41
application actions 425-429
arrange step 27, 40, 259, 428-429
assert library 25, 28
assert module 28
assert step 25, 27, 40, 259, 429
assert.deepStrictEqual 26
assertions 25
asserting on the DOM 194-207
finding elements 201-203
writing better assertions 204-207
turning into preconditions 182-183
writing 73-85
circular assertions 83-85
custom matchers 81-83
error handling 73-76
loose assertions 76-81
asymmetric matchers 80
atomicity 71-73
automated testing
choosing what to test 100-105, 110
integration tests 104-105
mocking 102-104
third-party software 101-102
CI/CD pipeline 464-466
code coverage 105-111
automated coverage reports 107
coverage types 107-108
good and bad 108-109
cost and revenue 47-53
defined 4-9
end-to-end tests 37-45
acceptance tests vs. 44-45
testing GUIs 43-44
testing HTTP APIs 39-43
exploratory testing 45-47
importance of 9-16
collaboration 13-15
predictability 10-11
reproducibility 12-13
speed 15-16
integration tests 31-37
organizing test suites 60-73, 109-110
atomicity 71-73
breaking down tests 65-68
global hooks 70-71
parallelism 68-70
test doubles 85-100, 110
testing pyramid 19-23
automated testing (continued)
unit tests 23-30
writing good assertions 73-85, 110
circular assertions 83-85
custom matchers 81-83
error handling 73-76
loose assertions 76-81
B
@babel/preset-react package 253
babel-loader 253
babelify package 253-254, 258
backend application testing
eliminating nondeterminism 162-176
dealing with time 167-176
parallelism and shared resources 163-167
external dependencies 140-160
API integration 152-160
database integration 140-152
reducing costs while preserving quality 176-183
creating transitive guarantees 181-182
reducing overlap between tests 177-181
turning assertions into preconditions 182-183
structuring testing environment 113-126
end-to-end testing 115-118
integration testing 119-124
unit testing 124-126
testing HTTP endpoints 126-140
basic access authentication 136
before hook 151
beforeAll hook 35, 63-64, 92
beforeEach hook 35, 63, 71-72, 92, 95, 138, 150-151, 200, 220, 225, 228, 239, 275, 407, 412, 435, 439
behavior-driven development (BDD) 375-377
bike-shedding 477
black box tests 38
bottom-up testing approach 355-364
deciding which approach to take 362-364
defined 356-357
impact on workflow 357-359
pros and cons 359-364
costs 360-361
coverage 361-362
reliability 360
branch coverage 107
brittle selectors 403
browserify 193, 252
browsers
frontend application testing 217-234
History API integrations 221-234
localStorage integrations 217-221
UI-based end-to-end testing on multiple 445-448
running 447-448
using testing frameworks 446-447
bubbles property 215
C
carts 32, 66, 120, 122
CI/CD (continuous integration and continuous delivery)
continuous integration services 459-460
defined 457-463
continuous delivery 460-463
continuous integration 457-460
role of automated tests in pipeline 463-464
version-control checks 464-466
circular assertions 83-85
classname property 309
clearMocks property 92, 95
code coverage 105-109
automated coverage reports 107
coverage types 107-108
good and bad 108-109
test-driven development 361-362
code reviews 474-476
container property 296
continuous integration and continuous delivery. See CI/CD
core-js package 274
costs
automated testing and 47-53
reducing while preserving quality 176-183
creating transitive guarantees 181-182
reducing overlap between tests 177-181
turning assertions into preconditions 182-183
test-driven development 342, 364-369
coverage directory 107
css-in-js library 311
Cypress
overview 393-394
when to choose 394-395
D
data property 295
database integration 140-152
maintaining pristine state 148-152
setting up tests 141-145
using separate database instances 145-148
deepStrictEqual function 25, 28
deleting redundant tests 368-369
describe block 61-62, 64-65, 71, 228
design system 325
deterministic tests 162
devDependency 29, 33
documentation
quality 479-480
writing 326-328
DOM
asserting on 194-207
finding elements 201-203
writing better assertions 204-207
React rendering components and 259-264
dom-testing-library 202-204, 207, 216, 261-263, 265-268
E
@emotion/core package 311
emotion library 311-312, 314-316
end-to-end testing
acceptance tests vs. 44-45
overview 37-45
structuring testing environment for backend application testing 115-118
testing GUIs 43-44
testing HTTP APIs 39-43
UI-based
terminology 386-387
tools 387-395
where each type of test fits 383-387
Enzyme 277-278
error handling, assertions and 73-76
event handling, in frontend application testing 207-217
exploratory testing 45-47
external dependencies 140-160
API integration 152-160
database integration 140-152
maintaining pristine state 148-152
setting up tests 141-145
using separate database instances 145-148
F
f(x) notation 6
fetch 155, 235-237, 239, 270, 274, 411, 432
fetch-mock package 323
fixtures 151
flaky tests 398
formatters 476-478
frontend application testing
asserting on the DOM 194-207
finding elements 201-203
writing better assertions 204-207
browser APIs 217-234
History API integrations 221-234
localStorage integrations 217-221
event handling 207-217
HTTP requests 234-240
JSDOM 187-194
WebSockets 234-235, 240-247
function coverage 107
G
generatedAt property 80-81
GET request 389, 431-432, 437
global hooks 70-71
globalTeardown hook 70
green testing 367
GUIs, end-to-end testing of 43-44
H
History API integrations, testing 221-234
HTTP
end-to-end testing of APIs 39-43
requests 234-247
sending 411-413
tests involving 235-240
waiting for 431-433
testing endpoints 126-140
husky package 465, 478
I
integration testing
as best of both worlds 104-105
backend application testing 119-124
overview 31-37
inventory 66, 120, 122
IoT (Internet-of-Things) devices 163
isomorphic-fetch 39, 126, 153, 160, 236, 270
items property 30, 293
J
jest-dom library 263
jest-emotion 313, 315-316
jest-extended library 204
jest-puppeteer package 393
jest-when 157, 183
jest.config.js file 27
jest.fn 92
jest.spyOn 87
JSDOM 187-194
K
knex package 31, 405
knexfile.js file 31
koa-body-parser package 128
koa-router 39-40
L
line coverage 108
linters 476-478
localStorage integrations, testing 217-221
lolex package 171
loose assertions 76-81
M
maintenance costs 361
major version 29
manual mock 99
manual testing 9
matcher functions 28
matchers, custom 81-83
message property 295
middleware, testing 131-140
migrations 32
mocks 85-100
mocking imports 96-100
too much mocking 103-104
whether to mock or not 102-104
monitoring systems 478-479
N
NaN (not a number) 77, 165, 338
nock package 158, 160, 183, 236-239, 271, 275, 322
nondeterminism, eliminating 162-176
dealing with time 167-176
parallelism and shared resources 163-167
O
organizing test suites 60-73
atomicity 71-73
breaking down tests 65-68
global hooks 70-71
parallelism 68-70
P
package.json 27, 29-30, 140, 189, 251-253, 255-256, 274, 292, 319, 345, 399, 450, 465, 477
page objects 417-425
parallelism
organizing test suites 68-70
shared resources and 163-167
PATH environment variable 30
pino library 86-87
plugins directory 449
POST 245, 285, 323, 389
pow function 50
preset-env package 256, 258, 274
Puppeteer
overview 392-393
when to choose 392-393
Q
quality
code reviews 474-476
good documentation 479-480
linters and formatters 476-478
monitoring systems 478-479
preserving while reducing costs 176-183
creating transitive guarantees 181-182
reducing overlap between tests 177-181
turning assertions into preconditions 182-183
type systems 469-474
value of QA 45-47
quantity property 242
R
React application testing
component-level acceptance tests and component stories 317-328
writing documentation 326-328
writing stories 318-326
snapshot testing 295-307
serializers 307
utilities 305-307
testing component integration 282-295
testing styles 307-317
react library 251, 261
React testing ecosystem
setting up 250-258
React application 250-255
testing environment 255-258
testing libraries 258-279
Enzyme 277-278
react-testing-library 264-277
rendering components and the DOM 259-264
test renderer 278-279
react-dom package 251, 259, 261-262, 264-265, 279
react-is package 326
react-native application 279
react-spring library 291, 293-294
react-test-renderer 279
react-testing-library 250, 258, 264-278, 287, 295, 298, 384-385
interacting with components 267-272
rendering components and finding elements 265-267
waiting for events 272-277
refactoring tests 367
request package 160
resetMocks 95
restoreMocks 95
retrying tests 443-445
S
Selenium 387-391
function of 388-390
using Webdriver interfaces without 390
when to choose 391
selenium-webdriver package 390
serializers 307
server directory 283
setupFilesAfterEnv hook 151
setupFilesAfterEnv property 236
shallow rendering 277
sinonjs/fake-timers package 171, 176
snapshot testing 295-307
serializers 307
utilities 305-307
speed
automated testing 15-16
test-driven development 364-369
spies 85-86, 95-100
spy.mock.calls array 91
spy.mock.instances array 91
sqlite database 33
sqlite3 package 31, 405
statement coverage 107
stories 317-328
writing 318-326
writing documentation 326-328
stories property 326
@storybook/addon-actions package 324
@storybook/addon-knobs package 321
stubs
overview 85-100
stubbing API requests 437-440
stubbing components 291-295
stubbing functions 440-443
style property 205
style.color property 206
supertest package 127, 130, 138
support directory 448
T
TDD (test-driven development)
adjusting iteration size 339-341
balancing maintenance costs, delivery speed, and brittleness 364-369
implementation 364-367
maintenance 367-369
defined 332-339
philosophy behind 332-345
reasons to adopt 342-344
better-designed code 343-344
cost reduction 342
development process guidance 344
fear and anxiety reduction 342-343
more thorough testing 344
setting up environment 369-375
keeping distinct lanes 371-373
pairing 373-374
supplementary testing 374-375
teamwide adoption 370-371
specifications 375-377
top-down vs. bottom-up 355-364
deciding which approach to take 362-364
defined 356-357
impact on workflow 357-359
pros and cons 359-364
validations 375-377
when not to apply 344-345
writing JavaScript modules using 345-355
test doubles 85-100
testing-library 216
textContent property 260
third-party software, testing 101-102
time property 295
toBe assertion 28, 80
toBeBefore assertion 83
toBeGreaterThan assertion 78
toEqual assertion 28, 80
top-down testing approach 355-364
deciding which approach to take 362-364
defined 356-357
impact on workflow 357-359
pros and cons 359-364
costs 360-361
coverage 361-362
reliability 360
toThrow 76
transitive guarantees 53, 181-182
truncate statements 35
type systems 469-474
U
UI tests 385-386
UI-based end-to-end testing
best practices for 417-429
application actions 425-429
page objects 417-425
flakiness 429-445
avoiding waiting for fixed amounts of time 430-433
retrying tests 443-445
stubbing uncontrollable factors 433-443
on multiple browsers 445-448
running 447-448
using testing frameworks 446-447
terminology 386-387
tools 387-395
Cypress 393-394
Puppeteer 392-393
Selenium 387-391
visual regression tests 448-451
where each type of test fits 383-387
pure end-to-end tests 384-385
pure UI tests 385-386
UI-based end-to-end tests 383-384
writing 399-417
sending HTTP requests 411-413
sequencing actions 413-417
unit testing
overview 23-30
structuring testing environment for backend application testing 124-126
useEffect hook 274
user-event library 216
V
validation of software 463
version-control checks 464-466
visual regression tests 448-451
W
Webdrivers 390
WebSockets 234-235, 240-247
white box tests 38