1 00:00:06,570 --> 00:00:08,100 - In this section, we're going to see 2 00:00:08,100 --> 00:00:11,580 how and why to define parameterized tests. 3 00:00:11,580 --> 00:00:13,320 So, first of all, to understand the need 4 00:00:13,320 --> 00:00:15,270 for parameterized tests, we're gonna have a look 5 00:00:15,270 --> 00:00:18,660 at some code in the ParameterizedTests folder. 6 00:00:18,660 --> 00:00:21,600 I'm gonna show you a simple JavaScript file 7 00:00:21,600 --> 00:00:25,260 with an add function, which just adds two numbers together. 8 00:00:25,260 --> 00:00:27,720 And then I have some tests in this file 9 00:00:27,720 --> 00:00:29,880 which calls the add function several times 10 00:00:29,880 --> 00:00:31,080 with different inputs 11 00:00:31,080 --> 00:00:34,770 and with a different expected result each time. 12 00:00:34,770 --> 00:00:36,540 So let me show you the code first. 13 00:00:36,540 --> 00:00:41,540 So in JsTdd lesson three in the ParameterizedTests folder. 14 00:00:41,970 --> 00:00:45,180 I fill up that folder in the code editor 15 00:00:45,180 --> 00:00:47,160 that it looks like this. 16 00:00:47,160 --> 00:00:49,500 We have a simple calc.js. 17 00:00:49,500 --> 00:00:52,560 A very simple add function, adds two numbers together. 18 00:00:52,560 --> 00:00:54,990 And then I have four different versions 19 00:00:54,990 --> 00:00:57,630 of a test showing how to parameterized it. 20 00:00:57,630 --> 00:00:59,220 So, first of all, we'll have look 21 00:00:59,220 --> 00:01:04,200 at the kind of brute force approach in calc1.test. 22 00:01:04,200 --> 00:01:06,780 So in here, I import the add function. 23 00:01:06,780 --> 00:01:08,280 Have a look, I've got three tests. 24 00:01:08,280 --> 00:01:10,890 The first test, it calls the add function 25 00:01:10,890 --> 00:01:14,640 with 10 and 20 and it should give me back 30. 26 00:01:14,640 --> 00:01:16,890 The second test is exactly the same 27 00:01:16,890 --> 00:01:18,876 except that it has different inputs, 28 00:01:18,876 --> 00:01:22,800 10 and -20 with a result of -10. 29 00:01:22,800 --> 00:01:24,930 The third test is also exactly the same 30 00:01:24,930 --> 00:01:28,170 except with different inputs and a different result. 31 00:01:28,170 --> 00:01:31,830 So what we see there is a certain amount of duplication. 32 00:01:31,830 --> 00:01:34,140 The similarity between the tests is quite striking. 33 00:01:34,140 --> 00:01:37,200 The only thing that's different in each case is the numbers. 34 00:01:37,200 --> 00:01:40,440 And clearly that's not a good idea. 35 00:01:40,440 --> 00:01:42,630 You shouldn't be duplicating code like that. 36 00:01:42,630 --> 00:01:45,720 It's never a good idea to have duplicate code. 37 00:01:45,720 --> 00:01:49,470 So in a situation where we basically have the same test 38 00:01:49,470 --> 00:01:52,290 but to run it multiple times with different inputs 39 00:01:52,290 --> 00:01:53,850 and a different expected result, 40 00:01:53,850 --> 00:01:57,030 rather than having actually three separate tests, 41 00:01:57,030 --> 00:02:00,090 justify one test and parameterized it. 42 00:02:00,090 --> 00:02:01,830 And that's what I've done here. 43 00:02:01,830 --> 00:02:06,570 You can call test.each and then you give it an array 44 00:02:06,570 --> 00:02:11,040 and each array specifies a different invocation of the test. 45 00:02:11,040 --> 00:02:14,940 So this test here in black is going to be executed 46 00:02:14,940 --> 00:02:17,370 once with those inputs, 47 00:02:17,370 --> 00:02:19,530 a second time with those inputs, 48 00:02:19,530 --> 00:02:21,300 and a third time with those inputs. 49 00:02:21,300 --> 00:02:23,070 I've only written the test once, 50 00:02:23,070 --> 00:02:25,920 but it's going to be executed three times. 51 00:02:25,920 --> 00:02:29,430 So this test, it has a description 52 00:02:29,430 --> 00:02:32,490 and it has prompted as n1, n2, expected. 53 00:02:32,490 --> 00:02:35,010 These are the values that are going to get passed in. 54 00:02:35,010 --> 00:02:38,010 So the first time, a test will be executed. 55 00:02:38,010 --> 00:02:43,010 10 will be passed into n1, 20 into n2, 30 into expected. 56 00:02:44,820 --> 00:02:49,203 And adds 10 and 20 and the expected value should be 30. 57 00:02:50,100 --> 00:02:51,840 And then it repeats the test again. 58 00:02:51,840 --> 00:02:53,640 It runs the same test, second time. 59 00:02:53,640 --> 00:02:57,402 Passing a different set of values, 10 into n1, 60 00:02:57,402 --> 00:03:01,710 - 20 into n2, -10 into expected. 61 00:03:01,710 --> 00:03:04,560 So the second test is driven by the parameters 62 00:03:04,560 --> 00:03:06,120 and then it runs a third time. 63 00:03:06,120 --> 00:03:09,120 The same code, written once, but run three times. 64 00:03:09,120 --> 00:03:13,050 We'll now take n1, n2, expected. 65 00:03:13,050 --> 00:03:14,940 So that's a much better way of doing. 66 00:03:14,940 --> 00:03:16,410 It's much less duplication. 67 00:03:16,410 --> 00:03:19,470 I should run it just to make sure that it actually works. 68 00:03:19,470 --> 00:03:24,470 So in my command window, npm run test parameters. 69 00:03:24,570 --> 00:03:29,570 And the name of my test file is calc2.test.js. 70 00:03:32,130 --> 00:03:35,310 So it ran my test code three times 71 00:03:35,310 --> 00:03:36,810 with a different set of inputs 72 00:03:37,710 --> 00:03:39,723 and hopefully they should all pass. 73 00:03:40,890 --> 00:03:41,723 There we go. 74 00:03:42,570 --> 00:03:44,670 Unfortunately, I mean, it does work 75 00:03:44,670 --> 00:03:46,590 but when it ran the test, 76 00:03:46,590 --> 00:03:49,890 each time it ran the test, it displayed the same message, 77 00:03:49,890 --> 00:03:52,920 add two numbers to give correct result. 78 00:03:52,920 --> 00:03:55,110 So basically it displayed the same message 79 00:03:55,110 --> 00:03:58,263 or the same title for the test every time it ran it. 80 00:03:59,940 --> 00:04:03,600 So if you wanna parameterized the string as well 81 00:04:03,600 --> 00:04:07,920 to display a more useful message for each test run. 82 00:04:07,920 --> 00:04:10,323 You can do that like this. 83 00:04:11,880 --> 00:04:16,427 In the name of the test, you can define the test 84 00:04:16,427 --> 00:04:20,670 as an interpolated string with backticks 85 00:04:20,670 --> 00:04:24,270 and then you can use a %d and it'll substitute the value 86 00:04:24,270 --> 00:04:29,073 for n1 into here and n2 and expected. 87 00:04:29,910 --> 00:04:32,730 So that means that that as we run the test three times, 88 00:04:32,730 --> 00:04:36,360 we'll be using these embedded specifiers %d 89 00:04:36,360 --> 00:04:38,490 for decimal number. 90 00:04:38,490 --> 00:04:41,550 Will give us a different message name 91 00:04:41,550 --> 00:04:43,680 each test that gets executed. 92 00:04:43,680 --> 00:04:46,230 So let me show you that. 93 00:04:46,230 --> 00:04:51,223 So I'm good to run calc3.test.js. 94 00:04:52,440 --> 00:04:54,480 The tests will be run as before, 95 00:04:54,480 --> 00:04:57,060 but what's gonna be different is the titles of the test. 96 00:04:57,060 --> 00:04:58,290 Instead of having the same title 97 00:04:58,290 --> 00:05:00,900 be displayed every time like before, 98 00:05:00,900 --> 00:05:03,483 now it displays %d n1, 99 00:05:04,520 --> 00:05:07,560 %d n2, %d expected. 100 00:05:07,560 --> 00:05:10,260 So each run has different inputs 101 00:05:10,260 --> 00:05:12,390 for n1, n2, and expected. 102 00:05:12,390 --> 00:05:15,540 So the titles for the tests are more informative 103 00:05:15,540 --> 00:05:17,070 so that's better, isn't it? 104 00:05:17,070 --> 00:05:19,320 If one of these tests didn't work, 105 00:05:19,320 --> 00:05:20,668 now you've got a better idea, 106 00:05:20,668 --> 00:05:22,800 which set of inputs failed 107 00:05:22,800 --> 00:05:24,810 and that would lead you to figure out 108 00:05:24,810 --> 00:05:26,703 what the bug was in your code. 109 00:05:27,780 --> 00:05:29,730 So that's an improvement 110 00:05:29,730 --> 00:05:32,370 using these kind of embedded parameters 111 00:05:32,370 --> 00:05:35,790 to give us a more meaningful name for the tests. 112 00:05:35,790 --> 00:05:38,310 There's actually a different syntax you can use 113 00:05:38,310 --> 00:05:43,310 called an interpolated or Tagged Template Literal Syntax, 114 00:05:43,650 --> 00:05:45,720 where we have an interpolated string. 115 00:05:45,720 --> 00:05:49,590 test.each basically takes one giant string 116 00:05:49,590 --> 00:05:52,200 and this string specifies, 117 00:05:52,200 --> 00:05:55,530 well, the first line basically is one string 118 00:05:55,530 --> 00:05:59,040 where it specifies the values for the n1 parameter, 119 00:05:59,040 --> 00:06:02,100 the n2 parameter and the expected result 120 00:06:02,100 --> 00:06:04,920 for the first run and for the second run, 121 00:06:04,920 --> 00:06:05,970 and for the third one. 122 00:06:05,970 --> 00:06:08,400 The dollar curly bracket syntax here 123 00:06:08,400 --> 00:06:11,500 is ECMAScript interpolated string. 124 00:06:11,500 --> 00:06:14,280 So it basically evaluates that as a number 125 00:06:14,280 --> 00:06:16,560 and it passes in as n1. 126 00:06:16,560 --> 00:06:19,890 It evaluates this as a number and it passes as n2. 127 00:06:19,890 --> 00:06:22,170 And it evaluates this 30 as a number 128 00:06:22,170 --> 00:06:25,320 and passes it as the exp, as in expected. 129 00:06:25,320 --> 00:06:29,010 So the first row in this giant string 130 00:06:29,010 --> 00:06:30,570 that starts there and ends there, 131 00:06:30,570 --> 00:06:33,360 the first string is the name of variables. 132 00:06:33,360 --> 00:06:35,010 It's actually going to, what's gonna happen 133 00:06:35,010 --> 00:06:40,010 is every time it's gonna grab the next line. 134 00:06:40,320 --> 00:06:42,420 It'll grab the next line. 135 00:06:42,420 --> 00:06:47,420 So $10, $20, $30, and it'll put these into an object. 136 00:06:49,320 --> 00:06:50,550 It'll create an object 137 00:06:50,550 --> 00:06:53,580 with a property called n1 with a value 10, 138 00:06:53,580 --> 00:06:56,220 a property called n2 with a value 20, 139 00:06:56,220 --> 00:06:59,550 and property exp with a value 30. 140 00:06:59,550 --> 00:07:01,740 So we have an object created for us 141 00:07:01,740 --> 00:07:04,155 with properties n1, n2 and exp . 142 00:07:04,155 --> 00:07:08,700 And that object then gets passed into the test function. 143 00:07:08,700 --> 00:07:11,670 And in this text function, it receives an object 144 00:07:11,670 --> 00:07:13,696 and it uses destructuring. 145 00:07:13,696 --> 00:07:15,300 This is destructuring syntax. 146 00:07:15,300 --> 00:07:17,070 This, it receives an object 147 00:07:17,070 --> 00:07:20,580 and it extracts the n1 property into this variable. 148 00:07:20,580 --> 00:07:24,330 And it extracts the n2 property, 20, into that variable. 149 00:07:24,330 --> 00:07:27,990 And it extracts the exp property, 30, into that variable. 150 00:07:27,990 --> 00:07:31,170 And notice, the string here is slightly 151 00:07:31,170 --> 00:07:32,100 different syntax as well. 152 00:07:32,100 --> 00:07:32,933 We say $n1. 153 00:07:33,870 --> 00:07:37,267 So that would be the value of the n1 parameter, 10. 154 00:07:37,267 --> 00:07:41,490 $n2 is the value of the n2 parameter, which would be 20. 155 00:07:41,490 --> 00:07:42,540 So it's time through. 156 00:07:42,540 --> 00:07:46,200 And the $exp is obviously the value of the exp parameter, 157 00:07:46,200 --> 00:07:47,310 which would be 30. 158 00:07:47,310 --> 00:07:49,590 So there's a slightly different syntax here 159 00:07:49,590 --> 00:07:51,570 for building formatted string 160 00:07:51,570 --> 00:07:53,370 and a slightly different syntax here 161 00:07:53,370 --> 00:07:55,680 for grabbing access to the values. 162 00:07:55,680 --> 00:07:58,830 So this function will be called. 163 00:07:58,830 --> 00:08:03,210 The first time an object with an n1, n2, exp property 164 00:08:03,210 --> 00:08:06,150 set to these values, 10, 20, 30. 165 00:08:06,150 --> 00:08:08,880 Again, it'll call the function a second time, 166 00:08:08,880 --> 00:08:13,372 pass in an object with an n1, n2, exp property. 167 00:08:13,372 --> 00:08:17,760 So it'd be 10, -20, -10 and so on and so forth. 168 00:08:17,760 --> 00:08:21,360 So the result would be the same, but it's a different way. 169 00:08:21,360 --> 00:08:23,190 I actually quite like this syntax, to be honest. 170 00:08:23,190 --> 00:08:24,023 It's quite clear. 171 00:08:24,023 --> 00:08:24,856 It's quite tabular. 172 00:08:24,856 --> 00:08:27,662 It gives us an idea of the purpose 173 00:08:27,662 --> 00:08:29,580 of each row in the string. 174 00:08:29,580 --> 00:08:31,080 We should actually run it as well, I guess, 175 00:08:31,080 --> 00:08:32,790 to make sure that it does actually work. 176 00:08:32,790 --> 00:08:34,653 So I'm going to run calc4. 177 00:08:37,110 --> 00:08:39,510 So I'm looking here to see if the messages 178 00:08:39,510 --> 00:08:43,563 for the tests are meaningful and if the tests actually pass. 179 00:08:44,700 --> 00:08:49,700 Okay. So yes, grab the value of the n1 property, n2, exp. 180 00:08:50,190 --> 00:08:54,120 Displayed suitable error messages and the tests are passed. 181 00:08:54,120 --> 00:08:57,000 So personally, this is the way I would prefer 182 00:08:57,000 --> 00:08:59,490 to declare a parameterized test function 183 00:08:59,490 --> 00:09:01,560 using this Tagged Template Literal Syntax, 184 00:09:01,560 --> 00:09:03,123 which looks quite cool to me.