1
00:00:00,040 --> 00:00:03,320
It really is incredible when you
stop and think about it, isn't 

2
00:00:03,320 --> 00:00:04,960
it? 
How much of our day-to-day life,

3
00:00:04,960 --> 00:00:09,920
I mean everything from waking up
to ordering lunch, managing 

4
00:00:09,920 --> 00:00:11,840
money. 
It just depends on software 

5
00:00:11,920 --> 00:00:14,840
working perfectly. 
We use so many apps, so many 

6
00:00:14,840 --> 00:00:17,920
services all the time and mostly
we just take it for granted. 

7
00:00:17,920 --> 00:00:21,360
But how often do we actually 
consider the quality underneath?

8
00:00:21,400 --> 00:00:24,360
You know, the hidden stuff that 
make sure it all works every 

9
00:00:24,360 --> 00:00:27,120
single time. 
So today, that's exactly what 

10
00:00:27,120 --> 00:00:28,720
we're doing. 
We're going to dive deep into 

11
00:00:28,720 --> 00:00:31,320
software testing and 
specifically we're zeroing in on

12
00:00:31,320 --> 00:00:33,920
unit tests. 
These are like the tiny building

13
00:00:33,920 --> 00:00:35,840
blocks checking individual code 
pieces. 

14
00:00:36,040 --> 00:00:38,680
We'll unpack what makes a good 
unit test, the best practices 

15
00:00:38,680 --> 00:00:42,280
and also look at the common 
pitfalls, the the test smells 

16
00:00:42,440 --> 00:00:45,120
that can make them less helpful.
Basically helping you understand

17
00:00:45,360 --> 00:00:47,800
what makes a test a real asset. 
Yeah, absolutely. 

18
00:00:47,800 --> 00:00:50,560
And it's not just, you know, 
academic theory, good unit 

19
00:00:50,560 --> 00:00:53,320
tests, well written ones, they 
give you really practical 

20
00:00:53,320 --> 00:00:54,960
benefits. 
They give them like a safety 

21
00:00:54,960 --> 00:00:56,360
net. 
They catch regressions. 

22
00:00:56,720 --> 00:00:59,880
That's when you make a change, 
maybe fix a bug, add something 

23
00:00:59,880 --> 00:01:02,320
new, and whoops, you've 
accidentally broken something 

24
00:01:02,320 --> 00:01:05,880
else that used to work fine. 
Yes, the dreaded regression. 

25
00:01:06,000 --> 00:01:08,520
Exactly. 
Good unit tests catch those, 

26
00:01:08,720 --> 00:01:11,640
ideally right away, and they 
also work as like living 

27
00:01:11,640 --> 00:01:14,920
documentation for your code. 
If you want to figure out what a

28
00:01:14,920 --> 00:01:18,320
piece of code should do, often 
the unit test is the clearest 

29
00:01:18,320 --> 00:01:21,200
explanation you'll find. 
And that's like big companies, 

30
00:01:21,520 --> 00:01:24,640
you know, Google, Meta. 
They don't just suggest unit 

31
00:01:24,640 --> 00:01:27,480
testing, they actually require 
it for code going into 

32
00:01:27,480 --> 00:01:30,680
production. 
They even have systems that flag

33
00:01:30,680 --> 00:01:33,360
code that doesn't have tests. 
It really shows how vital this 

34
00:01:33,360 --> 00:01:36,160
is in practice. 
OK, so a safety net and living 

35
00:01:36,160 --> 00:01:37,800
documentation that makes a lot 
of sense. 

36
00:01:37,800 --> 00:01:40,960
So to help developers write 
these effective, maintainable 

37
00:01:40,960 --> 00:01:43,720
tests, there's this acronym 
right FIRT. 

38
00:01:44,080 --> 00:01:46,360
That's the one. 
First, it's a great way to 

39
00:01:46,360 --> 00:01:49,400
remember the key characteristics
of a really solid unit test. 

40
00:01:49,560 --> 00:01:51,280
Let's break it down then. 
What's the FF? 

41
00:01:51,840 --> 00:01:54,840
Is for fast. 
Unit tests need to run 

