forked from mikeckennedy/talk-python-transcripts
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy path045-testing-software-with-python.vtt
2567 lines (1711 loc) · 81.3 KB
/
045-testing-software-with-python.vtt
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
WEBVTT
00:00:00.001 --> 00:00:03.240
What is the role, the core purpose of writing tests for your application?
00:00:03.240 --> 00:00:07.180
Should you write more unit tests and fewer integration tests, or is it actually the other
00:00:07.180 --> 00:00:11.260
way around? You may have heard of the test pyramid with unit tests building the foundation.
00:00:11.260 --> 00:00:16.840
In this episode, we'll talk about a variation on that theme called the test column. We talk
00:00:16.840 --> 00:00:22.340
about this and more with Brian Okken on episode number 45 of Talk Python to Me, recorded January
00:00:22.340 --> 00:00:24.060
27th, 2016.
00:00:24.060 --> 00:00:53.280
Welcome to Talk Python to Me, a weekly podcast on Python, the language, the libraries, the
00:00:53.280 --> 00:00:57.900
ecosystem, and the personalities. This is your host, Michael Kennedy. Follow me on Twitter
00:00:57.900 --> 00:01:02.820
where I'm @mkennedy. Keep up with the show and listen to past episodes at talkpython.fm
00:01:02.820 --> 00:01:05.360
and follow the show on Twitter via at Talk Python.
00:01:05.360 --> 00:01:11.320
This episode is brought to you by Hired and SnapCI. Thank them for supporting the show on
00:01:11.320 --> 00:01:15.880
Twitter via at Hired underscore HQ and at Snap underscore CI.
00:01:15.880 --> 00:01:21.320
Hey, everyone. I hope you're looking forward to an interesting conversation on testing software
00:01:21.320 --> 00:01:26.780
using Python. This week, our guest, Brian Okken, is giving away five copies of his Python testing
00:01:26.780 --> 00:01:31.520
frameworks book. If you want to be in the running, be sure to visit talkpython.fm and enter your
00:01:31.520 --> 00:01:36.080
email address to become a friend of the show. Now, let's get right to the interview with Brian.
00:01:36.080 --> 00:01:37.900
Brian, welcome to the show.
00:01:37.900 --> 00:01:38.960
Hey, thanks, Mike.
00:01:39.200 --> 00:01:45.760
Yeah, it's really great to have another podcaster and a friend and a fellow Portlander here all
00:01:45.760 --> 00:01:49.220
together on Talk Python to talk about testing in Python.
00:01:49.220 --> 00:01:50.700
Yeah, I'm excited to be here.
00:01:50.700 --> 00:01:55.320
Yeah, yeah. It's really cool. So for the listeners out there who don't know,
00:01:55.320 --> 00:02:03.860
Brian is the host of Python Test Podcast, which is a fairly new, but how many episodes have you had?
00:02:03.920 --> 00:02:05.040
Are you on the ninth or tenth?
00:02:05.040 --> 00:02:08.300
Yeah, I can't remember. I think I did number nine recently.
00:02:08.300 --> 00:02:14.180
Yeah, number nine with Harry Percival. Excellent. Listen, that one, that's great. So I'll put a link
00:02:14.180 --> 00:02:20.860
to the podcast out there. So you spend a lot of time talking about testing and exploring sort of the
00:02:20.860 --> 00:02:24.900
whole spectrum or pyramid of testing in Python on your podcast, on your show.
00:02:25.380 --> 00:02:32.520
Yeah, I really want to cover... Actually, the podcast covers everything. I want to cover everything in
00:02:32.520 --> 00:02:34.260
software development and software testing.
00:02:34.260 --> 00:02:39.020
So we're definitely going to spend a good amount of time talking about that. But let's start at the
00:02:39.020 --> 00:02:42.060
beginning. How do you get into programming, Python, that sort of thing?
00:02:42.060 --> 00:02:48.460
Well, my first introduction to programming was in high school. I took a basic class.
00:02:48.460 --> 00:02:54.880
High school offered basic at Pascal, and I figured basic has to be easier, right? Because it's got basic in
00:02:54.880 --> 00:03:00.840
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.840 --> 00:03:08.440
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.440 --> 00:03:16.880
like Lunar Lander was one of my favorites. And then, yeah, I didn't do much more until college. I entered
00:03:16.880 --> 00:03:24.000
college intending to be an art and math major. And switched about two or three years in, switched to
00:03:24.000 --> 00:03:29.200
computer science. And then finished up with a bachelor's and master's at computer science.
00:03:29.960 --> 00:03:35.880
That's cool. So where'd Python come into the story?
00:03:35.920 --> 00:03:44.760
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.760 --> 00:03:53.960
well, at first test systems and then embedded programming of instruments. And that was all C++ and still is.
00:03:54.720 --> 00:04:03.520
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.520 --> 00:04:14.760
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.760 --> 00:04:23.980
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.980 --> 00:04:29.200
the application or whatever is built in, that's the language in which you have to write the test, right?
00:04:29.200 --> 00:04:36.140
So if you're writing a C++ app, you have to fire up CPP unit and do C++ unit testing.
00:04:36.640 --> 00:04:42.520
That's not really what you're doing, right? Like you're actually testing code that maybe isn't Python, right?
00:04:42.520 --> 00:04:50.440
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.440 --> 00:04:56.460
Anything with an interface that's available from Python, you can use Python test frameworks to test them.
00:04:56.460 --> 00:05:04.120
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.240 --> 00:05:11.780
But, yeah, it was probably 2010 when I started looking into other frameworks like unit test and pi test.
00:05:11.780 --> 00:05:19.220
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.220 --> 00:05:25.900
So what exactly are you talking about instruments and physical things that you're testing?
00:05:25.900 --> 00:05:30.620
And these are written in what, C++ or like embedded systems with C++ or C?
00:05:31.120 --> 00:05:37.440
Yeah, it's C++. But these are, you know, there's lots of levels of embedded programming.
00:05:37.440 --> 00:05:45.260
There's, you know, embedded programming in like, you know, your car or your phone or your watch or whatever.
00:05:45.440 --> 00:05:53.700
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.200 --> 00:05:56.580
The box I work on right now runs Windows.
00:05:56.580 --> 00:06:03.460
So I'm really writing a Windows application, but I don't really do any Windows stuff myself.
00:06:03.460 --> 00:06:06.180
But it's all written in C++, all of my code.
00:06:06.900 --> 00:06:14.040
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.040 --> 00:06:25.840
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.220 --> 00:06:30.640
Yeah, we, so that's, that's how our users control the box. So that's how we test them.
00:06:30.640 --> 00:06:39.320
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.320 --> 00:06:41.040
Or what do you, what exactly are you thinking?
00:06:41.040 --> 00:06:54.320
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.320 --> 00:07:07.760
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.760 --> 00:07:18.700
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.700 --> 00:07:28.800
Yeah. And anybody that's got, and any, we do not just cellular, but also like Wi-Fi broadcasting.
00:07:28.800 --> 00:07:35.240
So we do Wi-Fi testing and Bluetooth and anything that transmits and receives this box will test pretty much.
00:07:35.660 --> 00:07:46.900
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.900 --> 00:07:53.500
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.960 --> 00:08:03.380
Well, so the magic that glues it all together is a library that's available on PiPi called PiVisa.
00:08:03.380 --> 00:08:16.580
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.360 --> 00:08:29.000
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.000 --> 00:08:30.020
Works great.
00:08:30.020 --> 00:08:36.640
Would you say that that kind of testing is sort of more holistic or is that more like unit testing?
00:08:36.640 --> 00:08:43.220
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.220 --> 00:08:45.820
Yeah, it's definitely like an end-to-end test.
00:08:45.820 --> 00:08:49.860
We test, I'm testing our entire system.
00:08:50.420 --> 00:09:08.180
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.180 --> 00:09:09.940
Definitely more of an end-to-end.
00:09:10.520 --> 00:09:23.340
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.340 --> 00:09:31.760
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.440 --> 00:09:40.740
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.740 --> 00:09:55.880
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.880 --> 00:09:56.240
Yeah.
00:09:56.240 --> 00:09:57.300
Yeah, definitely.
00:09:57.300 --> 00:10:04.760
Yeah, but you, it sounds like your dependencies are more solid than, than maybe others, right?
00:10:04.760 --> 00:10:11.740
Like you've got physical devices and like scientific information coming in and, you know, like waveforms.
00:10:11.740 --> 00:10:14.360
And so you've, what kind of stuff do you do?
00:10:14.360 --> 00:10:16.700
That part actually isn't that different, really.
00:10:16.700 --> 00:10:28.040
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.040 --> 00:10:32.840
So that's similar to how our real signals are different from our test signals.
00:10:32.840 --> 00:10:35.560
The diff, the difficulty is, is the fuzziness.
00:10:35.560 --> 00:10:45.780
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.780 --> 00:10:53.960
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.960 --> 00:10:54.860
Otherwise it's wrong.
00:10:55.040 --> 00:10:59.700
And almost all of our measurements are, are, we've got tolerances around them.
00:10:59.700 --> 00:11:00.900
That's really interesting.
00:11:00.900 --> 00:11:09.320
Uh, a lot of people write software that is basically deterministic in, in ways that are easy to assess.
00:11:09.320 --> 00:11:19.040
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.040 --> 00:11:21.300
These super clear distinctions.
00:11:21.600 --> 00:11:31.380
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.380 --> 00:11:31.720
Yeah.
00:11:31.720 --> 00:11:37.820
I mean, if you get back a number and it's off by a thousandth, is that still the same?
00:11:37.820 --> 00:11:39.600
Does that count as okay or not?
00:11:39.600 --> 00:11:39.880
Right.
00:11:39.880 --> 00:11:41.180
That, that can be really challenging.
00:11:41.180 --> 00:11:41.800
Yeah.
00:11:41.800 --> 00:11:43.900
But there's, I mean, there's, there's ways to do it.
00:11:43.900 --> 00:11:51.580
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.580 --> 00:12:08.000
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.180 --> 00:12:09.520
So it all works out.
00:12:09.520 --> 00:12:09.840
Yeah.
00:12:09.840 --> 00:12:11.040
That's an interesting point.
00:12:11.040 --> 00:12:25.340
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.600 --> 00:12:28.940
That's like some other guy in, in like a manufacturing facility.
00:12:28.940 --> 00:12:35.440
Um, I'm, I'm mostly concerned with that, making sure all the heart, all the software didn't muck things up.
00:12:35.440 --> 00:12:45.220
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.220 --> 00:12:46.580
Right, right, right.
00:12:46.580 --> 00:12:50.820
So you assume that the hardware you've got is actually processing everything.
00:12:50.820 --> 00:12:51.180
Okay.
00:12:51.180 --> 00:12:55.380
But you've got to gather it, save it, interpret it, all that kind of stuff.
00:12:55.380 --> 00:12:57.800
And so you kind of start at that level, right?
00:12:57.800 --> 00:12:58.540
Yeah.
00:12:58.540 --> 00:13:10.700
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.700 --> 00:13:13.840
And then we don't put some, some array in the wrong place.
00:13:14.120 --> 00:13:17.120
Um, that's, that's the sort of stuff that I'm really concerned with.
00:13:17.120 --> 00:13:19.100
Yeah, that's interesting.
00:13:19.100 --> 00:13:23.940
One of my first jobs was working at a place called eye tracking, Inc.
00:13:23.940 --> 00:13:25.400
Uh, eye tracking.com.
00:13:25.400 --> 00:13:33.440
And we would build these scientific visualization tools and sort of data analysis on top of eye tracking data, right?
00:13:33.440 --> 00:13:36.700
Pupil dilation over time, where you're looking, that, that kind of stuff.
00:13:36.700 --> 00:13:43.440
And we would end up doing really complicated math sort of pipelines on it, you know, Fourier analysis,
00:13:43.800 --> 00:13:45.520
wavelet decomposition, those kinds of things.
00:13:45.520 --> 00:13:51.040
And you try to, you know, test the results of one of those things, you know, it's super hard.
00:13:51.040 --> 00:14:03.100
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.160 --> 00:14:07.900
Because the, maybe they use something like MATLAB to generate the reference results.
00:14:08.080 --> 00:14:13.640
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.640 --> 00:14:14.540
Yeah.
00:14:14.540 --> 00:14:20.160
It's an interesting challenge that I think a lot of people building, I don't know, more standard business apps.
00:14:20.160 --> 00:14:21.920
It doesn't really get on your radar, right?
00:14:22.000 --> 00:14:24.700
Because the user is either an admin or not.
00:14:24.700 --> 00:14:26.040
You know, assert true, done.
00:14:26.040 --> 00:14:27.200
Yeah.
00:14:27.200 --> 00:14:33.000
I mean, actually, people that have that sort of a test job, I'm like, what's so hard about this?
00:14:33.000 --> 00:14:35.420
Just, you know, write the test and get on with life.
00:14:36.380 --> 00:14:36.580
Yeah.
00:14:36.580 --> 00:14:37.440
So, okay.
00:14:37.440 --> 00:14:42.160
So let's, let's look at some of the frameworks and get some of your thoughts on that.
00:14:42.160 --> 00:14:48.220
So let's say the majority of people listening know what unit testing is, what the goals are.
00:14:48.220 --> 00:14:54.120
But I know a lot of my listeners are sort of scientists getting into programming or new programmers.
00:14:54.120 --> 00:14:57.160
So maybe give us just the elevator pitch.
00:14:57.160 --> 00:14:58.340
What is unit testing?
00:14:58.340 --> 00:14:59.120
Why do we care?
00:14:59.120 --> 00:15:02.360
I'm not sure why we care about unit testing, actually.
00:15:02.360 --> 00:15:05.260
Or software testing, rather.
00:15:05.340 --> 00:15:18.020
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.020 --> 00:15:23.840
And that just meant any developer test, anything written by developers, not written by the QA team.
00:15:23.840 --> 00:15:27.840
And, and in a lot of communities, it's stuck with that.
00:15:27.840 --> 00:15:31.420
It is, that's the, the, the use model.
00:15:31.520 --> 00:15:35.960
That's what a lot of people commonly term, term a unit test is something written by a developer.
00:15:35.960 --> 00:15:41.480
And then in the TDD community, that often isn't the, the definition.
00:15:41.480 --> 00:15:45.880
The unit test is often the, the smallest possible, like one function.
00:15:45.880 --> 00:15:47.460
You're testing one function at a time.
00:15:48.200 --> 00:15:56.200
And I look at, so there's the, the, the most importantly is that the entire, the entire thing is tested.
00:15:56.200 --> 00:15:57.680
Your entire software is tested.
00:15:57.680 --> 00:16:03.820
And unit testing is, I think there's certain places where you want to go in and test.
00:16:04.480 --> 00:16:07.220
I like to put tests anywhere where I have a promise.
00:16:07.220 --> 00:16:12.540
If I'm promising anybody other than myself that things are going to work right, we need tests there.
00:16:12.540 --> 00:16:19.400
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.400 --> 00:16:26.400
But the, and in your, anywhere there's interfaces, interfaces between groups or between components.
00:16:26.400 --> 00:16:28.140
Those are great places to put tests.
00:16:28.920 --> 00:16:31.300
And then of course the entire system function tests.
00:16:31.300 --> 00:16:43.060
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.060 --> 00:16:49.140
I think there's different scenarios where things like unit tests matter more and other times they matter less.
00:16:49.140 --> 00:16:57.820
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.200 --> 00:17:00.620
And you don't necessarily know everything that's changing.
00:17:00.620 --> 00:17:01.520
Right.
00:17:01.520 --> 00:17:12.020
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.020 --> 00:17:19.040
And they didn't understand this like implicit contract I built around the return value here or something like that.
00:17:19.040 --> 00:17:19.260
Right.
00:17:19.260 --> 00:17:19.900
Yeah.
00:17:19.900 --> 00:17:22.060
So I think it's really valuable there.
00:17:22.060 --> 00:17:28.160
And I think it's valuable for helping, helping build apps where fewer people are working on it.
00:17:28.160 --> 00:17:29.380
There there's less churn.
00:17:29.380 --> 00:17:44.240
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.740 --> 00:17:45.920
Everything is TDD.
00:17:45.920 --> 00:17:49.360
If you don't start that way, it's bad software.
00:17:49.360 --> 00:17:50.420
You just can't write it.
00:17:50.420 --> 00:17:52.680
How can you possibly stand up for it?
00:17:52.680 --> 00:17:57.300
And, you know, over time I saw a lot of people saying, well, we can't do that.
00:17:57.300 --> 00:17:57.980
Right.
00:17:58.120 --> 00:18:00.700
We are in too much of a hurry or whatever.
00:18:00.700 --> 00:18:02.320
You know, they have whatever excuse.
00:18:02.320 --> 00:18:04.440
A lot of times it wasn't totally unreasonable.
00:18:04.440 --> 00:18:10.040
We basically say we can't match that level of commitment to testing.
00:18:10.040 --> 00:18:11.520
So we're not going to do any.
00:18:11.520 --> 00:18:19.120
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.120 --> 00:18:23.640
Because, you know, if they had written, like you had said, the thing you're making a promise about, right?
00:18:23.640 --> 00:18:29.840
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.840 --> 00:18:35.020
The, the part that logs that the app started probably doesn't need you in a test, right?
00:18:35.020 --> 00:18:39.080
There's lots of parts of apps that are just there to support some sort of core.
00:18:39.080 --> 00:18:42.560
And that core is much more important that it's tested, I think.
00:18:42.560 --> 00:18:43.740
And what do you, what do you think?
00:18:44.300 --> 00:18:45.000
Yeah, totally.
00:18:45.000 --> 00:18:53.160
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.160 --> 00:18:55.180
The reason why somebody is buying your thing.
00:18:55.180 --> 00:18:57.580
That's what you should test the heck out of.
00:18:57.580 --> 00:18:58.900
Yes, absolutely.
00:18:58.900 --> 00:19:05.960
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.960 --> 00:19:06.220
Yeah.
00:19:06.220 --> 00:19:09.400
But there's, as you know, you ship real software.
00:19:09.400 --> 00:19:12.520
It's like, that's like 20% of the code you write.
00:19:12.620 --> 00:19:14.440
There's 80% that isn't that.
00:19:14.440 --> 00:19:18.620
Well, and then I like, I like code coverage tools.
00:19:18.620 --> 00:19:26.440
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.440 --> 00:19:31.040
There's a, you can either write more tests or you can delete code.
00:19:31.040 --> 00:19:33.640
I think you should delete more code.
00:19:33.640 --> 00:19:40.500
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.500 --> 00:19:49.220
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.220 --> 00:19:50.700
That's a really interesting point.
00:19:50.780 --> 00:19:50.960
Yeah.
00:19:50.960 --> 00:19:51.440
Yeah.
00:19:51.440 --> 00:19:51.500
Yeah.
00:19:51.500 --> 00:20:04.740
This episode is brought to you by Hired.
00:20:04.740 --> 00:20:10.340
Hired is a two-sided curated marketplace that connects the world's knowledge workers to the best opportunities.
00:20:10.820 --> 00:20:17.840
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.840 --> 00:20:23.580
Typically, candidates receive five or more offers within the first week, and there are no obligations, ever.
00:20:23.580 --> 00:20:25.140
Sounds awesome, doesn't it?
00:20:25.320 --> 00:20:26.800
Well, did I mention the signing bonus?
00:20:26.800 --> 00:20:30.180
Everyone who accepts a job from Hired gets a $1,000 signing bonus.
00:20:30.180 --> 00:20:32.980
And as Talk Python listeners, it gets way sweeter.
00:20:32.980 --> 00:20:38.700
Use the link Hired.com slash Talk Python To Me, and Hired will double the signing bonus to $2,000.
00:20:38.700 --> 00:20:40.840
Opportunity's knocking.
00:20:40.840 --> 00:20:44.260
Visit Hired.com slash Talk Python To Me and answer the call.
00:20:49.860 --> 00:21:01.100
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.100 --> 00:21:02.740
And there'll be like some method.
00:21:02.740 --> 00:21:04.440
I'm like, what does this do?
00:21:04.440 --> 00:21:07.260
What does this have anything to do with this code?
00:21:07.260 --> 00:21:08.700
It doesn't seem to do anything.
00:21:08.700 --> 00:21:15.000
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.000 --> 00:21:15.180
Yeah.
00:21:15.180 --> 00:21:17.160
Somebody should have just deleted it.
00:21:17.160 --> 00:21:20.920
They should have just deleted it and the world would have been a better place.
00:21:20.920 --> 00:21:23.080
But instead, you know, I wasted two hours.
00:21:23.080 --> 00:21:24.480
Somebody else probably wasted two hours.
00:21:24.480 --> 00:21:26.460
And it just gets kicked down the road.
00:21:26.460 --> 00:21:33.860
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.860 --> 00:21:37.040
I used to mostly focus on high level tests.
00:21:37.040 --> 00:21:42.700
But the, and I still do, but lower level tests do have their place.
00:21:43.300 --> 00:21:48.840
But the, I like the model of, in test-driven development of the red-green refactor.
00:21:48.840 --> 00:21:51.580
But just don't forget the refactor part.
00:21:51.580 --> 00:21:59.520
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.220 --> 00:22:05.440
I don't want to, I don't want to restrict my ability to change my mind and redesign something.
00:22:05.440 --> 00:22:05.880
So.
00:22:05.880 --> 00:22:13.900
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.900 --> 00:22:14.820
Well, I'm not even going to start.
00:22:14.820 --> 00:22:15.320
Forget this.
00:22:15.320 --> 00:22:16.900
It's too much work to do testing, right?
00:22:17.320 --> 00:22:17.580
Yeah.
00:22:17.580 --> 00:22:28.300
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.300 --> 00:22:32.220
But where do you start when you have like a 10 years of legacy code?
00:22:32.220 --> 00:22:34.920
You can't just cover everything.
00:22:34.920 --> 00:22:38.480
So yeah, there's a, you got to just start somewhere.
00:22:38.480 --> 00:22:42.260
You know, I have a book recommendation actually, now that you bring that up.
00:22:42.260 --> 00:22:52.460
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.460 --> 00:22:57.300
And he wrote a book called Working Effectively with Legacy Code.
00:22:58.180 --> 00:23:20.220
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.220 --> 00:23:22.040
And definitely recommend it.
00:23:22.100 --> 00:23:31.520
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.520 --> 00:23:32.160
Okay.
00:23:32.160 --> 00:23:32.680
Yeah.
00:23:32.680 --> 00:23:33.620
Have you seen that one?
00:23:33.620 --> 00:23:34.960
Definitely.
00:23:34.960 --> 00:23:38.760
I've got a difference of opinion on that one, but I'll just let that go.
00:23:38.760 --> 00:23:39.500
No, no, no, no, no.
00:23:39.500 --> 00:23:40.080
I wouldn't hear it.
00:23:40.080 --> 00:23:40.460
Tell me.
00:23:40.460 --> 00:23:46.380
I think it just seems silly to try to add a bunch of unit tests to a bunch of existing code.
00:23:46.380 --> 00:23:52.240
I think it's way more profitable for your company to put functionality testing around it.
00:23:52.240 --> 00:23:57.140
And because they like the end to end functionality testing of your system.
00:23:57.140 --> 00:24:06.840
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.840 --> 00:24:16.500
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.500 --> 00:24:17.180
Sure.
00:24:17.180 --> 00:24:20.000
So I think that's a totally, totally valid point.
00:24:20.000 --> 00:24:25.080
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.080 --> 00:24:28.660
So, you know, I'm, I'm going to only get it like a little bit, right.
00:24:28.660 --> 00:24:37.640
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.640 --> 00:24:42.600
And it gives you an answer back rather than trying to set up a whole bunch of tests inside there.
00:24:42.600 --> 00:24:48.360
The question was like, well, how could I refactor some dependency or some bits?
00:24:48.360 --> 00:24:48.580
Right.
00:24:48.580 --> 00:24:53.860
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.860 --> 00:24:55.000
We're going to call it good.
00:24:55.000 --> 00:25:01.680
It was some, some like really basic scaffolding to say the thing kind of looks still okay.
00:25:01.680 --> 00:25:02.740
Yeah.
00:25:02.740 --> 00:25:14.960
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.960 --> 00:25:22.640
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.640 --> 00:25:27.780
It's just, it's just, they don't, they don't test for that.
00:25:27.780 --> 00:25:29.340
Yeah, that's right.
00:25:29.340 --> 00:25:45.840
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.120 --> 00:25:47.120
Can you go into that a bit?
00:25:47.120 --> 00:25:48.080
Yeah, sure.
00:25:48.080 --> 00:25:55.440
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.940 --> 00:25:56.640
All right.
00:25:56.640 --> 00:26:05.360
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.500 --> 00:26:16.260
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.260 --> 00:26:17.440
And, um.
00:26:17.440 --> 00:26:17.620
Right.
00:26:17.620 --> 00:26:20.540
Kind of like a food pyramid where like the dessert is at the top.
00:26:20.540 --> 00:26:23.400
You should have just a little tiny bit and that's the functional bit at the top.
00:26:23.840 --> 00:26:24.280
Yeah.
00:26:24.280 --> 00:26:37.680
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.680 --> 00:26:39.500
I just don't buy it.
00:26:39.500 --> 00:26:44.040
Um, and what, what happens I think is developers see that and they go, Oh, okay.
00:26:44.040 --> 00:26:48.380
Focus on unit tests and leave, leave the end to end test to QA.
00:26:48.580 --> 00:26:53.440
The problem with that big problem with that is a lot of teams don't have a QA anymore.
00:26:53.440 --> 00:26:56.660
So there's nobody doing end to end tests.
00:26:56.660 --> 00:26:58.500
Somebody's got to.
00:26:58.500 --> 00:27:01.620
Um, so it's, if there's no QA, then it's your customers.
00:27:01.620 --> 00:27:05.860
And, I don't think that's the right person to do quality assurance.
00:27:05.860 --> 00:27:15.780
So I, I, I think that focusing on, maybe a column of tests, it should be a column, not a pyramid.
00:27:16.840 --> 00:27:18.780
Do, do the tests where they make sense.
00:27:18.780 --> 00:27:28.180
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.180 --> 00:27:40.420
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.800 --> 00:27:44.200
And then, I don't really know what integration tests are.
00:27:44.200 --> 00:27:47.480
There's a lot of definitions for it, but it's the middle part.
00:27:47.480 --> 00:27:52.180
And sometimes it's integration test means integrating with the outside world.
00:27:52.180 --> 00:27:55.920
So if you're integrating with a database library, it's tests against that.
00:27:56.020 --> 00:28:02.260
But then also some people think of, integration tests as between two components or between two functions.
00:28:02.260 --> 00:28:06.960
And then unit tests are the, the low level while you're designing your code.