﻿1
00:00:04,599 --> 00:00:08,631
In our previous lesson, we worked
on handling the player inputs,

2
00:00:09,273 --> 00:00:13,400
but we've only been testing
our application through feature tests.

3
00:00:14,233 --> 00:00:18,808
Automated tests are a crucial part
of having a robust codebase

4
00:00:18,833 --> 00:00:20,700
that is easier to work with,

5
00:00:20,833 --> 00:00:24,167
but they are not a replacement
for manual tests,

6
00:00:24,200 --> 00:00:28,742
since there is always a chance
that we have overlooked behaviors

7
00:00:28,767 --> 00:00:31,733
while working on our automated tests.

8
00:00:32,426 --> 00:00:35,199
Alright, let's check out our app so far.

9
00:00:35,627 --> 00:00:37,533
And look at this!

10
00:00:37,558 --> 00:00:39,517
We're getting a warning

11
00:00:39,542 --> 00:00:43,823
because we're providing
an invalid prop to our worldleboard.

12
00:00:43,848 --> 00:00:46,633
And this is great!
We wrote a test for this.

13
00:00:47,173 --> 00:00:52,017
Remember, the word of the day
must be a 5 characters long,

14
00:00:52,033 --> 00:00:55,600
real English word
with everything in uppercase.

15
00:00:56,769 --> 00:00:58,933
So I'm opening the app.vue

16
00:00:58,958 --> 00:01:01,900
and I'm gonna pass
the word-of-the-day of TESTS.

17
00:01:02,900 --> 00:01:05,923
If we save it,
run all of our tests again,

18
00:01:05,948 --> 00:01:07,428
we can see that we're still passing,

19
00:01:07,453 --> 00:01:09,468
so I'm just gonna make a commit over here.

20
00:01:12,201 --> 00:01:17,667
And I'll call it, use word
of the day that passes validation.

21
00:01:19,367 --> 00:01:22,333
But okay,
let's test our app manually now.

22
00:01:22,733 --> 00:01:25,700
If we go back to the browser
and we refresh the page,

23
00:01:25,725 --> 00:01:28,500
we can see that that warning
is no longer showing up.

24
00:01:29,033 --> 00:01:31,763
I'll also be displaying
my keyboard over here

25
00:01:31,788 --> 00:01:34,200
so you can see what I am typing.

26
00:01:35,743 --> 00:01:38,417
Alright, so if I type
a lowercase character,

27
00:01:38,442 --> 00:01:42,167
you can see that it immediately
becomes uppercase automatically.

28
00:01:42,967 --> 00:01:47,230
And if I type a number,
you can see that the number appears.

29
00:01:47,255 --> 00:01:51,000
So this is a bug, but if I type
a valid character afterwards,

30
00:01:51,025 --> 00:01:52,700
the number disappears.

31
00:01:53,340 --> 00:01:54,683
So this is great, right?

32
00:01:54,708 --> 00:01:57,967
We discovered a bug in our application.

33
00:01:58,567 --> 00:02:02,300
This is because Vue
isn't refreshing the render

34
00:02:02,300 --> 00:02:06,400
until a change is reflected
in the guessInProgress.

35
00:02:07,400 --> 00:02:11,300
This is a great opportunity for us
to write a regression test

36
00:02:11,333 --> 00:02:14,667
and make sure that this bug
that we just identified

37
00:02:14,692 --> 00:02:18,810
and will soon be fixing,
won't return to the app in the future.

38
00:02:19,883 --> 00:02:22,670
So I'm gonna go back to our test suite

39
00:02:23,623 --> 00:02:25,700
and create a brand new test.

40
00:02:27,733 --> 00:02:29,833
And for the description of this test,

41
00:02:29,900 --> 00:02:34,300
I'm gonna name something
that is describing the bug that I saw,

42
00:02:34,326 --> 00:02:37,567
but explaining the behavior
that I want my app to have.

43
00:02:37,767 --> 00:02:40,613
So non-letter characters,

44
00:02:41,833 --> 00:02:47,367
do not render
on the screen while being typed.

