1
00:00:00,040 --> 00:00:03,280
Welcome to the Deep Dive, where 
we take your sources and extract

2
00:00:03,280 --> 00:00:07,960
the most important insights. 
Today we're embarking on a deep 

3
00:00:07,960 --> 00:00:11,360
dive into a really critical 
layer of software quality 

4
00:00:11,360 --> 00:00:15,600
assurance integration tests. 
Our guide for this is Software 

5
00:00:15,600 --> 00:00:18,880
Engineering a Modern Approach by
Marco Tulio Valente. 

6
00:00:19,440 --> 00:00:22,720
We're focusing specifically on 
Section 8.8, which is all about 

7
00:00:22,720 --> 00:00:25,520
this topic. 
Our mission really is to unpack 

8
00:00:25,520 --> 00:00:27,920
what these tests actually are, 
why there's such an essential 

9
00:00:27,920 --> 00:00:30,800
bridge between, you know, 
individual code units and a 

10
00:00:30,800 --> 00:00:34,200
fully working system, and what 
value they bring to developers 

11
00:00:34,200 --> 00:00:36,280
and, well, to you as the end 
user. 

12
00:00:36,960 --> 00:00:39,520
Now, we've often discussed unit 
tests on the show, those 

13
00:00:39,520 --> 00:00:42,600
microscopic checks on single 
code components, making sure 

14
00:00:42,600 --> 00:00:45,480
each little piece works 
perfectly in isolation, like 

15
00:00:45,480 --> 00:00:47,880
checking just one gear in a 
clockwork mechanism, maybe. 

16
00:00:47,880 --> 00:00:49,880
Exactly. 
But what happens when that gear 

17
00:00:49,880 --> 00:00:52,000
needs to mesh with the next one 
in the spring and the whole 

18
00:00:52,000 --> 00:00:53,400
assembly? 
What happens when these 

19
00:00:53,400 --> 00:00:55,880
perfectly working individual 
parts need to interact, 

20
00:00:56,200 --> 00:00:58,800
especially with things outside 
the code like databases or 

21
00:00:58,800 --> 00:00:59,920
external systems? 
Right. 

22
00:00:59,960 --> 00:01:02,360
And that's precisely where 
integration tests, or sometimes 

23
00:01:02,360 --> 00:01:04,200
people call them service tests, 
come into play. 

24
00:01:04,280 --> 00:01:07,200
They step onto the stage here, 
this intermediate level of 

25
00:01:07,200 --> 00:01:10,480
testing. 
It's just vital for getting from

26
00:01:10,480 --> 00:01:13,840
those isolated parts to a 
cohesive working hole. 

27
00:01:14,080 --> 00:01:16,840
Yeah, if you think about the the
bigger picture of software 

28
00:01:16,840 --> 00:01:19,720
testing, integration tests 
really do fill that crucial 

29
00:01:19,720 --> 00:01:22,000
middle ground. 
Unit tests, like you said, 

30
00:01:22,000 --> 00:01:25,000
they're focused on the smallest 
bits, maybe a single class, a 

31
00:01:25,000 --> 00:01:26,920
single function, totally 
isolated. 

32
00:01:27,760 --> 00:01:29,520
Integration tests, they bump up 
the scope. 

33
00:01:29,840 --> 00:01:32,800
Their main goal is to exercise a
whole service or maybe a 

34
00:01:32,800 --> 00:01:34,400
significant feature of the 
system. 

35
00:01:34,520 --> 00:01:36,840
So more complex. 
Definitely. 

36
00:01:36,960 --> 00:01:38,640
It means they involve multiple 
classes. 

37
00:01:38,640 --> 00:01:41,520
Sometimes these classes are even
from different packages, you 

38
00:01:41,520 --> 00:01:43,440
know different modules or parts 
of the application. 

39
00:01:43,920 --> 00:01:45,840
But the real defining 
characteristic, and where the 

40
00:01:45,840 --> 00:01:48,640
complexity often lies, is their 
interaction with real 

41
00:01:48,640 --> 00:01:50,320
dependencies. 
Real ones. 

42
00:01:50,640 --> 00:01:53,600
Not fake exactly. 
We're talking actual databases, 

43
00:01:53,800 --> 00:01:57,800
live remote services it needs to
call, external API's, message 

44
00:01:57,800 --> 00:02:01,320
queues, that kind of thing. 
Unlike unit tests which often 

45
00:02:01,320 --> 00:02:03,480
use mocks or simulated versions 
of these things. 

