1
00:00:00,990 --> 00:00:06,510
OK, one more thing I want to turn our attention to, and it is a very important component and one that

2
00:00:06,510 --> 00:00:12,900
gets ignored far too often by developers, especially new developers, and that is testing when we write

3
00:00:12,900 --> 00:00:17,710
code, we want to write tests to ensure that our code actually does what it's supposed to do.

4
00:00:18,120 --> 00:00:20,660
Fortunately, go makes this remarkably easy.

5
00:00:21,240 --> 00:00:23,070
So, first of all, we need something to test.

6
00:00:24,000 --> 00:00:30,300
So what I'm going to do, I have a new project here with one file named Echo, and inside of that I

7
00:00:30,300 --> 00:00:31,920
have an empty main function.

8
00:00:31,920 --> 00:00:34,280
And as you have to have, I'm going to create a new function.

9
00:00:34,560 --> 00:00:41,310
I'm going to call this function divide and it's going to take two parameters, X and Y, not very original

10
00:00:41,310 --> 00:00:46,440
variable names, but they'll do the trick and they're going to be off type float 32 and it's going to

11
00:00:46,440 --> 00:00:48,420
return one of two things.

12
00:00:48,420 --> 00:00:49,920
Well, Ash is going to return to things.

13
00:00:50,040 --> 00:00:56,850
It's going to return a float 32, which will be the result of our division and an error which will have

14
00:00:56,850 --> 00:01:00,440
an error if there is an error or it will be nil if there is no error.

15
00:01:00,990 --> 00:01:03,990
So it takes two parameters and it returns to things.

16
00:01:04,560 --> 00:01:08,090
Now, the very first thing we need, of course, is a place to store a result.

17
00:01:08,100 --> 00:01:15,570
So I'll find a new variable var and I'll just call a result and it's a type float 32 and then we can

18
00:01:15,570 --> 00:01:16,260
do our division.

19
00:01:16,290 --> 00:01:24,240
Our division is result equals X divided by Y and then I need to return our result and an error if we

20
00:01:24,240 --> 00:01:24,720
have one.

21
00:01:24,900 --> 00:01:31,870
Now sadly this will never throw an error that I can catch, so I need to check for something.

22
00:01:31,890 --> 00:01:33,750
Now what situations are there.

23
00:01:34,440 --> 00:01:39,440
We're dividing one float by another or one number by another will result in an error.

24
00:01:39,960 --> 00:01:44,670
And if you took math at all at any point in the past, you'll know that division by zero is generally

25
00:01:44,670 --> 00:01:45,480
frowned upon.

26
00:01:46,410 --> 00:01:49,460
You can't divide something by zero or you get an undefined result.

27
00:01:49,470 --> 00:01:50,250
So that's our error.

28
00:01:50,490 --> 00:01:56,940
So I can just check to say if y which is what I'm dividing by right here, if that's equal to zero,

29
00:01:57,090 --> 00:01:58,360
then return an error.

30
00:01:58,380 --> 00:02:00,180
So I will return and I'll return.

31
00:02:00,190 --> 00:02:01,840
I have to return to things.

32
00:02:01,870 --> 00:02:06,930
I'll return result which is set to zero right now because I've just initialize that, not done anything

33
00:02:06,930 --> 00:02:09,870
with it and then I'll just generate my own error.

34
00:02:10,140 --> 00:02:15,960
And it's as simple as this errors knew and then I will put in my error.

35
00:02:15,960 --> 00:02:19,050
Message cannot divide by zero.

36
00:02:19,410 --> 00:02:19,780
That's it.

37
00:02:20,490 --> 00:02:23,820
So now I can return nil down here because there is no air.

38
00:02:24,150 --> 00:02:25,050
So let's go through this.

39
00:02:25,050 --> 00:02:26,490
Here's a function called divide.

40
00:02:26,970 --> 00:02:30,270
I initialize a variable type happens to be float 32.

41
00:02:30,570 --> 00:02:36,030
I checked to make sure what I'm dividing by our deviser y is not zero.

42
00:02:36,030 --> 00:02:41,100
If it is equal to zero, return the result, which is zero because I haven't done anything with it and

43
00:02:41,100 --> 00:02:42,780
an error that I've created myself.

44
00:02:43,170 --> 00:02:48,870
Otherwise, if Y is not equal to zero to the division, return the result and return nil for an error

45
00:02:49,050 --> 00:02:50,310
and appear in the main function.