42
00:01:54,840 --> 00:01:56,720
incredibly quickly. 
We're talking milliseconds. 

43
00:01:57,000 --> 00:01:58,920
Think about a developer coding, 
making changes. 

44
00:01:58,920 --> 00:02:01,800
They want instant feedback, run 
tests, see the result. 

45
00:02:01,880 --> 00:02:04,560
If that takes seconds, let alone
minutes, it just breaks their 

46
00:02:04,560 --> 00:02:07,080
concentration, their flow. 
Right, that friction adds up. 

47
00:02:07,080 --> 00:02:11,440
Massively across a whole team 
running tests dozens of times a 

48
00:02:11,440 --> 00:02:14,400
day. 
Slow tests can waste weeks, 

49
00:02:14,400 --> 00:02:16,600
maybe months of productivity 
over a year. 

50
00:02:16,880 --> 00:02:20,560
Now if you do have tests that 
are naturally slower, maybe they

51
00:02:20,920 --> 00:02:24,440
touch a database or talk to an 
external service, the usual fix 

52
00:02:24,440 --> 00:02:26,280
is to split them. 
You have your super fast suite 

53
00:02:26,280 --> 00:02:28,920
you run constantly and then a 
separate slower suite that maybe

54
00:02:28,920 --> 00:02:31,800
runs, you know, once a day or as
part of the build process. 

55
00:02:31,920 --> 00:02:34,240
OK, speed is key for that 
immediate feedback. 

56
00:02:34,520 --> 00:02:36,840
Got it. 
What about the I independent? 

57
00:02:36,960 --> 00:02:39,400
I stands for independent. 
This is super important. 

58
00:02:39,600 --> 00:02:42,040
It means the order your tests 
run in shouldn't matter at all. 

59
00:02:42,200 --> 00:02:44,280
Test A before test B or B before
A. 

60
00:02:44,280 --> 00:02:46,200
Same result every time. 
Why? 

61
00:02:47,040 --> 00:02:49,920
Because one test should never 
mess with the environment or 

62
00:02:49,920 --> 00:02:52,600
like global state that another 
test depends on. 

63
00:02:53,360 --> 00:02:56,400
So no shared data or settings 
between tests. 

64
00:02:56,560 --> 00:02:58,800
Exactly. 
Each test needs to set up its 

65
00:02:58,800 --> 00:03:02,000
own little isolated world, do 
its checks, and then clean up 

66
00:03:02,000 --> 00:03:03,920
completely. 
This isn't just about 

67
00:03:03,920 --> 00:03:05,400
predictability, though that's 
huge. 

68
00:03:05,800 --> 00:03:08,560
It also means you can run tests 
in parallel, you know, across 

69
00:03:08,720 --> 00:03:11,880
multiple CPU cores, which can 
drastically speed things up. 

70
00:03:11,880 --> 00:03:13,760
Makes sense. 
Parallel execution needs 

71
00:03:13,760 --> 00:03:16,960
independence. 
OK, next U is R reeatable. 

72
00:03:17,000 --> 00:03:21,200
This sounds like consistency. 
Recisely R for reeatable. 

73
00:03:21,560 --> 00:03:24,520
A test has to give you the same 
result ass Oregon fail every 

74
00:03:24,520 --> 00:03:26,560
single time you run it. 
Assuming the code hasn't changed

75
00:03:26,560 --> 00:03:28,600
of course. 
If it asses once, it should ass 

76
00:03:28,600 --> 00:03:30,960
1000 times. 
If it fails, it should always 

77
00:03:30,960 --> 00:03:33,120
fail. 
When tests don't do this, when 

78
00:03:33,120 --> 00:03:35,760
they sometimes pass and 
sometimes fail for seemingly no 

79
00:03:35,760 --> 00:03:39,480
reason, we call them flaky tests
or sometimes erratic tests. 

80
00:03:39,480 --> 00:03:41,360
Flaky tests? 
I've heard horror stories. 

81
00:03:41,360 --> 00:03:43,880
What causes them? 
They are developers nightmare. 

82
00:03:44,040 --> 00:03:46,680
Seriously. 
A common cause is often 

