forked from mikeckennedy/talk-python-transcripts
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy path045-testing-software-with-python.txt
1710 lines (855 loc) · 63.7 KB
/
045-testing-software-with-python.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
00:00:00 What is the role, the core purpose of writing tests for your application?
00:00:03 Should you write more unit tests and fewer integration tests, or is it actually the other
00:00:07 way around? You may have heard of the test pyramid with unit tests building the foundation.
00:00:11 In this episode, we'll talk about a variation on that theme called the test column. We talk
00:00:16 about this and more with Brian Okken on episode number 45 of Talk Python to Me, recorded January
00:00:22 27th, 2016.
00:00:24 Welcome to Talk Python to Me, a weekly podcast on Python, the language, the libraries, the
00:00:53 ecosystem, and the personalities. This is your host, Michael Kennedy. Follow me on Twitter
00:00:57 where I'm @mkennedy. Keep up with the show and listen to past episodes at talkpython.fm
00:01:02 and follow the show on Twitter via at Talk Python.
00:01:05 This episode is brought to you by Hired and SnapCI. Thank them for supporting the show on
00:01:11 Twitter via at Hired underscore HQ and at Snap underscore CI.
00:01:15 Hey, everyone. I hope you're looking forward to an interesting conversation on testing software
00:01:21 using Python. This week, our guest, Brian Okken, is giving away five copies of his Python testing
00:01:26 frameworks book. If you want to be in the running, be sure to visit talkpython.fm and enter your
00:01:31 email address to become a friend of the show. Now, let's get right to the interview with Brian.
00:01:36 Brian, welcome to the show.
00:01:37 Hey, thanks, Mike.
00:01:39 Yeah, it's really great to have another podcaster and a friend and a fellow Portlander here all
00:01:45 together on Talk Python to talk about testing in Python.
00:01:49 Yeah, I'm excited to be here.
00:01:50 Yeah, yeah. It's really cool. So for the listeners out there who don't know,
00:01:55 Brian is the host of Python Test Podcast, which is a fairly new, but how many episodes have you had?
00:02:03 Are you on the ninth or tenth?
00:02:05 Yeah, I can't remember. I think I did number nine recently.
00:02:08 Yeah, number nine with Harry Percival. Excellent. Listen, that one, that's great. So I'll put a link
00:02:14 to the podcast out there. So you spend a lot of time talking about testing and exploring sort of the
00:02:20 whole spectrum or pyramid of testing in Python on your podcast, on your show.
00:02:25 Yeah, I really want to cover... Actually, the podcast covers everything. I want to cover everything in
00:02:32 software development and software testing.
00:02:34 So we're definitely going to spend a good amount of time talking about that. But let's start at the
00:02:39 beginning. How do you get into programming, Python, that sort of thing?
00:02:42 Well, my first introduction to programming was in high school. I took a basic class.
00:02:48 High school offered basic at Pascal, and I figured basic has to be easier, right? Because it's got basic in
00:02:54 the name. But at the same time, I didn't really get into it too much then. But at the same time,
00:03:00 I had a TRS-80 at home. And I spent a little time like typing in games from game listings from magazines,
00:03:08 like Lunar Lander was one of my favorites. And then, yeah, I didn't do much more until college. I entered
00:03:16 college intending to be an art and math major. And switched about two or three years in, switched to
00:03:24 computer science. And then finished up with a bachelor's and master's at computer science.
00:03:29 That's cool. So where'd Python come into the story?
00:03:35 I learned C++. I learned all sorts of languages, Perl and C++ and others in college. I got a job at Hewlett-Packard doing,
00:03:44 well, at first test systems and then embedded programming of instruments. And that was all C++ and still is.
00:03:54 And then, I don't know, maybe four or five years later, I was in a group that had a Python test framework for testing,
00:04:03 system testing the instrument. And started, that was probably maybe 2000, 2002. And I've been using Python for testing instruments ever since then.
00:04:14 One thing that I think is interesting about that, a lot of times people feel like the programming language that the thing you're testing,
00:04:23 the application or whatever is built in, that's the language in which you have to write the test, right?
00:04:29 So if you're writing a C++ app, you have to fire up CPP unit and do C++ unit testing.
00:04:36 That's not really what you're doing, right? Like you're actually testing code that maybe isn't Python, right?
00:04:42 Yeah, it's all C++ and other languages inside. And we've got, but it's got a, the interface is available.
00:04:50 Anything with an interface that's available from Python, you can use Python test frameworks to test them.
00:04:56 And, you know, right off the bat, I had frameworks that the company gave me and didn't even think about it.
00:05:04 But, yeah, it was probably 2010 when I started looking into other frameworks like unit test and pi test.
00:05:11 Yeah, okay. So let's dig into a little bit of the type of stuff that you test at work, and then we'll come back and talk about your podcast a little more.
00:05:19 So what exactly are you talking about instruments and physical things that you're testing?
00:05:25 And these are written in what, C++ or like embedded systems with C++ or C?
00:05:31 Yeah, it's C++. But these are, you know, there's lots of levels of embedded programming.
00:05:37 There's, you know, embedded programming in like, you know, your car or your phone or your watch or whatever.
00:05:45 But these are big instruments. These are, I don't know, they look like stereo components, but they're, they've got many processors inside.
00:05:54 The box I work on right now runs Windows.
00:05:56 So I'm really writing a Windows application, but I don't really do any Windows stuff myself.
00:06:03 But it's all written in C++, all of my code.
00:06:06 Yeah, the user interface, a lot of people use these for the boxes I work on are mainly used in production lines.
00:06:14 And the production line control uses a, I guess, a string based, it's called Skippy, but it's a, it's a special language to control instruments with.
00:06:26 Yeah, we, so that's, that's how our users control the box. So that's how we test them.
00:06:30 Is that like for like managing factories? So if you're like building cars, like the machines, like put the door on or whatever, like those types of devices?
00:06:39 Or what do you, what exactly are you thinking?
00:06:41 Well, okay, so the box I work on right now is, is called the communications test box, one box tester, but it, so it tests all the RF, the transmit and receive abilities of a mobile phone.
00:06:54 So pretty much, yeah, every, every phone that sells in the world has to go through testing to make sure it, you know, it does it, it, since it's a transmitter, it has to follow FCC rules.
00:07:07 I see. So if I like lived down in San Diego and worked at Qualcomm, maybe I would buy your company's product to test the phone internals that we're building, something like that?
00:07:18 Yeah. And anybody that's got, and any, we do not just cellular, but also like Wi-Fi broadcasting.
00:07:28 So we do Wi-Fi testing and Bluetooth and anything that transmits and receives this box will test pretty much.
00:07:35 Okay, cool. And so to test this embedded C++ app, basically, do you do some sort of C level interop with Python?
00:07:46 And do you expose some kind of API that Python can understand? Or do you do this Skippy API against it? Or what's the story there?
00:07:53 Well, so the magic that glues it all together is a library that's available on PiPi called PiVisa.
00:08:03 So, yeah, there's a, Roden Schwartz and National Instruments and others have these Visa DLLs that you can use to interact, to send Skippy over LAN.
00:08:17 And I use PiVisa to get at that. So it's really easy. You connect those up and you got to, you just have an object that you can send write and read commands to.
00:08:29 Works great.
00:08:30 Would you say that that kind of testing is sort of more holistic or is that more like unit testing?
00:08:36 It sounds to me like my first guess is like you're kind of hitting the outside, like so maybe an integration test type story, yeah?
00:08:43 Yeah, it's definitely like an end-to-end test.
00:08:45 We test, I'm testing our entire system.
00:08:50 But the kind of the, there is, so, you know, in looking at test frameworks, I'm way more interested in how the fixture model is because I use, we use setup and teardown to actually do things like, you know, move signals around and hit switch boxes.
00:09:08 Definitely more of an end-to-end.
00:09:10 But we do use ideas like mock, like if I'm testing the measurement capabilities, for instance, it's difficult to test that against a, like a moving target, like an actual mobile.
00:09:23 So we'll have an arbitrary waveform generator generate a known signal and we test the receive side against the known signal.
00:09:32 And then we can do the other end also, we send our transmission to like a different instrument to test it against something else.
00:09:40 When you think of software architectures, you often hear people talk about things like dependency injection and basically managing and decoupling the dependencies of your software so that you can test the individual pieces, right?
00:09:55 Yeah.
00:09:56 Yeah, definitely.
00:09:57 Yeah, but you, it sounds like your dependencies are more solid than, than maybe others, right?
00:10:04 Like you've got physical devices and like scientific information coming in and, you know, like waveforms.
00:10:11 And so you've, what kind of stuff do you do?
00:10:14 That part actually isn't that different, really.
00:10:16 I mean, because like on a, if you had like a big user database or something on a web application, the real, the real database on in, in the world is going to be a lot different than your like test database.
00:10:28 So that's similar to how our real signals are different from our test signals.
00:10:32 The diff, the difficulty is, is the fuzziness.
00:10:35 So, we often don't really get, because even with a, a, a pure signal from a generator, we've got, you've got noise in the system.
00:10:45 So you can't, you can't just get a, get a number out of a, out of a, a measurement and say, if it's 3.2, then it's correct.
00:10:53 Otherwise it's wrong.
00:10:55 And almost all of our measurements are, are, we've got tolerances around them.
00:10:59 That's really interesting.
00:11:00 a lot of people write software that is basically deterministic in, in ways that are easy to assess.
00:11:09 So I get a Boolean back or I query for a user and the user is either there or they're not, or they're an, they're an admin or they're a regular user, right?
00:11:19 These super clear distinctions.
00:11:21 But when you get into sort of sciencey spaces, it gets really hard to actually just know, know that you're right.
00:11:31 Yeah.
00:11:31 I mean, if you get back a number and it's off by a thousandth, is that still the same?
00:11:37 Does that count as okay or not?
00:11:39 Right.
00:11:39 That, that can be really challenging.
00:11:41 Yeah.
00:11:41 But there's, I mean, there's, there's ways to do it.
00:11:43 We've got, we, we can, there's, we can split the, we, when we're testing the entire system, it's difficult to tell because it, you know,
00:11:51 if it's off by 10%, it's hard to, you know, visually know, but, but we can, the, the actual numbers that go through the system go through, you know, there's, there's the different pieces are, are tested with different rigor.
00:12:08 So it all works out.
00:12:09 Yeah.
00:12:09 That's an interesting point.
00:12:11 And I'm, I'm actually not, I'm not the guy that, that tests the, the box to make sure that the, that it like actually, like if we say we're putting out like minus 10 dB, that it's actually really 10 dB, minus 10 dB.
00:12:25 That's like some other guy in, in like a manufacturing facility.
00:12:28 I'm, I'm mostly concerned with that, making sure all the heart, all the software didn't muck things up.
00:12:35 So, in, in the end, I trust that the hardware is working correctly and I just want to make sure that the software hasn't mucked up the, the pristine hardware.
00:12:45 Right, right, right.
00:12:46 So you assume that the hardware you've got is actually processing everything.
00:12:50 Okay.
00:12:51 But you've got to gather it, save it, interpret it, all that kind of stuff.
00:12:55 And so you kind of start at that level, right?
00:12:57 Yeah.
00:12:58 And then the, the measurement data that we're turning back, I mean, we're, we're sending back, we've got like thousands of different like measurement points that we're sending back and making sure that we don't muck one of those up.
00:13:10 And then we don't put some, some array in the wrong place.
00:13:14 that's, that's the sort of stuff that I'm really concerned with.
00:13:17 Yeah, that's interesting.
00:13:19 One of my first jobs was working at a place called eye tracking, Inc.
00:13:23 eye tracking.com.
00:13:25 And we would build these scientific visualization tools and sort of data analysis on top of eye tracking data, right?
00:13:33 Pupil dilation over time, where you're looking, that, that kind of stuff.
00:13:36 And we would end up doing really complicated math sort of pipelines on it, you know, Fourier analysis,
00:13:43 wavelet decomposition, those kinds of things.
00:13:45 And you try to, you know, test the results of one of those things, you know, it's super hard.
00:13:51 So we basically would come up with a reference input and a reference output and go, if the deviation from, from this graph to that graph is, it's not too large, we'll call it, we'll call it the same, right?
00:14:03 Because the, maybe they use something like MATLAB to generate the reference results.
00:14:08 And, you know, the way it deals with floating point numbers might be slightly different than the language we were using or something like that.
00:14:13 Yeah.
00:14:14 It's an interesting challenge that I think a lot of people building, I don't know, more standard business apps.
00:14:20 It doesn't really get on your radar, right?
00:14:22 Because the user is either an admin or not.
00:14:24 You know, assert true, done.
00:14:26 Yeah.
00:14:27 I mean, actually, people that have that sort of a test job, I'm like, what's so hard about this?
00:14:33 Just, you know, write the test and get on with life.
00:14:36 Yeah.
00:14:36 So, okay.
00:14:37 So let's, let's look at some of the frameworks and get some of your thoughts on that.
00:14:42 So let's say the majority of people listening know what unit testing is, what the goals are.
00:14:48 But I know a lot of my listeners are sort of scientists getting into programming or new programmers.
00:14:54 So maybe give us just the elevator pitch.
00:14:57 What is unit testing?
00:14:58 Why do we care?
00:14:59 I'm not sure why we care about unit testing, actually.
00:15:02 Or software testing, rather.
00:15:05 No, so that, that's a, the, the, the phrase unit test is a, is one that's kind of a, a sticky point for me because the, in extreme programming, the, they use the term unit test.
00:15:18 And that just meant any developer test, anything written by developers, not written by the QA team.
00:15:23 And, and in a lot of communities, it's stuck with that.
00:15:27 It is, that's the, the, the use model.
00:15:31 That's what a lot of people commonly term, term a unit test is something written by a developer.
00:15:35 And then in the TDD community, that often isn't the, the definition.
00:15:41 The unit test is often the, the smallest possible, like one function.
00:15:45 You're testing one function at a time.
00:15:48 And I look at, so there's the, the, the most importantly is that the entire, the entire thing is tested.
00:15:56 Your entire software is tested.
00:15:57 And unit testing is, I think there's certain places where you want to go in and test.
00:16:04 I like to put tests anywhere where I have a promise.
00:16:07 If I'm promising anybody other than myself that things are going to work right, we need tests there.
00:16:12 So if I've got a, a library that other team, other team members use or other, other groups use, that needs tests around it.
00:16:19 But the, and in your, anywhere there's interfaces, interfaces between groups or between components.
00:16:26 Those are great places to put tests.
00:16:28 And then of course the entire system function tests.
00:16:31 I think the, the focus on unit testing, unfortunately takes some of the responsibility out of system level testing where I think it's unfortunate.
00:16:43 I think there's different scenarios where things like unit tests matter more and other times they matter less.
00:16:49 So times I think they matter a lot are when you have a lot of people all in the same general code base making changes.
00:16:58 And you don't necessarily know everything that's changing.
00:17:00 Right.
00:17:01 So, so people are checking in changes and you're not necessarily, I mean, you're doing code reviews and stuff, but you're not necessarily like always aware like, oh, they actually changed this method that I was depending on.
00:17:12 And they didn't understand this like implicit contract I built around the return value here or something like that.
00:17:19 Right.
00:17:19 Yeah.
00:17:19 So I think it's really valuable there.
00:17:22 And I think it's valuable for helping, helping build apps where fewer people are working on it.
00:17:28 There there's less churn.
00:17:29 But one of the things that I saw, you know, early two thousands and in response to the extreme programming was people saw that they, they thought they had to do, you know, 95% code coverage.
00:17:44 Everything is TDD.
00:17:45 If you don't start that way, it's bad software.
00:17:49 You just can't write it.
00:17:50 How can you possibly stand up for it?
00:17:52 And, you know, over time I saw a lot of people saying, well, we can't do that.
00:17:57 Right.
00:17:58 We are in too much of a hurry or whatever.
00:18:00 You know, they have whatever excuse.
00:18:02 A lot of times it wasn't totally unreasonable.
00:18:04 We basically say we can't match that level of commitment to testing.
00:18:10 So we're not going to do any.
00:18:11 And I think that that's one of the places where it can actually, that message of like test everything can become negative.
00:18:19 Because, you know, if they had written, like you had said, the thing you're making a promise about, right?
00:18:23 Like if, if you're writing like stock trading software, the part that actually says buy or sell, there should probably be tests on that.
00:18:29 The, the part that logs that the app started probably doesn't need you in a test, right?
00:18:35 There's lots of parts of apps that are just there to support some sort of core.
00:18:39 And that core is much more important that it's tested, I think.
00:18:42 And what do you, what do you think?
00:18:44 Yeah, totally.
00:18:45 It's like, I think, actually, I think you brought it up in one of your podcasts recently that, that it's the thing that, the thing that's making you money.
00:18:53 The reason why somebody is buying your thing.
00:18:55 That's what you should test the heck out of.
00:18:57 Yes, absolutely.
00:18:58 Like if, if, if that is your thing that you build for the world, that little essence of it, you had better test that, right?
00:19:05 Yeah.
00:19:06 But there's, as you know, you ship real software.
00:19:09 It's like, that's like 20% of the code you write.
00:19:12 There's 80% that isn't that.
00:19:14 Well, and then I like, I like code coverage tools.
00:19:18 But my, a lot of times I think that they're, instead of looking at the, there's two ways to get to 100%, right?
00:19:26 There's a, you can either write more tests or you can delete code.
00:19:31 I think you should delete more code.
00:19:33 If you've got, if you've got a, a bunch of software that is not reachable from the, the user interface.
00:19:40 If, if I can't make some section of the code hit that piece of code with, with normal user input, maybe it doesn't need to be there.
00:19:49 That's a really interesting point.
00:19:50 Yeah.
00:19:50 Yeah.
00:19:51 Yeah.
00:19:51 This episode is brought to you by Hired.
00:20:04 Hired is a two-sided curated marketplace that connects the world's knowledge workers to the best opportunities.
00:20:10 Each offer you receive has salary and equity presented right up front, and you can view the offers to accept or reject them before you even talk to the company.
00:20:17 Typically, candidates receive five or more offers within the first week, and there are no obligations, ever.
00:20:23 Sounds awesome, doesn't it?
00:20:25 Well, did I mention the signing bonus?
00:20:26 Everyone who accepts a job from Hired gets a $1,000 signing bonus.
00:20:30 And as Talk Python listeners, it gets way sweeter.
00:20:32 Use the link Hired.com slash Talk Python To Me, and Hired will double the signing bonus to $2,000.
00:20:38 Opportunity's knocking.
00:20:40 Visit Hired.com slash Talk Python To Me and answer the call.
00:20:49 I've spent more than once, I've been giving some big software projects and said, you know, have a look at this, and then we're going to need to have you help us add a feature or recommend some change.
00:21:01 And there'll be like some method.
00:21:02 I'm like, what does this do?
00:21:04 What does this have anything to do with this code?
00:21:07 It doesn't seem to do anything.
00:21:08 And I'll like study the code and then, you know, two hours later, I'm like, oh, it's never called at all.
00:21:15 Yeah.
00:21:15 Somebody should have just deleted it.
00:21:17 They should have just deleted it and the world would have been a better place.
00:21:20 But instead, you know, I wasted two hours.
00:21:23 Somebody else probably wasted two hours.
00:21:24 And it just gets kicked down the road.
00:21:26 The other thing, one of the things that I actually like, I'm writing more lower level tests than I used to.
00:21:33 I used to mostly focus on high level tests.
00:21:37 But the, and I still do, but lower level tests do have their place.
00:21:43 But the, I like the model of, in test-driven development of the red-green refactor.
00:21:48 But just don't forget the refactor part.
00:21:51 So if a test, putting a test in place makes it so that you cannot refactor something, then maybe that test isn't quite right.
00:22:00 I don't want to, I don't want to restrict my ability to change my mind and redesign something.
00:22:05 So.
00:22:05 I had brought up the, you know, the perfect being the enemy of the good sort of thing where people say, if I can't have really good test coverage, like what, what is it?
00:22:13 Well, I'm not even going to start.
00:22:14 Forget this.
00:22:15 It's too much work to do testing, right?
00:22:17 Yeah.
00:22:17 Well, and that's, you see that a lot when, when a team like looks at, looks at their code and they go, they get a new manager in or a new, somebody comes in and says, hey, we need to add a bunch of tests to this.
00:22:28 But where do you start when you have like a 10 years of legacy code?
00:22:32 You can't just cover everything.
00:22:34 So yeah, there's a, you got to just start somewhere.
00:22:38 You know, I have a book recommendation actually, now that you bring that up.
00:22:42 So there, you know, Michael Feathers is a guy that in the early days of test driven development and extreme programming and all that sort of stuff, he was really active.
00:22:52 And he wrote a book called Working Effectively with Legacy Code.
00:22:58 And it's, you know, given the time, it was a little more C++ focused, but it has some really amazing ideas of like, how do I take this app, which has a million lines of code and zero tests, and start carving out little epochs of code functionality that are supported by tests and ways you can do that that are safe.
00:23:20 And definitely recommend it.
00:23:22 If people are dealing with like huge apps that are not yet tested and put together in a way that makes them basically untestable, check out Michael Feathers' book.
00:23:31 Okay.
00:23:32 Yeah.
00:23:32 Have you seen that one?
00:23:33 Definitely.
00:23:34 I've got a difference of opinion on that one, but I'll just let that go.
00:23:38 No, no, no, no, no.
00:23:39 I wouldn't hear it.
00:23:40 Tell me.
00:23:40 I think it just seems silly to try to add a bunch of unit tests to a bunch of existing code.
00:23:46 I think it's way more profitable for your company to put functionality testing around it.
00:23:52 And because they like the end to end functionality testing of your system.
00:23:57 If, if you know, like you, you need to know if you're going to refactor something, you need to know that the end functionality is still working solid.
00:24:06 And if you have tests in place to guarantee that, then what value is it to, to go in and add like thousands of unit tests?
00:24:16 Sure.
00:24:17 So I think that's a totally, totally valid point.
00:24:20 And I think, you know, it's been like, gosh, it's probably been 12, 13 years since I read that book.
00:24:25 So, you know, I'm, I'm going to only get it like a little bit, right.
00:24:28 But I think the idea was like, suppose you've got some huge, you've got a library you're calling and like you hit the outside method, like some, you know, do your thing library.
00:24:37 And it gives you an answer back rather than trying to set up a whole bunch of tests inside there.
00:24:42 The question was like, well, how could I refactor some dependency or some bits?
00:24:48 Right.
00:24:48 So maybe what you do is you just come up with a bunch of inputs, save the outputs and go long as those don't change.
00:24:53 We're going to call it good.
00:24:55 It was some, some like really basic scaffolding to say the thing kind of looks still okay.
00:25:01 Yeah.
00:25:02 I mean, I, I think looking at, putting tests around the outside and then also looking at the different interfaces in the side of the system and, and maybe sure, maybe adding some different interfaces that weren't there before to try to separate the design.
00:25:14 But all of that involves like a redesign and you're not going to, you're not going to guarantee that you're not breaking external functionality.
00:25:22 It's just, it's just, they don't, they don't test for that.
00:25:27 Yeah, that's right.
00:25:29 So I think that's, that's probably an interesting thing to explore a bit is, can we be talking about unit tests and the whole extreme programming origins of it and all that, but there's kind of what you refer to on your show as like a pyramid of testing capabilities or functionality.
00:25:46 Can you go into that a bit?
00:25:47 Yeah, sure.
00:25:48 Well, I don't really like the test pyramid, but if you, if you do much reading about software testing, you'll run into a test pyramid.
00:25:55 All right.
00:25:56 So the test pyramid, the, the notion, if you read in, do any reading on test software testing, you'll run across references to a test pyramid.
00:26:05 So the idea is, a foundation of unit tests and some integration tests and very little functional tests, just end to end tests.
00:26:16 And, um.
00:26:17 Right.
00:26:17 Kind of like a food pyramid where like the dessert is at the top.
00:26:20 You should have just a little tiny bit and that's the functional bit at the top.
00:26:23 Yeah.
00:26:24 And, what, what, and the, there's the reason is because supposedly functional system testing is, doesn't give you much benefit and it, they break and they're brittle and they're fragile.
00:26:37 I just don't buy it.
00:26:39 and what, what happens I think is developers see that and they go, Oh, okay.
00:26:44 Focus on unit tests and leave, leave the end to end test to QA.
00:26:48 The problem with that big problem with that is a lot of teams don't have a QA anymore.
00:26:53 So there's nobody doing end to end tests.
00:26:56 Somebody's got to.
00:26:58 so it's, if there's no QA, then it's your customers.
00:27:01 And, I don't think that's the right person to do quality assurance.
00:27:05 So I, I, I think that focusing on, maybe a column of tests, it should be a column, not a pyramid.
00:27:16 Do, do the tests where they make sense.
00:27:18 You've got to have full behavior coverage, end to end wise to make sure that your system works the way you promised it's going to work.
00:27:28 And, and also like with, especially with, continuous integration, if you're relying solely on automated tests, those have to be promises that you're trying to keep to the customer.
00:27:40 And then, I don't really know what integration tests are.
00:27:44 There's a lot of definitions for it, but it's the middle part.
00:27:47 And sometimes it's integration test means integrating with the outside world.
00:27:52 So if you're integrating with a database library, it's tests against that.
00:27:56 But then also some people think of, integration tests as between two components or between two functions.
00:28:02 And then unit tests are the, the low level while you're designing your code.
00:28:06 I don't know.
00:28:07 I think that you just need to use your own.
00:28:10 I don't think there's a rule of thumb.
00:28:11 I think you got to use your judgment and put tests where it makes sense.
00:28:14 I think that, yeah, I really feel that that's, that that's good advice, right?
00:28:19 The whole, let's make, make the top part of the pyramid a little fatter and make it more like a column.
00:28:24 Yeah.
00:28:24 So I think that makes a lot of sense because let's say you have a thousand unit tests.
00:28:29 I actually, I'm with you.
00:28:31 I don't really know what an integration test is, but say you have a hundred of those and you're at 10 functional tests, right?
00:28:35 Do you really need the thousand unit tests or are those 10 functional tests enough?
00:28:42 Maybe.
00:28:42 Well, a lot of the arguments for the, a lot of the unit tests are to make sure that, you know, somebody else doesn't break your units or something.
00:28:52 But I don't know if you, I, I just think functional testing needs to be done more.
00:28:57 So, well, you know what I think the origins of it are.
00:29:00 I think it has to do with the TDD side of things like you, it's very difficult to functional TDD.
00:29:08 I think it's, I think it works great.
00:29:12 well, like, Harry brings it up and it's been brought up by others as kind of a double loop TDD where you, you start, start with the functional test.
00:29:21 And then, and then, while you're trying to fix that functional test, that's failing, you write a bunch of unit tests.
00:29:29 I think that works, works good.
00:29:31 I just, you know, once you have the functional test working, do you need to keep the unit tests?
00:29:38 I don't know.
00:29:38 It's kind of up to you.
00:29:39 I think keep them if, if they're not, I think of a unit test is like scaffolding, right?
00:29:46 So if you're, well, you're, if it helps you to build your software to put a bunch of scaffolding around it.
00:29:50 Great.
00:29:51 But, once it's built, I don't know, some of the scaffolding can come down maybe.
00:29:56 Yeah.
00:29:57 You're left with columns or something, right?
00:29:59 Interesting.
00:30:01 Yeah.
00:30:01 I think that's a good way to look at it.
00:30:03 I think one of the really big values that unit tests provide in to some degree, the functional
00:30:10 tests and integration tests is they get you to think about how your function or object or
00:30:17 API is used from the outside sooner.
00:30:20 Yeah, definitely.
00:30:21 And that, that's why I think focusing on interfaces, if you, if you're really building an interface
00:30:25 that you need to have clean, then it needs to be, it needs to be changeable.
00:30:31 But, and tested, but like if, if, like, so let's say I'm writing a handful of classes that
00:30:36 all work together and I'm, I'm the main developer in this section of code, it's just going to
00:30:42 be me, right?
00:30:42 so if it, I don't think I'm going to put a unit test around every function because that
00:30:49 means every time I want to refactor this system, I've got to change all the unit tests.
00:30:55 As long as this, this subsystem works from the outside world.
00:31:00 I think that's enough.
00:31:01 I think one of the big mistakes that people also make, you know, in addition to being,
00:31:06 letting like the perfect be the enemy of the good and just saying, well, we can't do perfect.
00:31:10 So we're not starting.
00:31:10 I think the other problem is that people write unit test code in a different mental state.
00:31:17 Let's just say test code, right?
00:31:19 Cause you know, it's, it's up and down the, the, the column that you're defining here.
00:31:24 Yeah.
00:31:25 So I think they write those in a different mental state than the core of their application.
00:31:31 Like I've seen plenty of people just go to unit tests and just copy, paste, copy, paste,
00:31:35 like 10 lines of code.
00:31:37 And like, what are you doing?
00:31:39 Like, would you do that in normal code?
00:31:41 Of course you wouldn't, right?
00:31:42 You'd make that a function or some sort of object or something.
00:31:46 Right.
00:31:47 But that makes it way more painful to refactor or evolve your code when you've got 20 copies
00:31:55 of the thing that you have to maintain.
00:31:56 Well, yeah, that's another reason why I think you had to be careful with the whole, like,
00:32:00 have a, have as many unit tests as you can write in a day because it's, it's an, it's
00:32:06 a code asset, but it's also, it's also a, it's a weight around you.
00:32:10 You've got to, you've got to keep it all the time and you've got to change it.
00:32:13 It's, it's code maintenance.
00:32:14 There's test code maintenance just as there is normal code maintenance.
00:32:17 Yeah.
00:32:18 So I think you can structure your test code.
00:32:20 Most people's test code could probably be refactored to be way more maintainable.
00:32:25 And so that's good, but, and people should do that.
00:32:28 But like you say, like more is not always better.
00:32:31 I think if you think of what are the main use cases that a user is going to do with your application,
00:32:36 if you can test those, chances are all those little edge cases that you're testing, if they
00:32:42 were to go wrong, your main user stories or whatever don't really work anymore.
00:32:48 Right.
00:32:48 So do you have to write those little tests?
00:32:50 That's, that's an interesting question.
00:32:51 Well, I think that if, if a user, I, all the edge cases from a user's perspective, from
00:32:57 like an end user, those should be tested.
00:32:59 I definitely think you ought to test the edge cases, but the, the, the edge cases of
00:33:05 every function.
00:33:06 I don't, I don't think so.
00:33:08 If you've got like, like a, one of the examples I've given before is if I've got a, a username
00:33:14 that goes through the system and in some, some function that has to intercept that takes a
00:33:20 string then.
00:33:20 Right.
00:33:21 So do I need to test to make sure that string can handle a thousand characters?
00:33:25 maybe not.
00:33:27 It's interesting to question these assumptions about, you know, how many tests should you have?
00:33:33 How, how should they, should they be in a pyramid where it's, you know, decreasing as you go up
00:33:38 or should they be kind of more flat and so on?
00:33:42 Well, the, it's, it, and it's, it's sort of theoretical, right?
00:33:46 Because it just, it changes with every situation and the tests need to be an asset so that you
00:33:50 can, if they need to be such that you can trust that if the tests pass, your code is good and
00:33:57 whatever the tests have to be so that you can trust that you can check something in and it's
00:34:02 good because the tests pass, that's where you need to be, whatever it takes to get to
00:34:07 there.
00:34:08 Yeah.
00:34:08 And related to that is if you have tests such that it takes 15 minutes to ask the question,
00:34:14 do my test pass, people are going to stop running them and they just become stale.
00:34:19 All right.
00:34:34 This episode is brought to you by SnapCI, the only hosted cloud-based continuous integration
00:34:40 and delivery solution that offers multi-stage pipelines as a built-in feature.
00:34:45 SnapCI is built to follow best practices like automated builds, testing before integration,
00:34:50 and provides high visibility into who's doing what.
00:34:53 Just connect Snap to your GitHub repo and it automatically builds the first pipeline for you.
00:34:59 It's simple enough for those who are new to continuous integration, yet powerful enough to run
00:35:03 dozens of parallel pipelines.
00:35:05 More reliable and frequent releases.
00:35:07 That's Snap.
00:35:08 For a free, no obligation, 30-day trial, just go to snap.ci slash talkpython.
00:35:14 Well, that's the other beef I've got with, with the, the, a lot of the unit test stuff
00:35:27 with the testing and isolation.
00:35:29 So I don't even get that.
00:35:30 So if, if I want to, so one of the things is if test, the test suite is slow, you're not
00:35:35 going to run it.
00:35:36 So we've got it.
00:35:36 We want to try to speed up test suites.
00:35:38 But one of the ways to do that is to isolate every single function and every single test so
00:35:44 that the test doesn't rely on it.
00:35:46 This function doesn't rely on anything else.
00:35:49 But then if I've got such isolated tests, why am I running the whole suite?
00:35:54 Just run the thing, run the tests over the thing that I'm testing.
00:35:58 Right.
00:35:58 Because if you're not testing the integration, then you're doing like 95% rework that theoretically
00:36:05 doesn't affect you, right?
00:36:05 Right.
00:36:06 If I'm writing code that, is modular and everything, if, like the stock example,
00:36:12 if I want to check to see if the buy button works, I don't need to test to make sure that
00:36:18 that functionality that I changed didn't break the printing function.
00:36:22 Yeah.
00:36:23 Yeah.
00:36:23 The about page shouldn't fail when I change the trading engine, right?
00:36:26 Yeah, exactly.
00:36:29 So one thing that you talked about on, I think it was show eight, if I recall my,
00:36:34 my ordering correctly, of your podcast was the theme was like writing software is like
00:36:42 nothing else.
00:36:42 And I found that really interesting and it really resonated with me, not necessarily on a testing
00:36:49 level, but on a software engineering level, right?
00:36:53 Like people say people typically who are not skilled in the art of writing software will
00:36:59 come and say, Hey, look, your title is software engineer.
00:37:04 We have other types of engineers.
00:37:06 They build like bridges.
00:37:07 They can tell us within 10% accuracy of not just the cost of the project, but the duration
00:37:17 of the project and how many people need to be on it.
00:37:19 Why can't you do that with software?
00:37:21 And I think your, your sort of a riff on software is like nothing else.
00:37:24 It was really, I think it was neat.
00:37:26 Well, I, I, I appreciate that.
00:37:29 I like that as well.
00:37:30 The, that notion that it's like engineering or it's like architecture or it's like,
00:37:36 you know, whatever it isn't, it's, it's, it's its own thing.
00:37:40 It's hard to define what, what it's like.
00:37:43 And now as I'm in a management role, I've got to do some of those things.
00:37:46 I've got to come up with estimates and I'm, I'm often the evil guy that says, well, how long
00:37:51 is this going to take?
00:37:52 Are you going to be done next week?
00:37:53 and, and I know the answer is nobody knows, but, but you know, you've got to ask
00:37:59 those questions anyway.
00:38:00 So.
00:38:01 Yeah.
00:38:01 I read a book by somebody and I totally forgot all the details.
00:38:04 So I think it's lost.
00:38:06 It was talking about this and it said, you know, people often refer to software engineering
00:38:14 and I'd actually personally don't really like the term software engineer much.