46
00:02:50,670 --> 00:02:57,480
All I have to do is call it so I'll say result and error, which is an error there.

47
00:02:57,480 --> 00:03:04,950
Assign the value of divide and I'll just do one hundred divided by ten and they'll check for my error.

48
00:03:05,340 --> 00:03:08,580
If error is not equal to nil, what should I do.

49
00:03:09,180 --> 00:03:13,020
I should just say, well, log print line error and return.

50
00:03:13,170 --> 00:03:13,980
Don't do anything else.

51
00:03:14,010 --> 00:03:14,970
Stop at that point.

52
00:03:15,150 --> 00:03:17,040
Otherwise, what am I going to do.

53
00:03:17,190 --> 00:03:22,800
Log print line result of division is and then my result.

54
00:03:23,730 --> 00:03:24,090
All right.

55
00:03:24,090 --> 00:03:25,320
So I can run this program.

56
00:03:25,770 --> 00:03:27,270
Go run.

57
00:03:27,420 --> 00:03:29,400
May not go and it should work.

58
00:03:31,410 --> 00:03:32,650
Result of division is 10.

59
00:03:32,730 --> 00:03:33,270
Perfect.

60
00:03:33,490 --> 00:03:39,810
OK, now what if I try to divide by zero, just changes to zero, clear the screen.

61
00:03:42,100 --> 00:03:44,780
And run it again cannot divide by zero.

62
00:03:44,800 --> 00:03:52,720
That works great, but the entire purpose of this exercise is not to learn how to divide because you

63
00:03:52,720 --> 00:03:53,880
probably already know how to do that.

64
00:03:53,980 --> 00:03:55,100
It's to write tests.

65
00:03:55,120 --> 00:03:59,110
So here's how you write tests and go in go the tests.

66
00:03:59,350 --> 00:04:03,130
The tests themselves live right beside the coalition trying to test.

67
00:04:03,310 --> 00:04:05,100
So I have one file, mango.

68
00:04:05,440 --> 00:04:11,190
I'll now create another file and it has to have a specific kind of name and fortunately is pretty easy.

69
00:04:11,800 --> 00:04:21,430
So when I create my file, I will call it new go file, main underscore test or go, which means these

70
00:04:21,430 --> 00:04:23,540
are the tests for mango.

71
00:04:24,040 --> 00:04:26,510
So it has to end with underscore test go.

72
00:04:28,240 --> 00:04:29,810
So how do we write tests?

73
00:04:29,830 --> 00:04:35,410
Well, I'm going to show you two ways, one way, which is kind of manual and slow and one another way

74
00:04:35,440 --> 00:04:36,550
which is way more efficient.

75
00:04:36,640 --> 00:04:41,680
But we'll do the easy ones first, the manual ones to write, to write a test and go.

76
00:04:41,680 --> 00:04:42,400
It's just a function.

77
00:04:42,640 --> 00:04:45,910
And you have to give the function a name and it has to start with the word test.

78
00:04:45,910 --> 00:04:47,680
Otherwise it's going to get ignored.

79
00:04:47,680 --> 00:04:51,360
And I'm going to test divide because I have a function called write.

80
00:04:51,400 --> 00:04:52,450
So I'm going to do that.

81
00:04:52,900 --> 00:04:58,930
And it takes this for argument's T is the conventional name that you're going to use for this variable.

82
00:04:59,260 --> 00:05:03,040
And it's a pointer to testing Dorte, which is a built in package.

83
00:05:03,430 --> 00:05:05,310
So you see that an important testing for me.

84
00:05:05,680 --> 00:05:10,480
Now, I write my tests and all I do is I need to get the result in this case.

85
00:05:10,480 --> 00:05:13,240
I don't care what the result is, I'm going to call that function.

86
00:05:13,930 --> 00:05:20,500
I'm going to check for an error and I'll divide, oh, let's say ten point zero and one point zero.

87
00:05:21,070 --> 00:05:25,540
OK, if error is not equal to nil, then what do I do?

88
00:05:25,930 --> 00:05:28,450
I throw an error, but I don't throw a standard error.

89
00:05:28,450 --> 00:05:29,500
I throw a testing error.

90
00:05:29,650 --> 00:05:31,510
T dot error.

91
00:05:32,230 --> 00:05:36,430
Got an error when we should not have.

92
00:05:38,260 --> 00:05:42,040
So I'm checking for air, but I'm not checking for errors in my programming code.