45
00:02:54,003 --> 00:02:57,176
And how can we demonstrate this bug?

46
00:02:58,656 --> 00:03:05,567
Well, we can do this
by mounting our component just fine

47
00:03:05,667 --> 00:03:09,333
and typing a player guess,
as we saw before,

48
00:03:09,767 --> 00:03:14,300
that if I start typing numbers
and I don't type something that is valid,

49
00:03:14,467 --> 00:03:16,533
the number stays on the screen.

50
00:03:16,558 --> 00:03:18,533
So let's just type numbers in here.

51
00:03:18,806 --> 00:03:24,867
And in this case, what I want to see
is a complete empty input.

52
00:03:25,367 --> 00:03:28,730
Let's run our tests. And look at this.

53
00:03:28,767 --> 00:03:34,467
We effectively reproduced the bug
that we've witnessed it, manually.

54
00:03:35,367 --> 00:03:38,433
A good way for us to force
a re-render in this case

55
00:03:38,458 --> 00:03:41,933
would be to unset
the value of guessInProgress

56
00:03:41,967 --> 00:03:45,800
at the start of each update
of the formatted guess.

57
00:03:46,500 --> 00:03:50,556
We can achieve this by making
the guessInProgress nullable

58
00:03:50,646 --> 00:03:53,433
and then set it to null
right at the start.

59
00:03:53,458 --> 00:03:54,619
So let's do this.

60
00:03:55,233 --> 00:03:58,999
So guessInProgress
is either a string or null.

61
00:03:59,160 --> 00:04:00,790
And I'll have it start as null.

62
00:04:01,862 --> 00:04:06,437
And now in here, you can see that because
of our formatted guessInProgress,

63
00:04:06,713 --> 00:04:10,533
I want it to still be a string.

64
00:04:10,733 --> 00:04:13,830
So I want to make sure
that whenever you're trying to get

65
00:04:15,063 --> 00:04:16,867
a formatted guessInProgress,

66
00:04:17,133 --> 00:04:19,800
if the guessInProgress
right now is null,

67
00:04:19,867 --> 00:04:23,633
this is going to coalesce
into an empty string.

68
00:04:23,733 --> 00:04:26,000
Because over here
is the null coalescing operator.

69
00:04:26,867 --> 00:04:28,700
For the case of our setter,

70
00:04:28,906 --> 00:04:30,767
what I want to do at the very start

71
00:04:30,792 --> 00:04:34,233
is set the guessInProgress
value to be null.

72
00:04:34,333 --> 00:04:41,967
And then I can calculate the value
to be whatever is the processed raw value.

73
00:04:43,303 --> 00:04:45,800
And for the case of the onSubmit function,

74
00:04:45,867 --> 00:04:49,100
I'll just be operating
with the formatted guessInProgress.

75
00:04:50,877 --> 00:04:54,500
The guessInProgress
is now just an internal ref

76
00:04:54,640 --> 00:04:57,167
for the sake
of the formatted guessInProgress.

77
00:04:57,192 --> 00:04:58,219
And that's it.

78
00:05:00,613 --> 00:05:04,008
All right, with these changes,
we should be able to run our tests

79
00:05:04,033 --> 00:05:07,400
and see that we're back to a green stage.

80
00:05:08,620 --> 00:05:11,533
And just like that, the bug is gone.

81
00:05:11,567 --> 00:05:15,667
Look at this, I'm trying to type
special characters, nothing appears,

82
00:05:15,692 --> 00:05:20,330
I can type regular characters
and they do appear right away.

83
00:05:20,719 --> 00:05:23,200
So we fixed the bug. Amazing.

84
00:05:24,000 --> 00:05:26,767
We can no longer type
invalid characters at all.

85
00:05:27,180 --> 00:05:29,923
Not only that,
but we also have a test suite

86
00:05:29,967 --> 00:05:34,100
that will guard our application
from this bug ever returning.

87
00:05:35,881 --> 00:05:39,900
Hello folks, this is a quick update
to episode 9

