WEBVTT 1 00:00:00.050 --> 00:00:01.660 Hi guys and welcome back. 2 00:00:01.660 --> 00:00:04.060 In this video, we're going to be writing some more tests 3 00:00:04.060 --> 00:00:06.140 for the printer just to give you a bit more practise 4 00:00:06.140 --> 00:00:08.310 and show you a couple more things. 5 00:00:08.310 --> 00:00:12.970 Let's begin by writing a test for printing outside capacity. 6 00:00:12.970 --> 00:00:16.340 Like we did earlier, we will do with.self.assertRaises 7 00:00:17.460 --> 00:00:21.203 and now it'll be a PrinterError that we're gonna catch. 8 00:00:22.090 --> 00:00:25.863 We'll do self.printer.print 301. 9 00:00:27.420 --> 00:00:31.890 Notice that we printed 25 pages in this nest. 10 00:00:31.890 --> 00:00:35.630 So, here we could, in theory, do 276 11 00:00:35.630 --> 00:00:38.173 in order to still breach capacity. 12 00:00:40.530 --> 00:00:42.920 No, that's absolutely not correct. 13 00:00:42.920 --> 00:00:44.910 I hope that you didn't believe me there. 14 00:00:44.910 --> 00:00:47.000 You're getting a new printer for each nest 15 00:00:47.000 --> 00:00:51.410 because we've got this setup and not setup class. 16 00:00:51.410 --> 00:00:54.050 Remember exactly what I said there, 17 00:00:54.050 --> 00:00:58.260 this dependency between two tests is a bad thing. 18 00:00:58.260 --> 00:00:59.583 You do not want that. 19 00:01:00.510 --> 00:01:03.460 So, you do need 301 pages in order to breach capacity 20 00:01:03.460 --> 00:01:08.040 because this printer is a new printer related to this one. 21 00:01:08.040 --> 00:01:09.020 Okay. 22 00:01:09.020 --> 00:01:11.400 So, this should raise a PrinterError. 23 00:01:11.400 --> 00:01:14.040 And indeed as we save the file, these tests run 24 00:01:14.040 --> 00:01:16.140 and you get two out of two. 25 00:01:16.140 --> 00:01:19.900 Notice that if we do 276, the test fails there 26 00:01:19.900 --> 00:01:23.003 because the printer is a new printer. 27 00:01:24.180 --> 00:01:26.633 So, it says PrinterError not raised. 28 00:01:28.420 --> 00:01:30.000 Hope you didn't believe me there. 29 00:01:30.000 --> 00:01:34.740 So, next one is we are going to print the exact capacity. 30 00:01:34.740 --> 00:01:38.453 So, we'll say test print the exact capacity. 31 00:01:41.930 --> 00:01:46.930 And we will do self.printer.print, self.printer.capacity. 32 00:01:51.420 --> 00:01:53.180 Now this is a private property 33 00:01:53.180 --> 00:01:56.640 or at least a property that has an underscore in front it. 34 00:01:56.640 --> 00:01:59.380 So, in theory, you should not use it, 35 00:01:59.380 --> 00:02:00.770 but really what it means in Python 36 00:02:00.770 --> 00:02:04.090 is you should not change it, but you can still read it, 37 00:02:04.090 --> 00:02:05.600 and that's what we're reading here. 38 00:02:05.600 --> 00:02:08.600 So, we're going to print exactly up to the capacity 39 00:02:08.600 --> 00:02:10.820 of the printer, and this is an important one to check 40 00:02:10.820 --> 00:02:12.945 because it is very frequent 41 00:02:12.945 --> 00:02:17.945 that you will have something like this in your if statement 42 00:02:18.570 --> 00:02:20.090 is a fairly mistake to make 43 00:02:20.090 --> 00:02:21.520 and then you'll see that it fails. 44 00:02:21.520 --> 00:02:24.730 And you will never be able to print the last page 45 00:02:24.730 --> 00:02:25.780 in your printer. 46 00:02:25.780 --> 00:02:28.780 Even when your printer has one page left of ink, 47 00:02:28.780 --> 00:02:30.890 if you have a check like this one, 48 00:02:30.890 --> 00:02:31.850 you won't be able to print it 49 00:02:31.850 --> 00:02:34.300 because one will be equal to one, 50 00:02:34.300 --> 00:02:36.460 which is the capacity left. 51 00:02:36.460 --> 00:02:37.330 So, you want to do, 52 00:02:37.330 --> 00:02:40.290 if the pages is greater than the capacity, 53 00:02:40.290 --> 00:02:41.260 you want to raise the error. 54 00:02:41.260 --> 00:02:45.120 So, if pages is one and capacity is one, 55 00:02:45.120 --> 00:02:46.380 you will still print. 56 00:02:46.380 --> 00:02:50.580 If pages is one and capacity is zero, then you won't print 57 00:02:50.580 --> 00:02:52.370 and you'll raise an error. 58 00:02:52.370 --> 00:02:53.203 Okay. 59 00:02:53.203 --> 00:02:54.036 So, this is an important one to check, 60 00:02:54.036 --> 00:02:55.533 a very frequent mistake. 61 00:02:57.070 --> 00:03:00.690 Next up, we could test the printer speed, 62 00:03:00.690 --> 00:03:04.310 and this is really what we're doing here. 63 00:03:04.310 --> 00:03:06.130 So, you could write a separate message 64 00:03:06.130 --> 00:03:08.303 that says test_printer_speed 65 00:03:09.760 --> 00:03:12.180 and then you can have a pages 10 66 00:03:12.180 --> 00:03:17.180 and an expected message of printed 10 pages in 5.00 seconds. 67 00:03:19.030 --> 00:03:20.650 Then you will get your result, 68 00:03:20.650 --> 00:03:25.650 which will be self.printer.print 10 pages, 69 00:03:27.620 --> 00:03:31.790 and then self.assertEqual the result 70 00:03:31.790 --> 00:03:34.390 and the expected message. 71 00:03:34.390 --> 00:03:38.260 I would do this instead of checking the message here 72 00:03:38.260 --> 00:03:40.703 and then I would remove this and put it there. 73 00:03:41.723 --> 00:03:46.723 That way, you have two tests that do two separate things. 74 00:03:46.750 --> 00:03:50.800 If you get an error because you run out of capacity 75 00:03:50.800 --> 00:03:54.226 just by print 25 pages, even though the capacity is 300, 76 00:03:54.226 --> 00:03:56.540 then you're gonna catch it with this test 77 00:03:56.540 --> 00:03:57.640 and not with this one. 78 00:03:58.860 --> 00:04:02.030 Similarly, for example, let's say that you set capacity 79 00:04:02.030 --> 00:04:07.030 to 300, but you have hardcoded capacity to 20 here, 80 00:04:07.960 --> 00:04:10.073 then your test will fail. 81 00:04:13.260 --> 00:04:16.530 Self.printer.print 25 fails 82 00:04:16.530 --> 00:04:18.940 even though you've set capacity to 300 83 00:04:18.940 --> 00:04:21.320 because you hardcoded it to 20 here. 84 00:04:21.320 --> 00:04:23.505 This could happen for example if you forget to make it equal 85 00:04:23.505 --> 00:04:26.880 to capacity and instead you hardcode it to a value 86 00:04:26.880 --> 00:04:29.210 while you're developing the class. 87 00:04:29.210 --> 00:04:32.400 That's why I'm a big fan of having separate tests 88 00:04:32.400 --> 00:04:35.280 that do separate individual checks 89 00:04:35.280 --> 00:04:37.960 as opposed to one that does multiple things. 90 00:04:37.960 --> 00:04:39.290 Of course, sometimes you're not sure 91 00:04:39.290 --> 00:04:42.080 if your test is testing one thing or two things. 92 00:04:42.080 --> 00:04:43.470 It can be difficult to gauge, 93 00:04:43.470 --> 00:04:44.950 but don't worry too much about it, 94 00:04:44.950 --> 00:04:46.680 just do the best you can 95 00:04:46.680 --> 00:04:50.450 and I'm sure that, over time, you will get better at it. 96 00:04:50.450 --> 00:04:53.750 Next up, let's test that the speed here 97 00:04:53.750 --> 00:04:55.580 or how many seconds it takes 98 00:04:55.580 --> 00:04:57.790 is always printed out to two decimal places 99 00:04:57.790 --> 00:04:59.550 and not, say, 10. 100 00:04:59.550 --> 00:05:01.870 So, we will say that we've got a new printer 101 00:05:01.870 --> 00:05:04.530 called fast_printer, that is, another printer object, 102 00:05:04.530 --> 00:05:06.830 where the pages per second is 3.0 103 00:05:06.830 --> 00:05:09.210 and the capacity is also 300. 104 00:05:09.210 --> 00:05:12.680 The pages we're gonna print is 11 and the expected message 105 00:05:13.710 --> 00:05:18.710 is printed 11 pages in 3.67 seconds. 106 00:05:19.580 --> 00:05:24.580 This is important because the way that Python will do it 107 00:05:25.370 --> 00:05:30.370 if you divide 11 by 3.0 is it'll be 3.666667 108 00:05:30.780 --> 00:05:32.970 and you don't want that normally 109 00:05:32.970 --> 00:05:35.300 when you're giving a message to a user. 110 00:05:35.300 --> 00:05:38.147 So, we will say fast_printer.print pages 111 00:05:38.147 --> 00:05:40.440 and then we will do self.assertEqual 112 00:05:41.978 --> 00:05:44.113 the result and the expected. 113 00:05:45.530 --> 00:05:46.363 Okay. 114 00:05:46.363 --> 00:05:49.130 So, run this and look at the tests passed, 115 00:05:49.130 --> 00:05:50.130 five out of five. 116 00:05:50.130 --> 00:05:53.730 If you go back to your printer and you take away this .2f, 117 00:05:53.730 --> 00:05:56.150 you'll see that this test then fails 118 00:05:57.760 --> 00:06:02.460 because you get first of all 5.0 seconds instead of 5.00 119 00:06:02.460 --> 00:06:05.860 and then you also get 3.66665. 120 00:06:05.860 --> 00:06:08.033 I thought it would be seven, but it is not. 121 00:06:09.130 --> 00:06:09.963 Okay. 122 00:06:09.963 --> 00:06:14.963 So, this is why we have that and these tests here. 123 00:06:14.980 --> 00:06:17.710 Really both of these are testing something similar, 124 00:06:17.710 --> 00:06:20.010 but this one is more gauged to testing, 125 00:06:20.010 --> 00:06:21.740 making sure the speed is correct. 126 00:06:21.740 --> 00:06:23.830 This one is making sure that the decimals are correct 127 00:06:23.830 --> 00:06:25.940 when there would be many of them. 128 00:06:25.940 --> 00:06:29.140 Next up, we can test for multiple print runs, 129 00:06:29.140 --> 00:06:31.250 making sure that a printer can print 130 00:06:31.250 --> 00:06:33.280 multiple times in succession. 131 00:06:33.280 --> 00:06:38.280 And we can print up to, say, the limit of capacity, 132 00:06:39.810 --> 00:06:44.640 then we can test multiple runs and there'll be an error 133 00:06:46.350 --> 00:06:47.640 where we essentially do the same thing 134 00:06:47.640 --> 00:06:52.640 but the last one is 226 or maybe we can even make it 135 00:06:53.040 --> 00:06:55.083 a bit more explicit just like that. 136 00:06:56.090 --> 00:06:56.923 All right. 137 00:06:56.923 --> 00:06:59.410 So, here are a few of the tests that we've come up with 138 00:06:59.410 --> 00:07:03.290 just for this simple printer class. 139 00:07:03.290 --> 00:07:07.780 And remember, the purpose of the tests is two-fold, 140 00:07:07.780 --> 00:07:09.560 or mostly two-fold. 141 00:07:09.560 --> 00:07:14.270 The first purpose is to document and to show the reader 142 00:07:14.270 --> 00:07:16.660 what the thing you're testing does 143 00:07:16.660 --> 00:07:19.480 and how it behaves in different scenarios. 144 00:07:19.480 --> 00:07:21.490 So, by looking at these tests here, 145 00:07:21.490 --> 00:07:24.470 you need to take your time to of course understand them, 146 00:07:24.470 --> 00:07:27.460 but you'll be able to glean that this printer 147 00:07:27.460 --> 00:07:29.960 has a print method that returns a message 148 00:07:29.960 --> 00:07:32.500 and it reaches errors, gets over here 149 00:07:32.500 --> 00:07:33.720 to when you go over the limit 150 00:07:33.720 --> 00:07:36.230 and you can print exactly up to the limit 151 00:07:36.230 --> 00:07:38.610 and you can do multiple print runs and so on. 152 00:07:38.610 --> 00:07:41.053 So, it's a little bit like documentation. 153 00:07:42.090 --> 00:07:43.290 If you're working on a team 154 00:07:43.290 --> 00:07:45.270 and you're working with other people, 155 00:07:45.270 --> 00:07:47.740 they'll be a lot of code in a large code base 156 00:07:47.740 --> 00:07:49.300 that you've never seen before. 157 00:07:49.300 --> 00:07:52.130 By looking at the tests in the large code bases, 158 00:07:52.130 --> 00:07:53.810 you can much more easily understand 159 00:07:53.810 --> 00:07:54.720 everything that's going on 160 00:07:54.720 --> 00:07:56.500 as long as the tests are good, of course. 161 00:07:56.500 --> 00:08:01.500 The second purpose of tests is to check that the code works 162 00:08:01.910 --> 00:08:04.370 in the same way that it did the last time. 163 00:08:04.370 --> 00:08:05.940 So, if somebody comes into your printer 164 00:08:05.940 --> 00:08:07.820 and makes a few changes, 165 00:08:07.820 --> 00:08:09.650 for example if they change this print method 166 00:08:09.650 --> 00:08:11.960 so that it no longer raises an error, 167 00:08:11.960 --> 00:08:15.640 you almost certainly want your tests to fail 168 00:08:15.640 --> 00:08:17.920 because if they don't, (laughs) 169 00:08:17.920 --> 00:08:20.280 then you can see that it tells me that, two failed. 170 00:08:20.280 --> 00:08:22.430 If your tests don't fail, 171 00:08:22.430 --> 00:08:25.410 it means that potentially in many places in your code, 172 00:08:25.410 --> 00:08:28.080 you could be depending on the error being raised 173 00:08:28.080 --> 00:08:29.900 and you are none the wiser. 174 00:08:29.900 --> 00:08:33.420 You don't know if that error is being raised or not anymore 175 00:08:33.420 --> 00:08:35.400 if you don't have tests for it. 176 00:08:35.400 --> 00:08:37.800 So, the tests, the second purpose of the tests 177 00:08:37.800 --> 00:08:41.763 is to keep you right in what you believe about your code. 178 00:08:42.730 --> 00:08:46.450 Of course, there is a third and final use of tests, 179 00:08:46.450 --> 00:08:48.650 which is that by writing tests, 180 00:08:48.650 --> 00:08:51.470 it will force you to write better code. 181 00:08:51.470 --> 00:08:53.530 If the code is very difficult to test, 182 00:08:53.530 --> 00:08:55.770 you're gonna have problems testing it. 183 00:08:55.770 --> 00:08:58.570 And that means usually that the code is too complicated. 184 00:08:58.570 --> 00:09:00.110 So, you should split it out into functions 185 00:09:00.110 --> 00:09:03.070 and test those separately and so on. 186 00:09:03.070 --> 00:09:04.317 In the coming videos, we're going to look 187 00:09:04.317 --> 00:09:07.590 at how you can split your code into functions 188 00:09:07.590 --> 00:09:11.070 and how to test when you have multiple layers. 189 00:09:11.070 --> 00:09:13.710 So, we're gonna be using patching and mocking 190 00:09:13.710 --> 00:09:14.823 in order to do that. 191 00:09:14.823 --> 00:09:15.970 It's really simple. 192 00:09:15.970 --> 00:09:18.383 It looks complicated, but it really isn't. 193 00:09:19.510 --> 00:09:20.940 Thanks for joining me in this video. 194 00:09:20.940 --> 00:09:22.390 I'll see you in the next one.