Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,090 --> 00:00:04,550
Now, this first test, which we wrote,
2
00:00:04,550 --> 00:00:08,240
isn't doing too much useful things.
3
00:00:08,240 --> 00:00:11,520
So let's make our component a bit more powerful
4
00:00:11,520 --> 00:00:14,940
so that we can test more useful things.
5
00:00:14,940 --> 00:00:16,670
And let's say that in this component
6
00:00:16,670 --> 00:00:19,470
we have some state, which should change
7
00:00:19,470 --> 00:00:20,950
if a button is clicked.
8
00:00:20,950 --> 00:00:22,210
And if that button is clicked
9
00:00:22,210 --> 00:00:24,320
some text on the screen changes,
10
00:00:24,320 --> 00:00:27,307
and we want to test whether that works correctly.
11
00:00:28,290 --> 00:00:30,960
So for this, of course, we need to import useState
12
00:00:31,980 --> 00:00:35,020
from React because that is how we can manage state
13
00:00:35,020 --> 00:00:36,980
and functional components.
14
00:00:36,980 --> 00:00:39,283
And then here we can call useState.
15
00:00:42,961 --> 00:00:45,080
And here, I'll just name that state
16
00:00:45,080 --> 00:00:46,233
changedText and setChangedText.
17
00:00:50,240 --> 00:00:52,830
And at the beginning,
18
00:00:52,830 --> 00:00:55,940
this is false because the text has not changed.
19
00:00:55,940 --> 00:00:58,633
But if a button is clicked, the text should change.
20
00:00:59,510 --> 00:01:02,440
So here I'll have a button where I say Change Text
21
00:01:03,390 --> 00:01:05,600
and upon a click on this button,
22
00:01:05,600 --> 00:01:07,750
I want to execute a function.
23
00:01:07,750 --> 00:01:10,020
So I'll add a function to this component,
24
00:01:10,020 --> 00:01:13,580
the changeTextHandler function,
25
00:01:13,580 --> 00:01:16,420
in which I'll simply call setChangedText
26
00:01:17,746 --> 00:01:18,796
and set this to true.
27
00:01:20,250 --> 00:01:22,440
And it's this changeTextHandler function
28
00:01:22,440 --> 00:01:26,220
which will be connected to this onClick prop here
29
00:01:27,170 --> 00:01:30,840
on this button changeTextHandler.
30
00:01:30,840 --> 00:01:31,673
Like this.
31
00:01:33,510 --> 00:01:34,920
Now of course we need to do something
32
00:01:34,920 --> 00:01:36,900
when that state changes.
33
00:01:36,900 --> 00:01:39,330
And therefore, I will render this paragraph
34
00:01:39,330 --> 00:01:40,860
at the beginning
35
00:01:40,860 --> 00:01:43,110
so we can render it conditionally and check
36
00:01:43,110 --> 00:01:46,230
if changed text is false
37
00:01:46,230 --> 00:01:47,963
with an exclamation mark here.
38
00:01:48,800 --> 00:01:50,470
And if that's the case,
39
00:01:50,470 --> 00:01:52,913
then I will render that.
40
00:01:54,340 --> 00:01:57,770
Otherwise, if changed text is true,
41
00:01:57,770 --> 00:02:00,750
hence no exclamation mark,
42
00:02:00,750 --> 00:02:04,093
I'll render 'Changed' here in this paragraph.
43
00:02:04,950 --> 00:02:07,523
That is some code, which we could have here.
44
00:02:08,610 --> 00:02:11,550
Now, if I save that, the component changes
45
00:02:11,550 --> 00:02:13,740
but our test still passes
46
00:02:13,740 --> 00:02:16,520
because the only test we have thus far
47
00:02:16,520 --> 00:02:18,660
doesn't care about that change
48
00:02:18,660 --> 00:02:20,363
we just made to the component.
49
00:02:21,870 --> 00:02:25,250
It just tests where 'Hello world' is still there,
50
00:02:25,250 --> 00:02:26,973
and that's definitely the case.
51
00:02:28,100 --> 00:02:30,830
But now with that new functionality,
52
00:02:30,830 --> 00:02:34,300
which we added here, I got at least two ideas
53
00:02:34,300 --> 00:02:36,800
on how we could test this component now
54
00:02:36,800 --> 00:02:40,450
in addition to the test which we already have.
55
00:02:40,450 --> 00:02:42,870
And do you have some ideas as well?
56
00:02:42,870 --> 00:02:44,520
Think about that briefly.
57
00:02:44,520 --> 00:02:46,400
And then after a couple of seconds
58
00:02:46,400 --> 00:02:48,453
I'll share my ideas with you.
59
00:02:51,680 --> 00:02:54,220
The two ideas, which I got here,
60
00:02:54,220 --> 00:02:59,220
are that we can A, test whether we see this text
61
00:02:59,520 --> 00:03:02,400
if the state did not change yet.
62
00:03:02,400 --> 00:03:04,573
So if the button was not clicked.
63
00:03:05,500 --> 00:03:09,170
And if we see this other text here
64
00:03:09,170 --> 00:03:10,963
if the button was clicked.
65
00:03:12,510 --> 00:03:13,960
Because that's important.
66
00:03:13,960 --> 00:03:15,610
When you write tests
67
00:03:15,610 --> 00:03:19,420
you really want to test all possible scenarios.
68
00:03:19,420 --> 00:03:22,730
Because otherwise your tests are not worth that much.
69
00:03:22,730 --> 00:03:25,090
Because if you only test one scenario
70
00:03:25,090 --> 00:03:27,080
then you will never notice,
71
00:03:27,080 --> 00:03:28,720
or at least not as quickly,
72
00:03:28,720 --> 00:03:31,690
if some other scenario fails because of some change.
73
00:03:31,690 --> 00:03:34,710
So you want to test all possible scenarios,
74
00:03:34,710 --> 00:03:37,223
all possible scenarios that make sense.
75
00:03:38,390 --> 00:03:43,390
So here in this case, I want to write two new tests.
76
00:03:43,580 --> 00:03:45,790
And definitely feel free to write
77
00:03:45,790 --> 00:03:48,240
at least one of those tests on your own.
78
00:03:48,240 --> 00:03:49,910
The test where we test
79
00:03:49,910 --> 00:03:51,860
whether we see this text
80
00:03:51,860 --> 00:03:54,340
if the button was not clicked.
81
00:03:54,340 --> 00:03:56,240
Because we don't know yet how we can click
82
00:03:56,240 --> 00:03:58,110
the button virtually,
83
00:03:58,110 --> 00:04:01,090
so you won't be able to write that test on your own,
84
00:04:01,090 --> 00:04:03,460
but you should be able to write that other test
85
00:04:03,460 --> 00:04:06,507
on your own, where you check for this paragraph.
86
00:04:06,507 --> 00:04:10,120
Here's a quick pause for you to pause the video
87
00:04:10,120 --> 00:04:13,170
and try writing that first test on your own.
88
00:04:13,170 --> 00:04:16,183
Thereafter we'll write both tests together.
89
00:04:20,230 --> 00:04:21,610
Were are you successful?
90
00:04:21,610 --> 00:04:23,060
Let's write that together
91
00:04:23,060 --> 00:04:26,440
and let's start with that first test here.
92
00:04:26,440 --> 00:04:30,713
Here I want to test that the component renders,
93
00:04:31,920 --> 00:04:33,800
and please note how this reads
94
00:04:33,800 --> 00:04:35,380
like a nice sentence.
95
00:04:35,380 --> 00:04:38,510
Greeting component renders Hello World as a text.
96
00:04:38,510 --> 00:04:41,550
Greeting component renders something else.
97
00:04:41,550 --> 00:04:44,260
And that's how you typically want to name those things.
98
00:04:44,260 --> 00:04:45,990
So that tests you would name
99
00:04:45,990 --> 00:04:48,973
and test name for nice sentences.
100
00:04:49,920 --> 00:04:53,310
And here, I'll then say renders
101
00:04:55,350 --> 00:04:56,710
good to see you
102
00:04:59,780 --> 00:05:03,743
if the button was not clicked.
103
00:05:05,700 --> 00:05:08,910
So here I'm describing what I'm testing.
104
00:05:08,910 --> 00:05:10,920
And this part with the button is of course
105
00:05:10,920 --> 00:05:13,020
important because we will then soon write
106
00:05:13,020 --> 00:05:15,573
another test where we test the opposite.
107
00:05:17,100 --> 00:05:20,650
So here we again, want to arrange, act, and assert.
108
00:05:20,650 --> 00:05:22,340
Arranging is the same as before.
109
00:05:22,340 --> 00:05:23,683
We render greeting.
110
00:05:24,640 --> 00:05:26,260
Acting as the same as before.
111
00:05:26,260 --> 00:05:27,550
We don't do anything.
112
00:05:27,550 --> 00:05:28,800
We don't click the button,
113
00:05:28,800 --> 00:05:30,780
so we don't do anything.
114
00:05:30,780 --> 00:05:33,253
And then asserting is also quite similar.
115
00:05:34,560 --> 00:05:39,560
Here I then want to get my paragraph element
116
00:05:40,240 --> 00:05:43,730
or output element, however you want to name it.
117
00:05:43,730 --> 00:05:46,270
And I want to get it by text.
118
00:05:46,270 --> 00:05:48,370
And we could again match it exactly
119
00:05:48,370 --> 00:05:51,280
or just look for 'good to see you'
120
00:05:51,280 --> 00:05:53,060
without matching it exactly.
121
00:05:53,060 --> 00:05:55,513
And hence I'll set exact here to false.
122
00:05:57,420 --> 00:05:59,630
And then my expectation is
123
00:05:59,630 --> 00:06:02,490
that this element exists in the DOM
124
00:06:02,490 --> 00:06:05,593
so that I'm able to find an element with that test.
125
00:06:07,660 --> 00:06:10,260
Let's remove that second test for now and save this.
126
00:06:11,220 --> 00:06:13,600
Now our tests are executed
127
00:06:13,600 --> 00:06:18,010
and we see that we got two tests and both passed,
128
00:06:18,010 --> 00:06:19,773
which is our expectation.
129
00:06:20,980 --> 00:06:22,950
Now let's write that second test
130
00:06:22,950 --> 00:06:25,110
where we want to click that button.
131
00:06:25,110 --> 00:06:27,700
Here the expectation is that we render
132
00:06:30,210 --> 00:06:32,923
Changed if the button was clicked.
133
00:06:33,920 --> 00:06:36,210
So we render Changed
134
00:06:36,210 --> 00:06:38,713
if the button was clicked.
135
00:06:40,515 --> 00:06:42,515
And then here we write our testing code.
136
00:06:44,480 --> 00:06:46,270
Of course you can also put that into quotes
137
00:06:46,270 --> 00:06:47,390
to make it clearer
138
00:06:47,390 --> 00:06:50,370
what's the actual text you're looking for.
139
00:06:50,370 --> 00:06:51,460
But that is optional,
140
00:06:51,460 --> 00:06:53,340
and really just there to help you
141
00:06:53,340 --> 00:06:55,173
understand your testing output.
142
00:06:56,440 --> 00:06:59,310
Now again, we'll arrange the same way
143
00:06:59,310 --> 00:07:04,310
we did it before but now we also need to act.
144
00:07:04,470 --> 00:07:07,090
So I'll add those comments again here
145
00:07:07,090 --> 00:07:09,160
to make this easier to understand.
146
00:07:09,160 --> 00:07:11,260
Now we need to act.
147
00:07:11,260 --> 00:07:13,710
And the act which we want to do
148
00:07:13,710 --> 00:07:15,913
is that we want to click that button.
149
00:07:17,310 --> 00:07:19,880
Now for this, we can import another feature
150
00:07:19,880 --> 00:07:21,840
from another package,
151
00:07:21,840 --> 00:07:24,563
which also was installed out of the box,
152
00:07:25,400 --> 00:07:29,060
from the testing library user event package,
153
00:07:29,060 --> 00:07:30,203
to be precise.
154
00:07:31,340 --> 00:07:33,420
From there, I want to import
155
00:07:33,420 --> 00:07:36,150
userEvent just like this.
156
00:07:36,150 --> 00:07:39,253
So from @testing-library user event.
157
00:07:40,610 --> 00:07:42,190
User event is an object
158
00:07:42,190 --> 00:07:44,560
that helps us trigger user events
159
00:07:44,560 --> 00:07:46,703
in this virtual screen.
160
00:07:48,300 --> 00:07:50,270
We can simply use user event,
161
00:07:50,270 --> 00:07:52,820
and then there, we got all these typical events
162
00:07:52,820 --> 00:07:55,190
which we can perform like clicking,
163
00:07:55,190 --> 00:07:58,930
double clicking, hovering, typing into inputs.
164
00:07:58,930 --> 00:08:01,143
Here we of course need a click.
165
00:08:02,060 --> 00:08:05,750
And click then needs one argument at least.
166
00:08:05,750 --> 00:08:07,040
It needs the element
167
00:08:07,040 --> 00:08:09,940
on which you want to simulate a click.
168
00:08:09,940 --> 00:08:13,363
And in my case that's, of course, this button here.
169
00:08:14,530 --> 00:08:18,000
We can select this button again by text
170
00:08:18,000 --> 00:08:20,110
but we can also select it differently
171
00:08:20,110 --> 00:08:23,630
and to mix things up, I'll show you that alternative.
172
00:08:23,630 --> 00:08:26,010
We can, again, use the screen here
173
00:08:26,010 --> 00:08:29,043
and get this element by role.
174
00:08:30,160 --> 00:08:33,559
We can get it by role, and button is a role
175
00:08:33,559 --> 00:08:36,210
elements can have on the screen.
176
00:08:36,210 --> 00:08:38,520
And since I only have one button here
177
00:08:38,520 --> 00:08:41,722
that will give me access to this one button I have here.
178
00:08:42,770 --> 00:08:45,910
Of course you could also, again, use get by text.
179
00:08:45,910 --> 00:08:47,560
There is nothing wrong with that.
180
00:08:48,520 --> 00:08:51,410
Now that's the button on which we want to simulate a click.
181
00:08:51,410 --> 00:08:53,630
So it's this button element,
182
00:08:53,630 --> 00:08:55,763
which I pass to user event click.
183
00:08:57,620 --> 00:09:00,630
And then we still have the assert step.
184
00:09:00,630 --> 00:09:03,160
Here I want to get access
185
00:09:03,160 --> 00:09:07,710
to some element by text again.
186
00:09:07,710 --> 00:09:09,970
So I'll get by text,
187
00:09:09,970 --> 00:09:13,033
and the text I'm now looking for is changed.
188
00:09:14,620 --> 00:09:16,380
So I'll copy that.
189
00:09:16,380 --> 00:09:19,617
And that will actually be my exact text here.
190
00:09:22,180 --> 00:09:25,350
So we can now even remove exact false
191
00:09:25,350 --> 00:09:27,053
but you can also keep it there.
192
00:09:28,390 --> 00:09:30,840
And now of course we need the actual assertion
193
00:09:30,840 --> 00:09:34,540
which is that we expect output element
194
00:09:34,540 --> 00:09:37,963
to be in the document, like before.
195
00:09:39,440 --> 00:09:41,650
And if I save that,
196
00:09:41,650 --> 00:09:43,480
the tests all execute
197
00:09:43,480 --> 00:09:46,560
and all three tests passed,
198
00:09:46,560 --> 00:09:49,540
and that means that this button click simulation
199
00:09:49,540 --> 00:09:52,370
worked and this test passed.
200
00:09:52,370 --> 00:09:54,480
And that's how you can test
201
00:09:54,480 --> 00:09:57,313
user interaction and state changes here.
202
00:09:58,370 --> 00:10:01,620
Now to conclude this there is one other test
203
00:10:01,620 --> 00:10:05,190
we could add here to test another thing
204
00:10:05,190 --> 00:10:07,160
that should definitely be the case
205
00:10:07,160 --> 00:10:09,030
for this component.
206
00:10:09,030 --> 00:10:11,100
And it can be hard to spot it,
207
00:10:11,100 --> 00:10:12,700
but maybe you can see it.
208
00:10:12,700 --> 00:10:15,960
Which other thing could we test here
209
00:10:15,960 --> 00:10:17,963
that could make sense to test?
210
00:10:20,270 --> 00:10:23,700
Well, let me show you something.
211
00:10:23,700 --> 00:10:27,450
What if I introduce an error as a developer
212
00:10:27,450 --> 00:10:29,980
and I actually do forget
213
00:10:29,980 --> 00:10:33,200
to render this first paragraph conditionally.
214
00:10:33,200 --> 00:10:35,180
So it's always there.
215
00:10:35,180 --> 00:10:38,150
Unfortunately, my tests won't spot this,
216
00:10:38,150 --> 00:10:39,670
my tests all succeed
217
00:10:39,670 --> 00:10:42,593
because all the things I test still work out.
218
00:10:43,820 --> 00:10:46,170
But if I know that this paragraph
219
00:10:46,170 --> 00:10:47,720
should never be visible
220
00:10:47,720 --> 00:10:49,790
if we click the button,
221
00:10:49,790 --> 00:10:52,090
then of course we also need a test
222
00:10:52,090 --> 00:10:55,130
that tests if that paragraph is gone
223
00:10:55,130 --> 00:10:56,623
once we click the button.
224
00:10:57,687 --> 00:11:00,410
So there is a fourth test which could make sense here,
225
00:11:00,410 --> 00:11:03,480
a test where we click the button and then check
226
00:11:03,480 --> 00:11:07,340
if the paragraph with this text here
227
00:11:07,340 --> 00:11:09,363
is not visible.
228
00:11:10,370 --> 00:11:13,540
And definitely try writing this test on your own.
229
00:11:13,540 --> 00:11:15,380
Again, after a short pause,
230
00:11:15,380 --> 00:11:16,803
we'll write it together.
231
00:11:19,410 --> 00:11:21,040
Were are you successful?
232
00:11:21,040 --> 00:11:23,764
Let's write this test together.
233
00:11:23,764 --> 00:11:27,612
For that here, I'll give that test a description
234
00:11:27,612 --> 00:11:31,500
and I'll say 'does not render'.
235
00:11:31,500 --> 00:11:34,320
So greeting component
236
00:11:34,320 --> 00:11:35,890
does not render
237
00:11:38,830 --> 00:11:40,200
good to see you
238
00:11:43,190 --> 00:11:45,323
if the button was clicked.
239
00:11:46,980 --> 00:11:48,930
That's my description.
240
00:11:48,930 --> 00:11:52,110
And then here in the testing code,
241
00:11:52,110 --> 00:11:54,700
I will generally copy the code
242
00:11:54,700 --> 00:11:58,360
from that other test where we clicked the button
243
00:11:58,360 --> 00:12:01,280
because I again want to click the button.
244
00:12:01,280 --> 00:12:03,570
But then in here,
245
00:12:03,570 --> 00:12:07,200
I don't check if we have this changed paragraph,
246
00:12:07,200 --> 00:12:11,310
but instead I try to find the element
247
00:12:11,310 --> 00:12:13,720
with a text of 'good to see you',
248
00:12:13,720 --> 00:12:16,903
and that should not be an exact match.
249
00:12:18,630 --> 00:12:21,860
Now get by text will fail
250
00:12:21,860 --> 00:12:23,650
if an element is not found,
251
00:12:23,650 --> 00:12:25,860
and here my expectation is actually
252
00:12:25,860 --> 00:12:27,550
that it's not found.
253
00:12:27,550 --> 00:12:31,480
So here we should write not to be in the document.
254
00:12:31,480 --> 00:12:33,430
But again, since this would throw an error
255
00:12:33,430 --> 00:12:36,830
if it's not found, this test could never pass
256
00:12:36,830 --> 00:12:38,270
if the element is not found
257
00:12:38,270 --> 00:12:40,410
even though that is what we want.
258
00:12:40,410 --> 00:12:44,680
So that's then a reason for using query by text
259
00:12:44,680 --> 00:12:47,320
because that will simply return null
260
00:12:47,320 --> 00:12:49,833
if the element is not found.
261
00:12:51,370 --> 00:12:53,800
And therefore, actually here I then want to check
262
00:12:53,800 --> 00:12:57,130
if output element is null and for that,
263
00:12:57,130 --> 00:13:00,040
we got the toBeNull method here.
264
00:13:00,040 --> 00:13:03,120
And you can of course look through all the available methods
265
00:13:03,120 --> 00:13:06,483
to see what you need for your tests you're writing.
266
00:13:07,550 --> 00:13:09,440
So here I want to check if that's null
267
00:13:09,440 --> 00:13:11,350
because that would be my expectation
268
00:13:11,350 --> 00:13:13,990
since I don't want to find this element
269
00:13:13,990 --> 00:13:15,433
if the button was clicked.
270
00:13:16,710 --> 00:13:18,370
If we now save everything
271
00:13:20,760 --> 00:13:23,340
this test fails as it should
272
00:13:23,340 --> 00:13:26,180
because we have an error in our component.
273
00:13:26,180 --> 00:13:30,140
This element with this text should not exist.
274
00:13:30,140 --> 00:13:32,550
And now we see that this test fails
275
00:13:32,550 --> 00:13:34,610
and as a developer, we can go
276
00:13:34,610 --> 00:13:37,010
to the component code and fix this bug,
277
00:13:37,010 --> 00:13:40,140
and make sure that we only render this paragraph
278
00:13:40,140 --> 00:13:42,740
if changed text is not true.
279
00:13:42,740 --> 00:13:44,630
So what we had before.
280
00:13:44,630 --> 00:13:47,820
And if I save this, the tests rerun
281
00:13:47,820 --> 00:13:49,563
and they now all pass.
282
00:13:50,500 --> 00:13:52,700
And that's why testing is important,
283
00:13:52,700 --> 00:13:54,370
and how we write tests,
284
00:13:54,370 --> 00:13:56,520
and how we can also test more
285
00:13:56,520 --> 00:13:58,693
than just static components.
21160
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.