1
00:00:00,040 --> 00:00:02,640
Welcome to the Deep dive. 
Today we're getting into 

2
00:00:02,640 --> 00:00:06,720
something really fundamental in 
the tech world, the whole 

3
00:00:06,720 --> 00:00:10,960
practice of software testing. 
We're going to, you know, unpack

4
00:00:10,960 --> 00:00:14,200
why it's basically essential 
these days, absolutely critical.

5
00:00:14,200 --> 00:00:17,080
And our thinking today, it's 
guided by some great material. 

6
00:00:17,080 --> 00:00:21,040
Excerpts from Software 
Engineering a Modern Approach by

7
00:00:21,040 --> 00:00:23,400
Marco Tulio Valente. 
A really solid source. 

8
00:00:23,440 --> 00:00:27,680
So the mission today, we want to
look at how testing grew up 

9
00:00:27,680 --> 00:00:31,800
right from the old ways to agile
and then really dig into 

10
00:00:31,800 --> 00:00:35,200
automated tests, especially 
using this this model called the

11
00:00:35,200 --> 00:00:37,440
test pyramid. 
That pyramid's a great visual, 

12
00:00:37,440 --> 00:00:39,280
yeah. 
To kick things off, there's this

13
00:00:39,280 --> 00:00:41,320
quote from the book that just 
jumps out. 

14
00:00:41,760 --> 00:00:45,200
Code without tests is bad code. 
I mean, that's quite a 

15
00:00:45,200 --> 00:00:46,760
statement, isn't it, it? 
Absolutely is. 

16
00:00:46,800 --> 00:00:49,280
And it's it's way more than just
being catchy. 

17
00:00:49,320 --> 00:00:53,280
OK, The thing is, writing 
software, it's like building 

18
00:00:53,280 --> 00:00:55,240
something incredibly complex 
from the ground up. 

19
00:00:55,360 --> 00:00:58,080
I mean, software is one of those
intricate things humans make. 

20
00:00:58,320 --> 00:01:02,200
So it's just naturally going to 
have flaws, inconsistencies, 

21
00:01:02,800 --> 00:01:04,920
bugs. 
So testing isn't just, you know,

22
00:01:04,920 --> 00:01:06,800
checking things at the end. 
It's going to be part of the 

23
00:01:06,800 --> 00:01:09,800
building process itself. 
It's how you build in robustness

24
00:01:09,840 --> 00:01:12,680
from the start instead of just 
fixing things when they break 

25
00:01:12,680 --> 00:01:14,320
later. 
So the quote isn't just being 

26
00:01:14,320 --> 00:01:16,760
dramatic, it's about engineering
integrity. 

27
00:01:16,960 --> 00:01:18,680
Exactly. 
That's a perfect way to put it. 

28
00:01:18,800 --> 00:01:23,160
Engineering Integrity. 
OK, so if testing is so baked 

29
00:01:23,160 --> 00:01:25,840
into modern development, how did
it used to be? 

30
00:01:25,840 --> 00:01:29,960
What was the the old way? 
Oh, it was a totally different 

31
00:01:29,960 --> 00:01:32,200
world really. 
Think traditional waterfall 

32
00:01:32,200 --> 00:01:33,560
development. 
OK, waterfall. 

33
00:01:33,560 --> 00:01:36,920
Testing was its own separate 
box, a distinct phase. 

34
00:01:37,160 --> 00:01:41,600
You do requirements analysis, 
design, coding, then you test. 

35
00:01:41,640 --> 00:01:43,880
After everything else was 
supposedly done, pretty much. 

36
00:01:43,920 --> 00:01:46,400
And it often wasn't even the 
developers doing it, you had 

37
00:01:46,400 --> 00:01:49,400
separate test teams. 
Right, the QA department. 

38
00:01:49,480 --> 00:01:54,160
Exactly, and a lot of what they 
did was manual, like literally 

39
00:01:54,360 --> 00:01:57,040
clipping through the 
application, typing stuff in, 

40
00:01:57,040 --> 00:01:58,840
looking at the screen to see if 
it was right. 

41
00:01:58,840 --> 00:02:01,440
Since slow it was. 
And the main goal was simple, 

42
00:02:02,240 --> 00:02:06,160
find the bugs before this thing 
gets out to real users before 

43
00:02:06,160 --> 00:02:08,880
production. 
OK, so that was the old way, but

44
00:02:08,880 --> 00:02:11,400
then things changed. 
We talked about Agile a lot. 