46
00:02:03,480 --> 00:02:05,360
Right. 
To keep them isolated precisely,

47
00:02:06,320 --> 00:02:09,400
integration tests insist on 
using the real deal. 

48
00:02:10,240 --> 00:02:12,440
They want to see how your code 
actually behaves when it's 

49
00:02:12,440 --> 00:02:15,760
talking to the real database 
it'll use in production or the 

50
00:02:15,760 --> 00:02:17,880
actual third party service it 
relies on. 

51
00:02:18,120 --> 00:02:20,360
That feels like a really 
important distinction. 

52
00:02:20,600 --> 00:02:24,080
So for the developers building 
these systems and I guess for us

53
00:02:24,120 --> 00:02:26,800
using them too, what does that 
mean practically? 

54
00:02:26,800 --> 00:02:28,720
How does it change their testing
routine? 

55
00:02:28,720 --> 00:02:30,400
Oh it. 
Absolutely changes things. 

56
00:02:30,480 --> 00:02:33,960
The very nature of these tests 
means a different scale and 

57
00:02:33,960 --> 00:02:37,040
definitely a different frequency
because they involve more moving

58
00:02:37,040 --> 00:02:41,400
parts, real external systems, 
maybe network calls, they're 

59
00:02:41,400 --> 00:02:45,760
just inherently more complex and
consequently they take 

60
00:02:45,760 --> 00:02:48,680
significantly more time to run 
compared to those super fast 

61
00:02:48,680 --> 00:02:49,880
unit tests. 
Right. 

62
00:02:49,880 --> 00:02:52,440
Unit tests can run in 
milliseconds sometimes. 

63
00:02:52,440 --> 00:02:53,880
Exactly. 
Think about the difference 

64
00:02:53,880 --> 00:02:57,160
between, say, flicking a single 
light switch versus firing up 

65
00:02:57,160 --> 00:03:00,080
the entire electrical system of 
a building check and the lights,

66
00:03:00,200 --> 00:03:02,480
the AC, the elevators, 
everything working together. 

67
00:03:02,480 --> 00:03:04,920
It just takes longer. 
OK, so if they're slower I'm 

68
00:03:04,920 --> 00:03:07,320
guessing they don't run on them 
like after every tiny code 

69
00:03:07,320 --> 00:03:08,720
change. 
You're spot on. 

70
00:03:09,080 --> 00:03:12,200
Developers might run their unit 
tests constantly, maybe hundreds

71
00:03:12,200 --> 00:03:15,200
of times a day. 
Integration tests much less 

72
00:03:15,200 --> 00:03:19,120
frequently, maybe a few times a 
day, or perhaps as part of an 

73
00:03:19,120 --> 00:03:21,960
automated build process like a 
continuous integration pipeline 

74
00:03:22,400 --> 00:03:25,200
before things get deployed. 
So there's a trade off speed 

75
00:03:25,200 --> 00:03:27,640
versus depth. 
That's a great way to put it. 

76
00:03:27,640 --> 00:03:29,680
Speed versus depth of 
validation. 

77
00:03:30,120 --> 00:03:33,480
There's slower, yes, but the 
kind of validation they provide 

78
00:03:33,480 --> 00:03:36,440
is invaluable. 
They catch a whole category of 

79
00:03:36,440 --> 00:03:39,240
bugs that unit tests just 
physically cannot find. 

80
00:03:39,480 --> 00:03:42,320
Like what kind of bugs? 
Well, think about things like 

81
00:03:42,320 --> 00:03:45,560
misconfigurations between 
different services, or maybe the

82
00:03:45,560 --> 00:03:48,280
structure. 
The schema of the database 

83
00:03:48,600 --> 00:03:52,400
doesn't quite match what the 
code expects or network issues 

84
00:03:52,400 --> 00:03:55,840
causing timeouts or subtle 
problems where your code isn't 

85
00:03:55,840 --> 00:03:58,760
quite using an external services
API correctly. 

86
00:03:59,080 --> 00:04:01,840
These are the kinds of problems 
that often only show up when all

87
00:04:01,840 --> 00:04:04,680
the pieces are actually trying 
to talk to each other for real 

88
00:04:04,960 --> 00:04:08,280
and finding those late, like in 
production, that can be really 

89
00:04:08,280 --> 00:04:10,960
painful and expensive to fix. 
Yeah, I can imagine. 

90
00:04:10,960 --> 00:04:14,640
OK, this abstract idea starts to
make more sense now, and I think

91
00:04:14,640 --> 00:04:17,839
the source helps here, right? 
It gives a concrete example. 