93
00:05:42,280 --> 00:05:45,330
I'm checking to see whether an error is actually thrown.

94
00:05:45,340 --> 00:05:51,900
So in this case, when I divide ten by one, that's absolutely valid and I should not get an error.

95
00:05:52,090 --> 00:05:57,190
So all I'm running here is a test to say if I divide ten by one, I should not get an error.

96
00:05:57,200 --> 00:05:59,470
If I do, then fail this test.

97
00:05:59,500 --> 00:06:00,280
So let's run this.

98
00:06:00,280 --> 00:06:02,740
And here's how you run tests and go go test.

99
00:06:03,610 --> 00:06:05,470
That's pretty easy and pass.

100
00:06:05,470 --> 00:06:08,260
OK, and I can actually do a little bit more detail.

101
00:06:08,260 --> 00:06:16,030
Go test Dash V for verbose and it says I'm running testified, I pass testified and it told me how long

102
00:06:16,030 --> 00:06:18,190
it took to run all the questions around all the tests.

103
00:06:18,730 --> 00:06:20,070
Now that's one test.

104
00:06:20,080 --> 00:06:26,140
Let's try copying this and I'm going to copy and paste it and give it a new name test, bad divide,

105
00:06:26,140 --> 00:06:30,040
I'll call it this time, meaning I'm testing for bad division.

106
00:06:30,040 --> 00:06:34,270
And this time I'm going to say divide ten by zero.

107
00:06:34,990 --> 00:06:38,950
In this case, what should happen if error is equal to nil?

108
00:06:38,980 --> 00:06:48,270
If it doesn't throw an error we say did not get an error when we should have and again, think it through.

109
00:06:48,790 --> 00:06:55,330
If I divide ten by zero, it should generate that error that we wrote in our function and return zero

110
00:06:55,330 --> 00:06:56,020
and an error.

111
00:06:56,410 --> 00:06:58,390
So error should not be equal to nil.

112
00:06:58,600 --> 00:07:06,190
If error is equal to nil, then I failed the test so we can now run the test again, go test and again

113
00:07:06,190 --> 00:07:07,600
it should pass and they both pass.

114
00:07:08,020 --> 00:07:14,350
Now, the problem here, of course, is what if I really want to test my division function thoroughly?

115
00:07:14,770 --> 00:07:19,720
I'm going to wind up writing one function for every one of these tests, and that's really, really

116
00:07:19,720 --> 00:07:20,410
inefficient.

117
00:07:20,770 --> 00:07:26,830
So instead, let's run what's called a table test and we'll do this, first of all, by showing what

118
00:07:26,830 --> 00:07:28,660
kind of data I want to test.

119
00:07:28,660 --> 00:07:33,880
So right at the top of my program, right after my input statement, I'm going to write a variable tests

120
00:07:34,210 --> 00:07:39,430
and it's going to be equal to a slice of stroke's slice of strokes.

121
00:07:40,210 --> 00:07:42,700
And inside of that, I have to define the struct.

122
00:07:42,970 --> 00:07:46,120
So first of all, I want to give my testimony, which is just a string.

123
00:07:47,050 --> 00:07:52,040
Then I'm going to give my name, my dividend, my first number that I'm passing, which is a thirty

124
00:07:52,090 --> 00:07:53,890
two dividend.

125
00:07:53,890 --> 00:08:01,510
I better still write and then the deviser, but I'm dividing by which is again a float thirty two.

126
00:08:02,620 --> 00:08:03,520
Is that enough.

127
00:08:03,530 --> 00:08:04,540
No it's not.

128
00:08:04,540 --> 00:08:09,280
I want to also include what do I expect to get from the results of this division.

129
00:08:09,280 --> 00:08:11,980
So I'll call it expected and it's a float.

130
00:08:11,980 --> 00:08:16,300
Thirty two and finally I'm going to put in one more variable.

131
00:08:16,300 --> 00:08:18,340
Is an error expected.

132
00:08:18,340 --> 00:08:21,160
So is error which is a boolean true or false.

133
00:08:21,310 --> 00:08:24,600
OK then that defines my struct.

134
00:08:24,610 --> 00:08:30,310
Now it's populated with some test data and what we're going to have is every entry in this slice will

135
00:08:30,310 --> 00:08:32,140
be a test that I run once.

136
00:08:32,500 --> 00:08:37,900
So first of all, I'm going to call my test is valid data and that name can be whatever you want.

137
00:08:37,900 --> 00:08:39,700
But my test is testing with valid data.