88
00:05:39,967 --> 00:05:43,833
of a Wordle
on Test Driven Development with Vue.

89
00:05:44,333 --> 00:05:47,800
During that episode,
we wrote a regression task

90
00:05:47,867 --> 00:05:50,300
that proved that at the moment,

91
00:05:50,467 --> 00:05:55,833
a player was being able to type numbers
directly into the input box.

92
00:05:56,000 --> 00:05:59,030
And remember,
the worlde game does not allow that,

93
00:05:59,033 --> 00:06:03,700
so, we wrote a task that exposed this bug
and we made that test pass

94
00:06:04,367 --> 00:06:07,733
by setting
the guessInProgress.value to null

95
00:06:07,833 --> 00:06:10,267
and only then, recalculating that.

96
00:06:10,333 --> 00:06:15,300
So, if I run the test over here, you can
see that these tests are all passing.

97
00:06:16,100 --> 00:06:19,890
However, it came to our attention
that for some people

98
00:06:20,133 --> 00:06:23,033
this test was failing,
even after this change.

99
00:06:23,300 --> 00:06:25,367
And what is the cause behind this?

100
00:06:25,700 --> 00:06:28,933
Well, turns out
that when we recorded this course

101
00:06:29,000 --> 00:06:33,433
we were using vue version 3.3,

102
00:06:33,700 --> 00:06:37,433
but now the latest version of vue is 3.4.

103
00:06:37,567 --> 00:06:44,333
And since then, vue has changed some
things about how computed references work.

104
00:06:44,433 --> 00:06:47,833
So, let me change the version of vue
to 3.4 in here,

105
00:06:50,430 --> 00:06:52,900
and if I try running the test once again,

106
00:06:53,549 --> 00:06:55,777
you can all see that this test is failing.

107
00:06:55,939 --> 00:06:58,539
So, if this is happening to you, as well,

108
00:06:59,000 --> 00:07:01,267
this video should help you out.

109
00:07:02,200 --> 00:07:06,433
Alright, so vue is now
being more performant

110
00:07:06,467 --> 00:07:09,067
on how it works with computed references.

111
00:07:09,100 --> 00:07:13,367
Setting this value to null, and then
assign it to have a new value afterwards,

112
00:07:13,400 --> 00:07:16,833
is no longer enough
to trigger a re-render.

113
00:07:17,067 --> 00:07:19,767
If you want to cause
this re-render to happen,

114
00:07:19,800 --> 00:07:24,467
what we're gonna have this of,
is this global helper function

115
00:07:24,567 --> 00:07:26,333
called triggerRef.

116
00:07:29,730 --> 00:07:34,367
And you can see over here comes straight
from the vue package itself,

117
00:07:34,667 --> 00:07:36,333
and what it takes,

118
00:07:36,467 --> 00:07:41,400
is a ref whose tied effects
will be executed.

119
00:07:41,733 --> 00:07:46,183
So, in our case,
we wanna trigger the side effects

120
00:07:46,267 --> 00:07:48,633
of formattedGuessInProgress.

121
00:07:48,700 --> 00:07:52,067
So, let's just copy it, paste triggerRef,

122
00:07:52,400 --> 00:07:54,577
and if I try running the test once again,

123
00:07:55,267 --> 00:07:58,800
we can see
that now all the tests are passing.

124
00:08:01,027 --> 00:08:04,537
I also want to give a huge shoutout
to Hank Yang

125
00:08:04,633 --> 00:08:07,533
for providing the suggestion
of using triggerRef

126
00:08:07,733 --> 00:08:14,000
and to ViFeng to sharing this issue
in our github issues

127
00:08:14,025 --> 00:08:16,058
for the repo of this class.

128
00:08:16,333 --> 00:08:19,770
Thank you so much folks,
and I hope this will help you.

129
00:08:19,933 --> 00:08:21,070
Happy coding!

130
00:08:22,307 --> 00:08:24,000
Let's make another commit.

131
00:08:25,213 --> 00:08:29,390
Fix bug that allowed player
to type guesses with numbers.

