1
00:00:00,000 --> 00:00:03,990
The Python standard library includes a unit test module that's very powerful and

2
00:00:04,000 --> 00:00:08,990
very flexible and is also very easy to use.

3
00:00:09,000 --> 00:00:11,990
Unit tests are valuable for a few reasons.

4
00:00:12,000 --> 00:00:15,990
Unit tests are automated tests that you can run on your code and you can write

5
00:00:16,000 --> 00:00:17,990
these tests once and save them and run them over and over.

6
00:00:18,000 --> 00:00:21,990
So if you have a set of code that's got a lifetime to it, that over the course

7
00:00:22,000 --> 00:00:25,990
of its lifetime it gets updated, it gets changed, having these unit tests

8
00:00:26,000 --> 00:00:30,990
already written and being able to run these unit tests on your code is going to

9
00:00:31,000 --> 00:00:32,990
have some real value for you.

10
00:00:33,000 --> 00:00:35,990
So let's look at how this is done in Python.

11
00:00:36,000 --> 00:00:39,990
I've got the saytime module here, which has been used for a number of different

12
00:00:40,000 --> 00:00:41,990
purposes in this course.

13
00:00:42,000 --> 00:00:47,990
And you'll notice at the end of it it's got a little test function.

14
00:00:48,000 --> 00:00:50,990
And when I wrote this, this just seemed like the easiest way to do it.

15
00:00:51,000 --> 00:00:54,990
And it's also, I like to be able to look at the results and say yeah, that looks right.

16
00:00:55,000 --> 00:00:56,990
That looks right. That looks right.

17
00:00:57,000 --> 00:01:01,990
If this were anymore complicated or if it was going to have much of a

18
00:01:02,000 --> 00:01:04,990
development lifecycle to it, I would use unit tests instead.

19
00:01:05,000 --> 00:01:10,990
And so we're going to go ahead and do that.

20
00:01:11,000 --> 00:01:14,990
This is a unittest script that I wrote for saytime.

21
00:01:15,000 --> 00:01:20,990
And I basically took those textual tests and I made them into unit tests.

22
00:01:21,000 --> 00:01:23,990
And this is very, very easy to do.

23
00:01:24,000 --> 00:01:26,990
All I do is I import saytime and I import the unittest.

24
00:01:27,000 --> 00:01:30,990
So this is the module that I'm working on and this is the unittest framework

25
00:01:31,000 --> 00:01:32,990
from the Python standard library.

26
00:01:33,000 --> 00:01:35,990
And then I create this class.

27
00:01:36,000 --> 00:01:39,990
And then at the end of the module here, if __name == "__main__", instead of just

28
00:01:40,000 --> 00:01:44,990
calling my own main, I call a special main that's in the unittest package.

29
00:01:45,000 --> 00:01:49,990
And in the unittest package, the special main will actually open up this file

30
00:01:50,000 --> 00:01:55,990
and parse it and find the classes that import unittest, and it will go ahead and

31
00:01:56,000 --> 00:01:58,990
run the test in that class.

32
00:01:59,000 --> 00:01:59,990
And so here is the class.

33
00:02:00,000 --> 00:02:01,990
So I can name it whatever I want.

34
00:02:02,000 --> 00:02:04,990
And it has a special method called setUp.

35
00:02:05,000 --> 00:02:07,990
In this special method setUp, I can do any initializations that I want to.

36
00:02:08,000 --> 00:02:09,990
And so here I've created this list of numbers.

37
00:02:10,000 --> 00:02:12,990
I could have just as easily put that in the test for the numbers, but I wanted

38
00:02:13,000 --> 00:02:15,990
to demonstrate the setUp here.

39
00:02:16,000 --> 00:02:21,990
And so I take a range of 11 numbers, from 0-10, and I make a list out of them,

40
00:02:22,000 --> 00:02:24,990
and I assign them to this variable here.