83
00:03:46,680 --> 00:03:48,960
concurrency issues. 
Like maybe you have an 

84
00:03:48,960 --> 00:03:50,680
asynchronous operation, 
something running in the 

85
00:03:50,680 --> 00:03:54,560
background and the test doesn't 
wait properly or waits for a 

86
00:03:54,560 --> 00:03:56,080
fixed time. 
That isn't always enough. 

87
00:03:56,600 --> 00:03:59,080
So maybe it calls a function 
that runs on another thread. 

88
00:03:59,360 --> 00:04:02,840
The test waits, say, one second,
but sometimes maybe the system's

89
00:04:02,840 --> 00:04:05,120
busy. 
That function takes 1.1 seconds.

90
00:04:05,240 --> 00:04:08,600
Boom, the test fails. 
But not because the code is 

91
00:04:08,600 --> 00:04:11,080
wrong, just because the timing 
was off that one time. 

92
00:04:11,200 --> 00:04:13,920
So it's actually a bug in the 
test, not the application code 

93
00:04:13,920 --> 00:04:15,360
itself. 
That sounds incredibly 

94
00:04:15,360 --> 00:04:16,480
frustrating. 
What's the impact? 

95
00:04:16,480 --> 00:04:19,079
Oh, it's hugely frustrating. 
And it's, well, surprisingly 

96
00:04:19,079 --> 00:04:20,800
common. 
Google did a study on their own 

97
00:04:20,800 --> 00:04:22,520
code. 
Massive code base, right? 

98
00:04:22,760 --> 00:04:26,640
They found something like 16% of
their tests showed non 

99
00:04:26,640 --> 00:04:29,640
deterministic behavior. 
Wow, 16%, yeah. 

100
00:04:30,120 --> 00:04:33,280
Think about that. 
Nearly one in six test failures 

101
00:04:33,280 --> 00:04:37,200
could be a false alarm. 
Developers waste hours chasing 

102
00:04:37,200 --> 00:04:39,520
ghosts, investigating failures 
that aren't real bugs. 

103
00:04:39,520 --> 00:04:43,080
It slows everything down, and 
worse, it erodes trust. 

104
00:04:43,560 --> 00:04:46,960
If your tests cry wolf all the 
time, developers start ignoring 

105
00:04:46,960 --> 00:04:49,040
them. 
Then when a real failure 

106
00:04:49,040 --> 00:04:52,280
happens, it might get missed. 
It's a productivity killer, yes,

107
00:04:52,440 --> 00:04:54,800
but it also just destroys 
confidence in your safety net. 

108
00:04:55,120 --> 00:04:56,800
That Google number really hits 
home. 

109
00:04:56,840 --> 00:04:59,920
OK, so we need fast, 
independent, repeatable tests. 

110
00:04:59,960 --> 00:05:02,840
What's S self checking? 
Yes, S is for self checking. 

111
00:05:03,200 --> 00:05:05,760
This basically means that test 
results should be obvious 

112
00:05:06,120 --> 00:05:08,200
immediately. 
A developer shouldn't need to 

113
00:05:08,200 --> 00:05:11,560
like manually read through log 
files or compare output data to 

114
00:05:11,560 --> 00:05:13,400
figure out if the test passed or
failed. 

115
00:05:13,680 --> 00:05:16,080
The test runner, you know the 
tool integrated into their 

116
00:05:16,080 --> 00:05:18,960
coding environment should just 
tell them, usually with colors. 

117
00:05:18,960 --> 00:05:22,280
Green for pass, red for fail. 
Simple visual feedback. 

118
00:05:22,560 --> 00:05:24,960
And if it fails? 
Crucially, if it fails, it needs

119
00:05:24,960 --> 00:05:27,520
to point you exactly to the 
line, the specific assertion, or

120
00:05:27,520 --> 00:05:29,560
check within that test that 
failed. 

121
00:05:29,960 --> 00:05:32,840
That makes debugging way faster.
No guesswork. 

122
00:05:33,000 --> 00:05:36,520
That instant feedback loop again
seems vital. 