45
00:02:11,880 --> 00:02:15,480
How did Agile just completely 
flip the script on testing? 

46
00:02:15,480 --> 00:02:18,280
Agile, yeah, it was a seismic 
shift for testing. 

47
00:02:18,440 --> 00:02:20,040
I mean fundamentally. 
How so? 

48
00:02:20,480 --> 00:02:23,720
Well, for starters, a huge chunk
of testing became automated. 

49
00:02:24,400 --> 00:02:27,920
Developers started writing code 
whose whole job was to test 

50
00:02:27,960 --> 00:02:30,920
other code. 
So the code tests itself in a 

51
00:02:30,920 --> 00:02:32,320
way. 
Kind of, yeah. 

52
00:02:32,600 --> 00:02:36,000
Programs became self testable. 
That's a massive change. 

53
00:02:36,000 --> 00:02:39,040
Definite way. 
And because of that, tests were 

54
00:02:39,040 --> 00:02:41,360
only done after coding. 
You could actually write the 

55
00:02:41,360 --> 00:02:43,600
test before you even wrote the 
class it was supposed to test. 

56
00:02:43,640 --> 00:02:45,800
Whoa, OK. 
Test Driven Development, right? 

57
00:02:45,800 --> 00:02:48,520
That's part of it, yeah. 
And those big separate test 

58
00:02:48,520 --> 00:02:52,000
teams mostly gone or they handle
very specialized stuff now. 

59
00:02:52,000 --> 00:02:54,800
So who does the test in? 
The developer, the person 

60
00:02:54,800 --> 00:02:56,840
writing the class, is now 
responsible for writing its 

61
00:02:56,840 --> 00:02:59,240
tests too. 
That makes sense responsibility 

62
00:02:59,240 --> 00:03:01,520
wise. 
It does, and testing took on new

63
00:03:01,520 --> 00:03:03,200
jobs. 
It wasn't just finding bugs 

64
00:03:03,200 --> 00:03:05,720
anymore. 
Tests became like living 

65
00:03:05,720 --> 00:03:08,280
documentation for the code. 
Documentation. 

66
00:03:08,640 --> 00:03:11,640
Well, a good test shows you 
exactly how a piece of code is 

67
00:03:11,640 --> 00:03:14,680
supposed to be used and what it 
should do better than comments 

68
00:03:14,680 --> 00:03:16,000
sometimes. 
Interesting. 

69
00:03:16,200 --> 00:03:19,360
Plus, they're crucial for 
checking if a bug fix over here 

70
00:03:19,520 --> 00:03:21,280
accidentally broke something 
over there. 

71
00:03:21,280 --> 00:03:24,080
You know, regression testing. 
Right, Run the tests, make sure 

72
00:03:24,080 --> 00:03:26,040
everything still passes exactly.
So. 

73
00:03:26,280 --> 00:03:29,520
Going back to that Michael 
Feathers quote, code without 

74
00:03:29,520 --> 00:03:33,280
tests is bad code in this agile 
world. 

75
00:03:33,280 --> 00:03:37,680
It's like if your code can't be 
easily tested, if it doesn't 

76
00:03:37,680 --> 00:03:41,240
have those automated tests, it's
just not good quality. 

77
00:03:41,240 --> 00:03:43,400
Maybe even legacy code from day 
one you've. 

78
00:03:43,400 --> 00:03:45,680
Nailed it. 
That's precisely the modern 

79
00:03:45,680 --> 00:03:47,600
view. 
And this focus on automated 

80
00:03:47,600 --> 00:03:51,320
tests wasn't just like a nice to
have, it became necessary. 

81
00:03:51,320 --> 00:03:53,600
Why necessary? 
Think about it, how could you 

82
00:03:53,600 --> 00:03:57,120
possibly manually test a complex
system that's changing maybe 

83
00:03:57,120 --> 00:03:59,040
multiple times a day? 
Yeah, impossible. 

84
00:03:59,040 --> 00:04:01,760
It's way too slow. 
Humans make mistakes, it costs 

85
00:04:01,760 --> 00:04:04,400
fortune, and you have to do it 
every single time anything 

86
00:04:04,400 --> 00:04:06,360
changes. 
Yeah, automation was the only 

87
00:04:06,360 --> 00:04:07,760
way to keep up. 
Right. 

88
00:04:07,760 --> 00:04:09,480
OK. 
So automation is key. 