41
00:02:25,000 --> 00:02:26,990
And so that gets used in test_numbers.

42
00:02:27,000 --> 00:02:28,990
So here is the first method.

43
00:02:29,000 --> 00:02:31,990
These methods will get run as the tests.

44
00:02:32,000 --> 00:02:33,990
So the first method here is test_numbers.

45
00:02:34,000 --> 00:02:36,990
And I've got some words that I'm going to compare those numbers again.

46
00:02:37,000 --> 00:02:41,990
And these are the words that will be the results of my saywords numwords.

47
00:02:42,000 --> 00:02:42,990
So 'oh', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine',

48
00:02:43,000 --> 00:02:47,990
'ten', those are the results that I'm expecting.

49
00:02:48,000 --> 00:02:50,990
And so I enumerate through the self.nums.

50
00:02:51,000 --> 00:02:53,990
I get both an index and the number itself.

51
00:02:54,000 --> 00:02:58,990
And then I run this assertEqual method, which is from the unittest package, and

52
00:02:59,000 --> 00:03:01,990
it's going to compare two values.

53
00:03:02,000 --> 00:03:05,990
And if these two values are equal, then fine. It will leave it alone.

54
00:03:06,000 --> 00:03:07,990
And if they're not, then it will throw an AssertionError.

55
00:03:08,000 --> 00:03:15,990
And so here the two values are the result from my saytime.numwords and the word

56
00:03:16,000 --> 00:03:17,990
from this tuple here.

57
00:03:18,000 --> 00:03:19,990
If they equal, then fine.

58
00:03:20,000 --> 00:03:22,990
And if they're not equal, then it'll throw an AssertionError.

59
00:03:23,000 --> 00:03:26,990
And so the same thing here, test_time. I have time_tuples.

60
00:03:27,000 --> 00:03:29,990
And so this is a tuple with a bunch of tuples in it.

61
00:03:30,000 --> 00:03:31,990
And these are the times that I'm testing against.

62
00:03:32,000 --> 00:03:33,990
And these are hours and minutes.

63
00:03:34,000 --> 00:03:36,990
And then here's the list of the results that I want, "midnight", "one past

64
00:03:37,000 --> 00:03:39,990
midnight", "eleven o'clock", etcetera.

65
00:03:40,000 --> 00:03:41,990
And if they compare equal, it's the same thing.

66
00:03:42,000 --> 00:03:43,990
I enumerate through the time_tuples.

67
00:03:44,000 --> 00:03:50,990
I run them through the module that I'm testing and I compare them to this tuple

68
00:03:51,000 --> 00:03:52,990
up here of these words.

69
00:03:53,000 --> 00:03:53,990
If they're equal, fine.

70
00:03:54,000 --> 00:03:55,990
If they're not equal, it throws an AssertionError.

71
00:03:56,000 --> 00:03:58,990
So this is how this works.

72
00:03:59,000 --> 00:04:01,990
And obviously you can write your own tests.

73
00:04:02,000 --> 00:04:03,990
There are a number of different assertion tests.

74
00:04:04,000 --> 00:04:06,990
You can find those in the documentation for the unittest module.

75
00:04:07,000 --> 00:04:11,990
I strongly recommend that you read the documentation for the unittest package.

76
00:04:12,000 --> 00:04:13,990
It's got a lot of options.

77
00:04:14,000 --> 00:04:16,990
It has a lot of methods that you can use for your testing.

78
00:04:17,000 --> 00:04:19,990
There are a lot of different assertions that you can test for.

79
00:04:20,000 --> 00:04:23,990
And it even has some ways to do some more complicated tests.

80
00:04:24,000 --> 00:04:26,990
This kind of test that I've written here is the simplest case.

81
00:04:27,000 --> 00:04:31,990
And for most purposes, this is actually just fine, and it does the job and

82
00:04:32,000 --> 00:04:33,990
it does the job well.