123
00:05:36,960 --> 00:05:42,080
OK last 1 T for timely. 
This sounds like it relates to 

124
00:05:42,080 --> 00:05:44,480
when you write the tests. 
It does indeed. 

125
00:05:44,760 --> 00:05:48,040
T for timely means you should 
write your test early, really 

126
00:05:48,040 --> 00:05:50,560
early ideally. 
And this is a cornerstone of 

127
00:05:50,560 --> 00:05:53,080
practices like Test Driven 
Development or TDD. 

128
00:05:53,160 --> 00:05:55,600
Yeah, you write the test before 
you write the production code. 

129
00:05:55,600 --> 00:05:57,560
It's testing. 
Write the test first, yeah? 

130
00:05:58,000 --> 00:06:00,720
It sounds a bit backward maybe, 
but it forces you to think 

131
00:06:00,720 --> 00:06:02,920
really clearly about what the 
code is supposed to do. 

132
00:06:02,920 --> 00:06:05,720
What is requirements are before 
you start implementing it. 

133
00:06:06,000 --> 00:06:09,320
It often leads to to cleaner, 
better designed and naturally 

134
00:06:09,320 --> 00:06:11,280
more testable code right from 
the start. 

135
00:06:11,520 --> 00:06:15,600
OK, F IRST, Fast, independent, 
repeatable, self checking, 

136
00:06:15,600 --> 00:06:17,920
timely. 
That's a really solid framework,

137
00:06:18,200 --> 00:06:19,880
but like you said, it's not 
always perfect. 

138
00:06:19,880 --> 00:06:22,920
Sometimes things go a bit wrong,
even if not technically broken. 

139
00:06:23,280 --> 00:06:25,600
These are the test smells. 
Exactly. 

140
00:06:25,680 --> 00:06:28,400
Test smells. 
It's an analogy to code smells 

141
00:06:28,400 --> 00:06:31,480
in your main application code. 
They aren't necessarily bugs, 

142
00:06:31,720 --> 00:06:35,360
not strict anti patterns always,
but they're warning signs, hints

143
00:06:35,360 --> 00:06:38,200
that maybe your test could be 
better, simpler, clearer, more 

144
00:06:38,200 --> 00:06:40,920
efficient. 
So not rules, but prompts to 

145
00:06:40,920 --> 00:06:43,760
maybe refactor the test. 
Precisely prompts to just take a

146
00:06:43,760 --> 00:06:45,440
look and ask. 
Is there a better way here? 

147
00:06:45,960 --> 00:06:49,000
One really common smell is the 
obscure test. 

148
00:06:49,560 --> 00:06:51,960
This is a test that's just hard 
to understand. 

149
00:06:51,960 --> 00:06:55,280
Maybe it's really long or the 
logic is super complex and 

150
00:06:55,280 --> 00:06:57,200
tangled. 
Remember we said test or 

151
00:06:57,200 --> 00:07:00,080
documentation. 
Right living documentation. 

152
00:07:00,080 --> 00:07:02,200
Well, if the test itself is 
confusing, it fails as 

153
00:07:02,200 --> 00:07:04,840
documentation. 
And it fails as a good test 

154
00:07:05,120 --> 00:07:08,320
because if it breaks, figuring 
out why is a major headache. 

155
00:07:08,560 --> 00:07:11,280
It makes maintenance harder, 
onboarding new people slower, 

156
00:07:11,480 --> 00:07:14,800
just general friction. 
The ideal usually is for a test 

157
00:07:14,800 --> 00:07:17,960
to check one specific thing. 
One requirement makes its 

158
00:07:17,960 --> 00:07:20,040
purpose crystal clear. 
Keep it focused. 

159
00:07:20,560 --> 00:07:22,960
OK, that makes sense. 
What's another smell to look out

160
00:07:22,960 --> 00:07:24,640
for? 
Another big one is tests with 

161
00:07:24,640 --> 00:07:27,560
conditional logic. 
So tests that have if statements

162
00:07:27,560 --> 00:07:30,400
or switch cases or loops inside 
the test method itself. 

163
00:07:30,400 --> 00:07:33,160
Why is that bad? 
Conditionals are normal in code.