92
00:04:17,839 --> 00:04:19,880
It does, yeah. 
A really good one actually. 

93
00:04:20,160 --> 00:04:22,000
It uses AQ and a form 
application. 

94
00:04:22,360 --> 00:04:25,080
Like a mini stack overflow. 
Pretty much, yeah. 

95
00:04:25,240 --> 00:04:27,400
A simplified version. 
And at the core of this app 

96
00:04:27,400 --> 00:04:30,560
there's a class they call Forum.
Think of it as the main 

97
00:04:30,560 --> 00:04:32,560
controller. 
It handles the basic stuff, 

98
00:04:33,200 --> 00:04:35,840
adding a new question listing 
all the questions that have been

99
00:04:35,840 --> 00:04:37,160
asked. 
OK, simple enough. 

100
00:04:37,240 --> 00:04:39,440
Right so picture this forum 
class. 

101
00:04:39,840 --> 00:04:43,440
It has methods like add question
and list all questions. 

102
00:04:44,000 --> 00:04:46,880
An integration test for this 
system is designed to actually 

103
00:04:46,880 --> 00:04:50,840
use these methods in a realistic
set, meaning it interacts 

104
00:04:50,840 --> 00:04:53,840
directly with the real database 
where the questions are stored. 

105
00:04:54,080 --> 00:04:57,360
I see and the source material 
shows how they set up a specific

106
00:04:57,360 --> 00:04:59,160
integration test class to do 
this. 

107
00:04:59,760 --> 00:05:02,720
Before each test runs, there's 
this really important setup 

108
00:05:02,720 --> 00:05:04,800
step. 
It makes sure every test starts 

109
00:05:04,800 --> 00:05:07,680
with a clean slate. 
First it truncates the database 

110
00:05:07,680 --> 00:05:09,440
tables. 
Basically it empties them out 

111
00:05:09,440 --> 00:05:10,560
completely. 
Wipes and clean. 

112
00:05:10,760 --> 00:05:13,720
Wipes and clean. 
Then it creates a new instance 

113
00:05:13,720 --> 00:05:17,920
of the form class and gives it a
live, real connection to that 

114
00:05:17,920 --> 00:05:22,000
now empty database. 
And just as importantly, after 

115
00:05:22,000 --> 00:05:25,840
each test finishes, whether it 
passed or failed, a cleanup step

116
00:05:26,000 --> 00:05:28,600
runs automatically to close that
database connection. 

117
00:05:28,880 --> 00:05:32,160
Why is that setup and tear down 
so critical? 

118
00:05:32,200 --> 00:05:34,360
It's all about consistency and 
reliability. 

119
00:05:34,360 --> 00:05:35,840
You want each test to be 
independent. 

120
00:05:36,280 --> 00:05:39,520
You don't want data leftover 
from a previous test run to mess

121
00:05:39,520 --> 00:05:40,840
up the results of the current 
one. 

122
00:05:41,080 --> 00:05:43,280
That clean slate is key. 
Makes sense. 

123
00:05:43,720 --> 00:05:47,360
So within this Q&A form example,
what specific things are the 

124
00:05:47,360 --> 00:05:49,640
tests actually checking? 
What scenarios? 

125
00:05:49,880 --> 00:05:52,400
The example highlights 2 really 
clear scenarios. 

126
00:05:52,400 --> 00:05:54,080
The first one is, well, pretty 
fundamental. 

127
00:05:54,240 --> 00:05:56,840
It just checks that if the 
database is empty right after 

128
00:05:56,840 --> 00:06:00,240
that cleaning step, calling list
all questions actually returns 

129
00:06:00,240 --> 00:06:02,920
an empty list. 
It confirms the initial state is

130
00:06:02,920 --> 00:06:04,440
correct. 
Simple baseline checkout 

131
00:06:04,440 --> 00:06:06,440
exactly. 
The second test is more 

132
00:06:06,440 --> 00:06:08,720
involved. 
It simulates more typical user 

133
00:06:08,720 --> 00:06:11,200
action. 
It uses the add question method 

134
00:06:11,200 --> 00:06:13,200
to add 3 different questions to 
the forum. 

135
00:06:13,440 --> 00:06:15,680
Then it calls list all questions
to get them back. 

136
00:06:15,920 --> 00:06:19,160
But it doesn't just check that 
it got three questions back, it 

137
00:06:19,160 --> 00:06:21,400
goes deeper. 
It actually verifies the 

138
00:06:21,400 --> 00:06:23,840
content. 
The text of each question 