83
00:04:34,000 --> 00:04:35,990
So let's go ahead and run it.

84
00:04:36,000 --> 00:04:38,990
When we run this, you'll notice that we get our little test.

85
00:04:39,000 --> 00:04:41,990
And we've been just selecting Python Run for all of these.

86
00:04:42,000 --> 00:04:44,990
There's a special one here in the PyDev module for Eclipse.

87
00:04:45,000 --> 00:04:46,990
It's called Python unit-test.

88
00:04:47,000 --> 00:04:49,990
And we're going to run that one. Say OK.

89
00:04:50,000 --> 00:04:51,990
And here it ran our unittest.

90
00:04:52,000 --> 00:04:54,990
We'll maximize this so we can see what it does.

91
00:04:55,000 --> 00:04:56,990
First of all, it finds files.

92
00:04:57,000 --> 00:04:59,990
And it finds the test-saytime.

93
00:05:00,000 --> 00:05:03,990
And that's our unittest module that we just wrote.

94
00:05:04,000 --> 00:05:04,990
And it imports the test module.

95
00:05:05,000 --> 00:05:07,990
So it's importing the saywords.

96
00:05:08,000 --> 00:05:10,990
And here it runs the two tests, test_numbers and test_time.

97
00:05:11,000 --> 00:05:12,990
It ran the two tests.

98
00:05:13,000 --> 00:05:14,990
It didn't throw any assertion errors.

99
00:05:15,000 --> 00:05:16,990
And there's the result that we're expecting.

100
00:05:17,000 --> 00:05:20,990
If it had not gotten the result that it wanted, let's just go ahead and misspell

101
00:05:21,000 --> 00:05:21,990
one of these words here.

102
00:05:22,000 --> 00:05:23,990
I'll just throw an extra o in there.

103
00:05:24,000 --> 00:05:25,990
We'll save that and we'll run it.

104
00:05:26,000 --> 00:05:27,990
And now we got one failure.

105
00:05:28,000 --> 00:05:33,990
You see it got an AssertionError that oh did not equal to ooh.

106
00:05:34,000 --> 00:05:37,990
So it gives us enough information here that we can actually go through the code

107
00:05:38,000 --> 00:05:40,990
and we can say, oh, well, I've got a typo in my assertion test or there's an

108
00:05:41,000 --> 00:05:44,990
actual problem in my module that I need to go and fix.

109
00:05:45,000 --> 00:05:48,990
So the beauty of this is, is that as your code goes through its development

110
00:05:49,000 --> 00:05:50,990
lifecycle, you make one release.

111
00:05:51,000 --> 00:05:51,990
You make another release.

112
00:05:52,000 --> 00:05:53,990
You make another release. You add features.

113
00:05:54,000 --> 00:05:54,990
You take features away.

114
00:05:55,000 --> 00:05:56,990
You change features.

115
00:05:57,000 --> 00:05:58,990
Your unit-tests are already written.

116
00:05:59,000 --> 00:06:00,990
And so you can accumulate more.

117
00:06:01,000 --> 00:06:01,990
You can change them.

118
00:06:02,000 --> 00:06:06,990
And this is going to help you to keep the quality of your code high throughout

119
00:06:07,000 --> 00:06:08,990
its development lifecycle.

120
00:06:09,000 --> 00:06:10,990
So unit-tests are very useful.

121
00:06:11,000 --> 00:06:15,990
The unit-test package that comes in the standard Python library is very complete

122
00:06:16,000 --> 00:06:17,990
and very well written and very reliable.

123
00:06:18,000 --> 00:06:20,990
If you're going to be releasing your code using Python, you must

124
00:06:21,000 --> 00:06:22,990
submit unit-tests with it.

125
00:06:23,000 --> 00:06:26,990
And of course the unit-tests are going to be of value to you in any code that

126
00:06:27,000 --> 00:06:37,000
has a lengthy product lifecycle.