164
00:07:33,360 --> 00:07:36,360
They are in production code, 
yes, but in a unit test you 

165
00:07:36,360 --> 00:07:38,040
generally want the code to be 
linear. 

166
00:07:38,360 --> 00:07:41,440
Just a straight path, set 
something up, execute the code 

167
00:07:41,440 --> 00:07:43,800
under test, check the result. 
Simple. 

168
00:07:44,360 --> 00:07:46,680
When you add ifs or loops, you 
add branching. 

169
00:07:47,080 --> 00:07:49,840
It makes it much harder to see 
at a glance exactly what 

170
00:07:49,840 --> 00:07:53,320
scenario that test is covering, 
which path was taken or all 

171
00:07:53,320 --> 00:07:56,800
conditions even being tested. 
It obscures the tests intent and

172
00:07:56,800 --> 00:07:58,280
makes it harder to read and 
trust. 

173
00:07:59,240 --> 00:08:02,600
OK, so aim for straight line 
code and tests for maximum 

174
00:08:02,600 --> 00:08:03,760
clarity. 
Got it. 

175
00:08:04,160 --> 00:08:06,000
Any others? 
The other classic one is code 

176
00:08:06,000 --> 00:08:08,520
duplication. 
Just like you avoid copying and 

177
00:08:08,520 --> 00:08:11,480
pasting code in your main 
application, you should avoid it

178
00:08:11,480 --> 00:08:14,440
in your tests too. 
If you see the same chunk of 

179
00:08:14,440 --> 00:08:17,800
setup code or the same sequence 
of actions repeated across 

180
00:08:17,800 --> 00:08:19,800
multiple test methods, that's a 
smell. 

181
00:08:20,000 --> 00:08:21,440
Why? 
Seems like it might be faster 

182
00:08:21,440 --> 00:08:24,360
sometimes just to copy paste. 
It might seem faster initially, 

183
00:08:24,360 --> 00:08:27,240
but it makes your test sweep 
bloated and worse if that 

184
00:08:27,240 --> 00:08:29,080
duplicated logic needs to change
later. 

185
00:08:29,440 --> 00:08:32,520
Maybe an API detail changes or a
set of step needs updating. 

186
00:08:32,520 --> 00:08:35,120
You have to find and fix it in 
every single place you copied 

187
00:08:35,120 --> 00:08:37,280
it. 
It's easy to miss one, leading 

188
00:08:37,280 --> 00:08:39,280
to inconsistent tests and 
potential errors. 

189
00:08:39,520 --> 00:08:41,240
Right maintenance nightmare. 
Exactly. 

190
00:08:41,559 --> 00:08:44,680
Often you can fix duplication by
creating shared helper methods 

191
00:08:44,800 --> 00:08:47,480
or using setup and tear down 
functions provided by your 

192
00:08:47,480 --> 00:08:50,920
testing framework. 
Keep it DRY, don't repeat 

193
00:08:50,920 --> 00:08:52,880
yourself. 
Applies to test too. 

194
00:08:53,080 --> 00:08:57,160
Obscure test, conditional logic,
code duplication, great 

195
00:08:57,160 --> 00:08:59,560
warnings, and I think it's worth
repeating what you said. 

196
00:08:59,560 --> 00:09:01,360
These are smells, not absolute 
commandments. 

197
00:09:01,360 --> 00:09:02,640
They're flags. 
Totally. 

198
00:09:02,680 --> 00:09:05,240
Yeah, they're signals to pause 
and think. 

199
00:09:05,800 --> 00:09:08,080
Could this test be simpler? 
Shorter. 

200
00:09:08,800 --> 00:09:10,960
More direct? 
Less repetitive? 

201
00:09:11,200 --> 00:09:14,320
Refactoring your tests is just 
as important as refactoring your

202
00:09:14,320 --> 00:09:16,320
production code. 
Keep them clean, keep them 

203
00:09:16,320 --> 00:09:18,320
understandable. 
It's an ongoing effort. 

204
00:09:18,480 --> 00:09:20,760
OK, that leads nicely into 
something that, well, people 