138
00:08:39,940 --> 00:08:45,790
I'll pass in one hundred point zero as my first number, ten point zero is my second number and ten

139
00:08:45,790 --> 00:08:47,470
point zero is the expected result.

140
00:08:47,680 --> 00:08:50,890
And this should not throw an error.

141
00:08:51,190 --> 00:08:54,280
So each of these values corresponds to each of these in order.

142
00:08:54,520 --> 00:08:57,820
So I'm having a test named for all the data I want to divide.

143
00:08:57,820 --> 00:08:58,840
One hundred by ten.

144
00:08:58,840 --> 00:09:01,720
I expect to get ten as a result and I expect no error.

145
00:09:02,050 --> 00:09:09,220
Now let's duplicate that line and call it invalid data hundred divided by zero and I can put zero point

146
00:09:09,220 --> 00:09:13,330
zero because it's a float and the result I'm expecting is zero.

147
00:09:15,110 --> 00:09:19,320
And am I expecting an error?

148
00:09:19,340 --> 00:09:23,330
Yes, if I try to divide by zero, then I should get an error.

149
00:09:23,630 --> 00:09:25,220
OK, let's just go with those two for now.

150
00:09:25,340 --> 00:09:28,550
These two effectively duplicate the two tests I've written already.

151
00:09:29,060 --> 00:09:29,960
I'll leave those there.

152
00:09:30,440 --> 00:09:33,170
But now I want to write a new function func.

153
00:09:33,170 --> 00:09:39,710
I'll call it test division and there's no tie and function test division.

154
00:09:40,940 --> 00:09:45,860
And it is again a Ts type testing T.

155
00:09:48,360 --> 00:09:50,820
And I put its parentheses there as curly brackets.

156
00:09:51,420 --> 00:09:55,490
Now I'm going to range over my test variable so we can know how to do that.

157
00:09:55,500 --> 00:09:57,830
We've already done that for I ignore the first one.

158
00:09:57,840 --> 00:10:03,360
I don't care what the index is for each test and I'll call it teet, which is pretty common when you're

159
00:10:03,360 --> 00:10:06,900
changing over tests equals range tests.

160
00:10:08,070 --> 00:10:10,530
And what do I want to do inside of that test?

161
00:10:10,560 --> 00:10:13,100
Well, first of all, let's just call that function.

162
00:10:13,110 --> 00:10:17,330
Got what am I getting from the function error?

163
00:10:18,240 --> 00:10:22,410
If there's an error, populate that variable, otherwise leave it is nil and call the function divide.

164
00:10:23,610 --> 00:10:27,870
And I'm going to call it the passing the two arguments right from this slice.

165
00:10:27,990 --> 00:10:38,760
So I address those by going to dot dividend t t dot divisor and then I actually run my checks.

166
00:10:38,910 --> 00:10:41,070
So first of all, what am I checking for.

167
00:10:41,490 --> 00:10:44,010
Well let's check, first of all to see if it should have an error.

168
00:10:44,040 --> 00:10:45,920
If T t is error.

169
00:10:46,080 --> 00:10:50,910
In other words, if this test is supposed to throw an error, then check to see if the error is now

170
00:10:50,910 --> 00:10:53,070
because of the error is no, I failed the test.

171
00:10:53,370 --> 00:10:56,940
If error is equal to nil, then fail the tests.

172
00:10:56,940 --> 00:11:05,360
I can put T to error expected and error, but did not get one.

173
00:11:06,390 --> 00:11:07,440
So that's the first check.

174
00:11:09,780 --> 00:11:14,970
So a second case would be if the error is not equal, if there is equal to.

175
00:11:15,510 --> 00:11:17,660
So that would be an opt out.

176
00:11:19,260 --> 00:11:27,060
And now I can check to see if error is not equal to nil, then I throw another Teda error.

177
00:11:28,470 --> 00:11:36,150
And this one is did not expect an error, but got one.

178
00:11:38,690 --> 00:11:44,390
And then to confront the threat, which is er error, I could just put air there, but you can also

179
00:11:44,390 --> 00:11:46,660
call the method on that which will give it as a strength.

180
00:11:47,640 --> 00:11:49,080
OK, so that's our first case.

181
00:11:49,520 --> 00:11:53,810
And then finally, we need to check to see did we get what we expected to get.

182
00:11:53,960 --> 00:12:01,730
If God is not equal to TTD expected, then throw another Teege error.