132
00:08:31,727 --> 00:08:35,645
Whenever you write a regression test
and implement the fix,

133
00:08:35,670 --> 00:08:38,504
make sure to test your test.

134
00:08:38,803 --> 00:08:40,204
What do I mean by this?

135
00:08:40,739 --> 00:08:43,604
For example, for this test we just wrote,

136
00:08:44,004 --> 00:08:48,637
if we were to go back to our code
and delete line 20

137
00:08:49,170 --> 00:08:50,570
and run the test again,

138
00:08:50,637 --> 00:08:53,737
we can see that the test suite
is still passing.

139
00:08:53,970 --> 00:08:57,004
Therefore, a developer
looking into our code

140
00:08:57,029 --> 00:09:02,470
might think that this line over here
is cluttered and can be removed.

141
00:09:02,823 --> 00:09:05,204
But we know that this line

142
00:09:05,304 --> 00:09:09,770
is only optional for the very first
interaction of the player,

143
00:09:09,804 --> 00:09:15,204
since the guess in progress starts at null
when the component is mounted.

144
00:09:15,637 --> 00:09:18,470
But for every further interactions,

145
00:09:18,517 --> 00:09:21,704
if we don't reset the guess
in progress back to null,

146
00:09:22,330 --> 00:09:26,837
the bug that allows invalid characters
to appear, will return.

147
00:09:28,100 --> 00:09:33,470
We should, therefore, make this need
very clear through our test.

148
00:09:33,637 --> 00:09:38,837
We can prove the necessity of that line
by doing one small modification.

149
00:09:39,236 --> 00:09:43,170
Instead of having our player
only interact with the component once,

150
00:09:43,336 --> 00:09:47,070
we're going to have them interact
with the component two times.

151
00:09:47,737 --> 00:09:51,704
So the player is going to type
12 over here, and then 123 over here,

152
00:09:52,237 --> 00:09:56,237
If I were to run our test right now,
we are still passing.

153
00:09:56,603 --> 00:10:00,443
And if another developer thinks
that this line is not needed,

154
00:10:00,870 --> 00:10:05,304
and they were to remove this,
we can see that now the tests are failing.

155
00:10:05,637 --> 00:10:08,670
So we've made our test more robust

156
00:10:08,744 --> 00:10:13,357
to demonstrate the need for the lines
that we're adding here.

157
00:10:13,877 --> 00:10:15,604
So always keep that in mind.

158
00:10:16,590 --> 00:10:20,004
Okay, so we're passing.
Let's make another commit.

159
00:10:20,277 --> 00:10:22,570
Make test more robust.

160
00:10:26,120 --> 00:10:29,070
Writing tests is not an exact science,

161
00:10:29,137 --> 00:10:33,270
and we can only strive to be
more comfortable with them over time.

162
00:10:33,570 --> 00:10:37,070
A lesson here is to always test your tests

163
00:10:37,104 --> 00:10:42,170
and make sure they are indeed guarding
the requirements you're describing.

164
00:10:43,674 --> 00:10:47,104
In this episode,
not only we had a great opportunity

165
00:10:47,129 --> 00:10:49,770
to see the value of manual tests,

166
00:10:49,950 --> 00:10:54,804
but we also were able to implement
a regression test in practice.

167
00:10:55,237 --> 00:11:00,637
This kind of flow is exactly what we see
in our day-to-day as developers.

168
00:11:00,737 --> 00:11:04,404
If we see a bug,
instead of just fixing it,

169
00:11:04,637 --> 00:11:08,937
we want to make sure to write a test
first that exposes that bug,

170
00:11:09,104 --> 00:11:11,570
and only then we fix it.

171
00:11:12,204 --> 00:11:16,270
This pattern makes our app
more robust and reliable,

172
00:11:16,376 --> 00:11:20,770
and will also reduce the odds
of this bug returning in the future.

173
00:11:21,370 --> 00:11:25,570
Hopefully, this will be something
that we'll all be striving for,

174
00:11:25,604 --> 00:11:27,670
from this point onwards.