205
00:09:20,760 --> 00:09:22,800
definitely discuss a lot in 
testing circles. 

206
00:09:23,200 --> 00:09:26,080
How many assert statements 
should you have in a single test

207
00:09:26,080 --> 00:09:27,800
method? 
Is there a magic number? 

208
00:09:28,040 --> 00:09:30,680
Yeah, that's a perennial debate.
There are definitely strong 

209
00:09:30,680 --> 00:09:33,040
opinions. 
A very common guideline, almost 

210
00:09:33,040 --> 00:09:36,960
a rule for some folks, is at 
most one assert per test. 

211
00:09:37,120 --> 00:09:38,520
One assert. 
Why so strict? 

212
00:09:38,520 --> 00:09:41,080
The argument is all about 
clarity and pinpointing 

213
00:09:41,080 --> 00:09:44,120
failures. 
If you stick to 1 assert, your 

214
00:09:44,120 --> 00:09:47,440
test is incredibly focused. 
For example, testing a stack 

215
00:09:47,440 --> 00:09:49,560
data structure. 
You wouldn't have one test 

216
00:09:49,560 --> 00:09:52,160
checking both that it's empty 
initially and that it has one 

217
00:09:52,160 --> 00:09:54,720
item after you push something. 
Instead, you have two tests. 

218
00:09:54,720 --> 00:09:58,120
Test one test eyes empty 
initially 1 Assert checking size

219
00:09:58,120 --> 00:10:01,400
is 0. 
Test 2 Test push ads item, 

220
00:10:01,400 --> 00:10:04,960
assert size is 1. 
After a push, if test push ads 

221
00:10:04,960 --> 00:10:07,440
item fails, you know exactly 
what went wrong. 

222
00:10:07,680 --> 00:10:09,200
The push didn't work as 
expected. 

223
00:10:09,360 --> 00:10:11,600
OK, I see the appeal super 
clear. 

224
00:10:11,600 --> 00:10:13,960
Failure messages makes debugging
faster. 

225
00:10:13,960 --> 00:10:16,160
Exactly. 
If you had multiple asserts in 

226
00:10:16,160 --> 00:10:19,000
one test and it fails, you might
have to dig a bit to figure out 

227
00:10:19,000 --> 00:10:22,160
which assert failed. 
Was the initial state wrong, or 

228
00:10:22,160 --> 00:10:24,320
did the action not produce the 
right final state? 

229
00:10:24,560 --> 00:10:26,520
One assert Remove that 
ambiguity. 

230
00:10:26,800 --> 00:10:29,600
Is it always practical? 
Does being that strict sometimes

231
00:10:29,600 --> 00:10:32,600
create more work or make tests 
less readable in other ways? 

232
00:10:32,760 --> 00:10:34,840
That's the counter argument, and
it's a valid 1. 

233
00:10:35,440 --> 00:10:37,760
You definitely shouldn't be 
dogmatic about the one assert 

234
00:10:37,760 --> 00:10:39,920
rule. 
There are situations where 

235
00:10:39,920 --> 00:10:42,920
multiple asserts and one test 
are perfectly fine, even 

236
00:10:42,920 --> 00:10:45,400
preferable. 
Think about testing a function, 

237
00:10:45,400 --> 00:10:49,000
say get book details, that 
returns a complex object 

238
00:10:49,000 --> 00:10:52,440
representing a book. 
This book object have a title, 

239
00:10:52,680 --> 00:10:55,680
an author, a ublication year, 
maybe a ublisher. 

240
00:10:55,680 --> 00:10:58,000
Right, multile related pieces of
data. 

241
00:10:58,080 --> 00:10:59,800
Exactly. 
It makes perfect sense to have 

242
00:10:59,800 --> 00:11:04,520
one test method forget book 
details and then have say 4A 

243
00:11:04,520 --> 00:11:07,200
suit statements inside it. 
One checking the title is 

244
00:11:07,200 --> 00:11:09,280
correct, one for the author, one
for the year, 1 for the 

245
00:11:09,280 --> 00:11:10,640
publisher. 
These are all checking different