139
00:06:23,840 --> 00:06:26,320
retrieved matches exactly what 
was put in. 

140
00:06:26,520 --> 00:06:30,680
So it checks the whole round 
trip, adding, saving, retrieving

141
00:06:30,680 --> 00:06:33,160
and checking the data integrity.
Precisely. 

142
00:06:33,520 --> 00:06:36,960
It demonstrates that complete 
life cycle, adding data, making 

143
00:06:36,960 --> 00:06:39,280
sure it's persisted correctly in
the database and then 

144
00:06:39,280 --> 00:06:41,600
successfully getting it back out
unchanged. 

145
00:06:41,840 --> 00:06:44,600
It really proved the components 
are working together properly. 

146
00:06:44,800 --> 00:06:48,160
Looking at that example then 
what really jumps out at you as 

147
00:06:48,160 --> 00:06:51,000
the most important take away 
about integration tests? 

148
00:06:51,160 --> 00:06:52,720
For me, there are two 
fascinating things here. 

149
00:06:52,760 --> 00:06:58,040
First, the tests themselves are 
written using J unit. 

150
00:06:58,160 --> 00:06:59,960
Which people might know from 
unit testing. 

151
00:06:59,960 --> 00:07:03,000
Exactly, which shows how 
versatile A framework like J 

152
00:07:03,000 --> 00:07:04,800
Unit is. 
It's not just for tiny unit 

153
00:07:04,800 --> 00:07:07,440
tests, it can handle these more 
complex integration scenarios 

154
00:07:07,440 --> 00:07:10,720
too. 2nd, and this is probably 
the most crucial point, it's a 

155
00:07:10,720 --> 00:07:14,120
true integration test because 
it's testing that forum class 

156
00:07:14,400 --> 00:07:17,160
with its actual dependency, the.
Real database. 

157
00:07:17,320 --> 00:07:20,200
The real database, not some 
simulated stand in. 

158
00:07:20,960 --> 00:07:23,560
That's absolutely critical for 
finding those real world 

159
00:07:23,560 --> 00:07:25,080
interaction problems we talked 
about. 

160
00:07:25,680 --> 00:07:28,920
And that process of resetting 
the database before each test, 

161
00:07:29,200 --> 00:07:33,840
that's vital to it ensures every
test starts from the same known 

162
00:07:33,840 --> 00:07:37,640
predictable state. 
It stops tests becoming flaky or

163
00:07:37,640 --> 00:07:39,840
unreliable because of leftover 
data. 

164
00:07:40,520 --> 00:07:44,080
So essentially this test really 
puts the core form functions 

165
00:07:44,080 --> 00:07:46,920
through their paces, checking 
how the different parts work 

166
00:07:46,920 --> 00:07:49,080
together right down to the 
database layer. 

167
00:07:49,440 --> 00:07:52,040
But notice it deliberately 
doesn't worry about the user 

168
00:07:52,040 --> 00:07:53,720
interface, how things look on 
screen. 

169
00:07:54,160 --> 00:07:56,960
The focus is squarely on that 
back end logic and the data 

170
00:07:56,960 --> 00:07:59,000
interaction. 
That's kind of the sweet spot 

171
00:07:59,000 --> 00:08:02,080
for integration tests. 
That sounds really thorough, but

172
00:08:02,080 --> 00:08:04,360
you know, with that kind of real
world interaction, it sounds 

173
00:08:04,360 --> 00:08:07,720
like it could also be tricky. 
What are some common headaches 

174
00:08:07,720 --> 00:08:09,360
developers run into with these 
tests? 

175
00:08:09,360 --> 00:08:10,080
Oh. 
Absolutely. 

176
00:08:10,240 --> 00:08:12,320
They're powerful, but they 
definitely come with challenges.

177
00:08:12,360 --> 00:08:14,240
Test flakiness is probably the 
biggest one. 

178
00:08:14,280 --> 00:08:18,400
Flakiness, meaning they 
sometimes fail for no obvious 

179
00:08:18,400 --> 00:08:20,640
reason. 
Exactly because they're talking 

180
00:08:20,640 --> 00:08:23,840
to real databases, real external
services over real networks. 

181
00:08:24,440 --> 00:08:28,000
They can fail because of 
temporary network glitches, or a

182
00:08:28,040 --> 00:08:32,200
database being a bit slow, or an
external service having a brief 

183
00:08:32,200 --> 00:08:34,919
outage. 
The test fails, but there's 

184
00:08:34,919 --> 00:08:36,840
actually no bug in the code 
being tested. 