89
00:04:10,000 --> 00:04:11,640
And you mentioned the test 
pyramid earlier. 

90
00:04:11,920 --> 00:04:14,160
Our source calls it an 
interesting way to classify 

91
00:04:14,160 --> 00:04:16,959
these automated tests. 
Mike Kuhn's idea, Yeah. 

92
00:04:16,959 --> 00:04:18,519
Mike Kuhn originally proposed 
it. 

93
00:04:18,519 --> 00:04:21,200
It's a really, really helpful 
model. 

94
00:04:21,600 --> 00:04:26,120
It basically sorts tests based 
on how big of a piece they're 

95
00:04:26,120 --> 00:04:28,440
looking at their granularity. 
Granularity, OK. 

96
00:04:28,480 --> 00:04:32,520
It breaks automated tests down 
into three main layers, Unit 

97
00:04:32,640 --> 00:04:35,880
integration and end to end. 
Unit integration end to end, 

98
00:04:35,880 --> 00:04:37,680
right? 
And the pyramid shape isn't just

99
00:04:37,680 --> 00:04:40,800
random, it tells you something 
about how many of each type you 

100
00:04:40,800 --> 00:04:43,360
should probably have. 
It guides the proportions. 

101
00:04:43,360 --> 00:04:45,400
OK, proportions are important, 
so let's start at the bottom, 

102
00:04:45,400 --> 00:04:46,840
the base of the pyramid. 
What's down there? 

103
00:04:47,040 --> 00:04:49,160
Down at the wide base, you've 
got unit tests. 

104
00:04:49,280 --> 00:04:52,280
Unit tests. 
These check the smallest 

105
00:04:52,280 --> 00:04:55,600
testable bits of your code. 
Usually that means a single 

106
00:04:55,600 --> 00:04:58,360
class, or maybe even just one 
method within a class. 

107
00:04:58,360 --> 00:05:00,400
OK, really small pieces. 
Exactly. 

108
00:05:00,440 --> 00:05:03,480
Yeah, and they test it 
completely alone, isolated from 

109
00:05:03,480 --> 00:05:05,080
everything else in the system. 
Isolated. 

110
00:05:05,080 --> 00:05:07,520
How do they do that? 
Often using things like mock 

111
00:05:07,520 --> 00:05:10,920
objects or stubs to pretend to 
be the other parts the class 

112
00:05:10,920 --> 00:05:12,240
might talk to. 
Got it. 

113
00:05:12,560 --> 00:05:15,040
And they're at the base because 
you should have the most of 

114
00:05:15,040 --> 00:05:18,280
these lots and lots. 
The general guideline like you 

115
00:05:18,280 --> 00:05:21,360
see in the source is maybe 
around 70% of your total 

116
00:05:21,360 --> 00:05:24,880
automated tests. 70% Wow. 
That's the vast majority. 

117
00:05:24,880 --> 00:05:26,400
Why so many? 
Because they have big 

118
00:05:26,400 --> 00:05:28,600
advantages. 
They're usually simple to write.

119
00:05:28,600 --> 00:05:32,120
They run super fast, like 
thousands and seconds, and if 

120
00:05:32,120 --> 00:05:34,880
one fails you know exactly where
the problem is. 

121
00:05:34,920 --> 00:05:37,000
Pinpoints the issue. 
Precisely. 

122
00:05:37,360 --> 00:05:39,800
They're like tiny little quality
checks on every single 

123
00:05:39,800 --> 00:05:41,320
component. 
Before you even assemble the 

124
00:05:41,320 --> 00:05:45,320
machine they check. 
Does this specific function give

125
00:05:45,320 --> 00:05:47,480
the right output for this 
specific input? 

126
00:05:47,600 --> 00:05:49,800
Makes sense. 
OK, base layer covered. 

127
00:05:50,080 --> 00:05:52,240
Moving up the pyramid, what's 
the next level? 

128
00:05:52,400 --> 00:05:54,480
In the middle we have 
integration tests. 

129
00:05:54,600 --> 00:05:56,240
Sometimes people call them 
service tests. 

130
00:05:56,240 --> 00:05:57,880
Integration tests. 
What do they integrate? 

131
00:05:58,040 --> 00:06:00,800
They check out different parts 
of your system work together, so

132
00:06:00,800 --> 00:06:04,240
instead of just one class in 
isolation, an integration test 

133
00:06:04,240 --> 00:06:06,840
might involve several classes, 
maybe from different modules or 