246
00:11:10,640 --> 00:11:13,200
aspects of the single logical 
result of that function called 

247
00:11:13,200 --> 00:11:15,440
the book object. 
Splitting that into four 

248
00:11:15,440 --> 00:11:18,360
separate tests would feel really
artificial and just add a lot of

249
00:11:18,360 --> 00:11:20,600
repetitive setup code. 
That makes total sense. 

250
00:11:20,600 --> 00:11:22,960
You're testing 1 cohesive unit 
of data OK? 

251
00:11:23,160 --> 00:11:26,240
Are there other examples where 
multiple asserts are OK? 

252
00:11:26,400 --> 00:11:28,920
Yeah, another common one is 
testing a simple method with 

253
00:11:28,920 --> 00:11:31,720
several related input cases 
where you can check them all 

254
00:11:31,720 --> 00:11:34,520
linearly without needing if 
statements in the test. 

255
00:11:35,440 --> 00:11:38,320
Imagine a simple string utility 
function like strings dot 

256
00:11:38,320 --> 00:11:40,160
repeat. 
You give it a string and a 

257
00:11:40,160 --> 00:11:42,880
number and it repeats the string
that many times. 

258
00:11:43,080 --> 00:11:46,240
OK, like repeat a three gives 
AAA. 

259
00:11:46,320 --> 00:11:49,920
Right, you could have one test 
method for repeat and inside it 

260
00:11:50,120 --> 00:11:52,560
assert that repeat. 
AI Arrow gives an empty string 

261
00:11:52,640 --> 00:11:57,280
repeat A1 gives a repeat, A2 
gives a, a repeat, a three gives

262
00:11:57,280 --> 00:11:59,080
AAA. 
These are all testing the core 

263
00:11:59,080 --> 00:12:01,680
logic of repeat with different 
simple inputs. 

264
00:12:02,040 --> 00:12:05,720
It's linear, easy to read, and 
efficiently covers several basic

265
00:12:05,720 --> 00:12:08,920
cases in one go. 
Trying to make 4 separate tests 

266
00:12:08,920 --> 00:12:11,440
for that might be overkill. 
So it really boils down to 

267
00:12:11,440 --> 00:12:14,240
judgement, doesn't it? 
The principle of 1 assert is a 

268
00:12:14,240 --> 00:12:16,760
great guideline for clarity, 
especially for pinpointing 

269
00:12:16,760 --> 00:12:19,280
failures, but you have to apply 
it sensibly. 

270
00:12:19,480 --> 00:12:22,200
Sometimes checking multiple 
related properties of a single 

271
00:12:22,200 --> 00:12:25,440
result or checking multiple 
simple inputs for one function 

272
00:12:25,560 --> 00:12:27,680
within one test just makes more 
practical sense. 

273
00:12:28,120 --> 00:12:31,600
That's exactly it. 
Principles are guides, not rigid

274
00:12:31,600 --> 00:12:33,680
laws. 
The ultimate goal is tests that 

275
00:12:33,680 --> 00:12:37,400
are clear, effective, 
maintainable, and actually help 

276
00:12:37,400 --> 00:12:40,080
your team build better software 
faster. 

277
00:12:40,400 --> 00:12:42,000
It's about finding that right 
balance. 

278
00:12:42,120 --> 00:12:44,360
Well, this has been a fantastic 
deep dive. 

279
00:12:44,400 --> 00:12:47,320
I think understanding those 
first principles really gives 

280
00:12:47,320 --> 00:12:51,000
you a solid foundation for 
writing good, robust tests, and 

281
00:12:51,000 --> 00:12:53,600
knowing about the test smells 
gives you the awareness to keep 

282
00:12:53,600 --> 00:12:56,080
improving them overtime, making 
sure they stay valuable. 

283
00:12:56,080 --> 00:12:57,920
Absolutely, thanks for digging 
into this with me. 

284
00:12:57,920 --> 00:13:00,240
These ideas really are 
fundamental if you're serious 

285
00:13:00,240 --> 00:13:03,000
about software quality today. 
Thanks everyone for joining us 

286
00:13:03,000 --> 00:13:04,160
on this deep dive.