183
00:12:01,940 --> 00:12:06,410
And this time I'll use Şeref because I'm going to put some placeholders in there.

184
00:12:06,890 --> 00:12:12,650
Expected percent F, but got percent F.

185
00:12:14,280 --> 00:12:20,850
And then I just populate those placeholders with expected and got so I expected to the expected and

186
00:12:20,850 --> 00:12:22,830
got there.

187
00:12:23,400 --> 00:12:25,480
All right, let's run this test and see what happens.

188
00:12:26,070 --> 00:12:27,180
Go test.

189
00:12:29,220 --> 00:12:38,490
And they all passed, and if I do go test you go test Daschle, you see, that is actually running those

190
00:12:38,490 --> 00:12:45,660
test runs test division twice because I have two values up here and then it runs the two manual ones.

191
00:12:45,690 --> 00:12:49,700
But I don't really need those anymore so I can get rid of them because I'm already testing them.

192
00:12:49,710 --> 00:12:55,320
And the great thing about this is if I want to run more tests on that, I just duplicate this and put

193
00:12:55,320 --> 00:12:56,280
some more values in here.

194
00:12:56,280 --> 00:13:02,370
So I'll put one where I expect certain results expected or expect five.

195
00:13:02,580 --> 00:13:03,520
How do I get five?

196
00:13:03,540 --> 00:13:09,780
Well, fifty divided by ten should give me five and now I can run those tests.

197
00:13:10,890 --> 00:13:11,670
And it works great.

198
00:13:11,700 --> 00:13:16,600
OK, let's take it here, expected an error, but did not get one fail test division, so.

199
00:13:16,650 --> 00:13:19,800
Oh yeah, down here I expect no air false.

200
00:13:20,360 --> 00:13:21,330
See, that's how they work.

201
00:13:22,870 --> 00:13:29,590
So clear the screen, run this again and away it goes, if I want to put another one in there, say

202
00:13:29,920 --> 00:13:34,630
expect fractioned so we're not going to do a whole division this time.

203
00:13:34,630 --> 00:13:39,790
So we'll do minus one divided by minus 777.

204
00:13:40,100 --> 00:13:41,290
And what does that give us?

205
00:13:41,320 --> 00:13:42,940
Well, I already did this on a calculator.

206
00:13:42,940 --> 00:13:47,230
It gives a zero point zero zero one two eight seven zero zero one three.

207
00:13:47,620 --> 00:13:49,750
And if I typed that right, this test should pass.

208
00:13:52,020 --> 00:13:56,640
And it passed, and that's all there is to testing now, one more thing about this, we can actually

209
00:13:56,640 --> 00:14:04,240
check our test coverage by going go test cover and it will tell me that I actually have in my testing

210
00:14:04,240 --> 00:14:10,590
course here, I have 50 percent of the statements are covered and we can even get better than that.

211
00:14:11,310 --> 00:14:17,810
And we can do so by running this command, which I'm going to paste in go test dashkova profile equals

212
00:14:17,820 --> 00:14:21,480
coverage out, which will spitfire's up here called coverage out.

213
00:14:21,840 --> 00:14:26,670
And then if that is successful, run, go to cover HTML equals coverage.

214
00:14:26,880 --> 00:14:27,660
And if I run that.

215
00:14:29,670 --> 00:14:35,970
It actually fires up my Web browser for me and shows me what's covered in green and what's not covered

216
00:14:35,970 --> 00:14:36,550
in red.

217
00:14:37,230 --> 00:14:40,770
Now, realistically speaking, a 50 percent test coverage is not great.

218
00:14:41,070 --> 00:14:47,490
But the reality is we're going to, throughout the course of this course, make our main functions as

219
00:14:47,490 --> 00:14:50,700
dumb as we possibly can and not bother testing them.

220
00:14:50,700 --> 00:14:55,890
So we're going to do as little in here as we possibly can instead of doing a lot within our main function.

221
00:14:55,890 --> 00:15:02,580
As time goes on, we'll begin to pass all of our actions off to functions and we'll test those functions.

222
00:15:02,580 --> 00:15:04,430
And we just won't bother to test our main function.

223
00:15:04,440 --> 00:15:09,270
And we'll get pretty, pretty good course test coverage as we go through this course.

224
00:15:09,420 --> 00:15:09,750
All right.

225
00:15:09,750 --> 00:15:10,560
That's it for testing.

226
00:15:10,560 --> 00:15:15,120
We'll see lots more of examples of this as we begin writing more sophisticated code.