134
00:06:06,840 --> 00:06:09,040
packages. 
OK, testing the connection. 

135
00:06:09,040 --> 00:06:11,320
Exactly. 
They often verify a specific 

136
00:06:11,320 --> 00:06:14,720
piece of functionality or a 
transaction that scans across 

137
00:06:14,720 --> 00:06:16,920
these components. 
They might even interact with 

138
00:06:16,920 --> 00:06:19,760
external things like hitting a 
real database or calling an 

139
00:06:19,760 --> 00:06:23,640
external API. 
OK, so less isolated now. 

140
00:06:23,640 --> 00:06:27,120
Much less isolated, and because 
they involve more moving parts, 

141
00:06:27,120 --> 00:06:30,360
maybe external systems, they 
naturally take longer to write 

142
00:06:30,640 --> 00:06:33,200
and definitely longer to run 
than unit tests. 

143
00:06:33,680 --> 00:06:35,760
And proportion wise. 
The recommendation is usually 

144
00:06:35,760 --> 00:06:39,680
around, say, 20% of your tests. 
Significantly fewer than unit 

145
00:06:39,680 --> 00:06:44,360
tests, but still a good chunk. 
20% OK unit integration. 

146
00:06:45,600 --> 00:06:48,040
That brings us to the very top 
of the pyramid. 

147
00:06:48,200 --> 00:06:50,280
What's up there? 
At the pointy top you have end 

148
00:06:50,280 --> 00:06:52,520
to end tests. 
End to end, E to E. 

149
00:06:52,760 --> 00:06:54,280
Right. 
You might also hear them called 

150
00:06:54,280 --> 00:06:58,360
UI tests, User interface tests 
or sometimes system tests. 

151
00:06:58,360 --> 00:06:59,960
And what are they testing end to
end? 

152
00:07:00,080 --> 00:07:02,840
They try to simulate a real 
user's journey through the 

153
00:07:02,840 --> 00:07:05,520
entire application as 
realistically as possible. 

154
00:07:05,520 --> 00:07:07,360
Like someone actually using the 
software. 

155
00:07:07,360 --> 00:07:11,000
Pretty much clicking buttons, 
filling out forms, navigating 

156
00:07:11,000 --> 00:07:13,680
between screens, the whole 
sequence of actions a user might

157
00:07:13,680 --> 00:07:16,760
take to complete a task, logging
and doing something complex, 

158
00:07:16,760 --> 00:07:18,760
logging out. 
OK, that sounds comprehensive. 

159
00:07:18,760 --> 00:07:20,480
It is. 
That's the goal, yeah, But 

160
00:07:20,480 --> 00:07:24,280
they're at the top, the smallest
section, maybe only 10% of your 

161
00:07:24,280 --> 00:07:26,920
tests, for good reason. 
Why so few? 

162
00:07:27,040 --> 00:07:29,920
They're way more complex to set 
up and maintain, they take a 

163
00:07:29,920 --> 00:07:33,480
long time to run compared to the
others, and crucially, they tend

164
00:07:33,480 --> 00:07:35,120
to be. 
Brittle. 

165
00:07:35,160 --> 00:07:36,320
Brittle. 
What does that mean? 

166
00:07:36,400 --> 00:07:39,280
It means they break easily, 
often for reasons unrelated to 

167
00:07:39,280 --> 00:07:41,160
actual bugs in the logic. 
Like what? 

168
00:07:41,480 --> 00:07:44,200
Like if someone just changes the
layout of the user interface 

169
00:07:44,200 --> 00:07:47,600
slightly, moves a button, 
changes an ID, the test script 

170
00:07:47,600 --> 00:07:49,680
might fail even if the 
underlying functionality is 

171
00:07:49,680 --> 00:07:51,760
perfectly fine. 
So they need a lot of 

172
00:07:51,760 --> 00:07:52,800
maintenance. 
A lot. 

173
00:07:53,040 --> 00:07:55,520
That's why you want fewer of 
them, focusing them on the most 

174
00:07:55,520 --> 00:07:57,440
critical user paths. 
Got it. 

175
00:07:57,720 --> 00:08:00,000
That pyramid structure makes a 
lot more sense now, balancing 

176
00:08:00,000 --> 00:08:03,680
speed, scope, and stability. 
OK, one last thing from the 

177
00:08:03,680 --> 00:08:07,120
source that seems really 
important for just clear 

178
00:08:07,120 --> 00:08:09,440
communication. 
The difference between a defect 