185
00:08:37,480 --> 00:08:40,640
And that flakiness can really 
damage developers confidence in 

186
00:08:40,640 --> 00:08:43,240
the tests. 
If they fail randomly, people 

187
00:08:43,240 --> 00:08:45,520
start ignoring them. 
Yeah, that's not good. 

188
00:08:45,920 --> 00:08:48,160
What else? 
Managing the test data can be a 

189
00:08:48,160 --> 00:08:51,160
significant hurdle too. 
We saw the example just wipe the

190
00:08:51,160 --> 00:08:53,480
tables clean, which is great for
simple cases. 

191
00:08:54,080 --> 00:08:56,440
But imagine a really complex 
system with lots of 

192
00:08:56,440 --> 00:08:58,920
interconnected data. 
Resetting everything might be 

193
00:08:58,920 --> 00:09:01,840
too slow, or you might need very
specific data setups for certain

194
00:09:01,840 --> 00:09:04,080
tests. 
So developers often have to 

195
00:09:04,080 --> 00:09:06,920
spend quite a bit of effort 
carefully creating the right 

196
00:09:06,920 --> 00:09:10,360
test data before a test and then
cleaning it up afterwards, 

197
00:09:10,600 --> 00:09:12,400
making sure tests don't 
interfere with each other 

198
00:09:12,400 --> 00:09:13,400
sounds. 
Like a lot of overhead. 

199
00:09:13,640 --> 00:09:16,720
It can be, and there's also the 
operational cost. 

200
00:09:16,720 --> 00:09:19,840
You might need separate test 
databases, maybe special 

201
00:09:19,840 --> 00:09:24,080
accounts for external services 
just for testing, or ways to 

202
00:09:24,080 --> 00:09:26,000
simulate parts you can't easily 
control. 

203
00:09:26,600 --> 00:09:30,280
Cools like test containers have 
become popular to help with 

204
00:09:30,280 --> 00:09:32,080
this. 
They let you spin up things like

205
00:09:32,080 --> 00:09:35,080
a database inside a docker 
container just for the test run,

206
00:09:35,080 --> 00:09:37,320
give you an isolated disposable 
environment. 

207
00:09:37,800 --> 00:09:39,760
That's clever. 
Yeah, it helps manage some of 

208
00:09:39,760 --> 00:09:42,760
that complexity, but ultimately 
it's always a balancing act. 

209
00:09:42,760 --> 00:09:45,920
You want that deep validation 
integration tests give you, but 

210
00:09:45,920 --> 00:09:49,520
you need to keep them reasonably
fast and crucially reliable and 

211
00:09:49,520 --> 00:09:51,560
maintainable. 
They need careful design and 

212
00:09:51,560 --> 00:09:54,160
ongoing attention. 
So it requires a thoughtful. 

213
00:09:54,160 --> 00:09:57,280
Approach, definitely. 
They're a powerful tool, but not

214
00:09:57,280 --> 00:09:59,720
one you just slap together. 
You need to think about what 

215
00:09:59,720 --> 00:10:02,160
you're trying to achieve and how
to do it reliably. 

216
00:10:02,680 --> 00:10:04,680
OK, well, that really clarifies 
their role. 

217
00:10:05,360 --> 00:10:08,360
So that wraps up our deep dive 
into integration tests for 

218
00:10:08,360 --> 00:10:10,560
today. 
We've seen how they act as this 

219
00:10:10,560 --> 00:10:14,120
vital middle layer in testing, 
making sure whole features or 

220
00:10:14,120 --> 00:10:17,320
services work correctly with 
their actual real dependencies 

221
00:10:17,320 --> 00:10:19,080
like databases or other 
services. 

222
00:10:19,880 --> 00:10:21,400
Bridging that gap. 
Exactly. 

223
00:10:21,560 --> 00:10:24,720
They're more complex, they take 
longer to run, so they're used 

224
00:10:24,880 --> 00:10:28,560
less often than unit tests, but 
that deep validation they 

225
00:10:28,560 --> 00:10:31,800
provide gives really valuable 
confidence that the whole system

226
00:10:31,800 --> 00:10:34,800
hangs together properly. 
Confidence is the keyword there 

227
00:10:34,800 --> 00:10:36,800
I think. 
It really is confidence that the

228
00:10:36,800 --> 00:10:39,160
software you rely on everyday 
has had these crucial 

229
00:10:39,160 --> 00:10:42,920
connections rigorously checked. 
Thank you for joining us on this

230
00:10:42,920 --> 00:10:43,600
deep dive.