179
00:08:09,440 --> 00:08:12,200
and a failure. 
Yes, this is a really useful 

180
00:08:12,200 --> 00:08:14,720
distinction. 
People often use bug for 

181
00:08:14,720 --> 00:08:17,320
everything but technically. 
Technically. 

182
00:08:18,000 --> 00:08:21,840
A defect or a bug is the actual 
mistake in the code. 

183
00:08:22,240 --> 00:08:25,240
It's where the code doesn't 
match its specification or 

184
00:08:25,240 --> 00:08:27,160
requirement. 
It's the flaw itself. 

185
00:08:27,280 --> 00:08:28,960
The error written down 
essentially. 

186
00:08:29,040 --> 00:08:31,640
Right, the incorrect line of 
code, the wrong logic. 

187
00:08:31,680 --> 00:08:34,880
Now a failure is what happens 
when that defective code 

188
00:08:34,880 --> 00:08:38,200
actually runs. 
And because it runs, the program

189
00:08:38,200 --> 00:08:41,200
does something wrong. 
It produces an incorrect result 

190
00:08:41,440 --> 00:08:44,480
or crashes, or just behaves 
unexpectedly. 

191
00:08:45,320 --> 00:08:47,920
So the failure is the observable
wrong thing. 

192
00:08:48,400 --> 00:08:51,160
Exactly. 
The defect is the hidden cause. 

193
00:08:51,520 --> 00:08:53,960
The failure is the visible 
symptom that occurs when the 

194
00:08:53,960 --> 00:08:56,680
defect gets triggered. 
You need the defect to be 

195
00:08:56,680 --> 00:08:59,800
executed to cause a failure. 
A defect is the cause, failure 

196
00:08:59,800 --> 00:09:01,800
is the effect. 
That's a great clarification. 

197
00:09:01,840 --> 00:09:03,600
Also, won't be on the same page,
yeah. 

198
00:09:03,600 --> 00:09:06,440
Definitely. 
Wow, this has been quite the 

199
00:09:06,440 --> 00:09:08,920
deep dive today. 
We've really covered a lot, you 

200
00:09:08,920 --> 00:09:11,840
know, starting with why testing 
is just non negotiable now, 

201
00:09:11,840 --> 00:09:15,080
tracing that big shift from 
waterfall separate phase to 

202
00:09:15,960 --> 00:09:18,160
Agile's integrated automated 
way. 

203
00:09:18,360 --> 00:09:21,120
A huge transformation. 
And then breaking down the test 

204
00:09:21,120 --> 00:09:23,760
pyramid, unit tests at the base,
integration in the middle and to

205
00:09:23,760 --> 00:09:26,680
end at the top, and finally 
getting that clear distinction 

206
00:09:26,680 --> 00:09:29,960
between a defect and a failure. 
Absolutely. 

207
00:09:30,240 --> 00:09:34,840
I think the main thing to take 
away is how central this 

208
00:09:34,840 --> 00:09:38,960
automated layered testing 
approach is to building good 

209
00:09:38,960 --> 00:09:41,360
software today. 
It's not an add on, It's 

210
00:09:41,360 --> 00:09:44,880
fundamental to quality, speed 
and just making sure things 

211
00:09:44,880 --> 00:09:46,280
don't fall apart. 
Totally agree. 

212
00:09:46,680 --> 00:09:49,480
So here's a final thought for 
you, our listener to chew on. 

213
00:09:49,520 --> 00:09:53,080
We heard that modern software is
becoming self testable, right? 

214
00:09:53,600 --> 00:09:57,120
And that tests also act as 
documentation for the production

215
00:09:57,120 --> 00:09:59,360
code. 
If those things are true, what 

216
00:09:59,360 --> 00:10:01,800
else could that mean for how we 
actually create software? 

217
00:10:02,040 --> 00:10:04,120
Does it open up new the 
possibilities beyond just 

218
00:10:04,120 --> 00:10:05,920
sketching bugs? 
Could it change what we even 

219
00:10:05,920 --> 00:10:10,400
think it means for software to 
be, you know, done or truly 

220
00:10:10,400 --> 00:10:11,880
complete? 
Interesting question. 

221
00:10:11,880 --> 00:10:13,680
Something to think about. 
We'll leave it there for this 

222
00:10:13,680 --> 00:10:15,000
time. 
Thanks for joining us on the 

223
00:10:15,000 --> 00:10:15,440
Deep Dive.
