1 00:00:00,630 --> 00:00:03,750 If you've been writing Python for a while, you've probably gotten pretty used to 2 00:00:03,750 --> 00:00:06,470 using in key word the for checking membership. 3 00:00:06,470 --> 00:00:09,630 You want to know if a certain value is in a list or dictionary. 4 00:00:09,630 --> 00:00:12,910 Lots of time we want to know if this is true when we're writing tests too. 5 00:00:12,910 --> 00:00:17,230 So unit test gives us assert in and assert not in. 6 00:00:17,230 --> 00:00:20,700 There are a couple of other handy lists, [UNKNOWN] and dictionary assertions, too. 7 00:00:20,700 --> 00:00:21,430 Let's take a look at them. 8 00:00:22,590 --> 00:00:26,800 For our next set of tests, we're going to use a couple of new classes that I wrote 9 00:00:26,800 --> 00:00:31,840 they're here in this dice dot pie file inside the dice directory. 10 00:00:31,840 --> 00:00:36,660 And, so these represent a die roller, like you might use for a table top game or 11 00:00:36,660 --> 00:00:38,170 a role playing game. 12 00:00:38,170 --> 00:00:40,910 You can make a roll, where is that class? 13 00:00:40,910 --> 00:00:41,530 There's the class. 14 00:00:41,530 --> 00:00:47,120 You can make a roll of dice with a string like one d six or 15 00:00:47,120 --> 00:00:50,750 two d six or five d eight, whatever. 16 00:00:50,750 --> 00:00:54,120 And it'll create how many dice with however many sides and 17 00:00:54,120 --> 00:00:56,070 it rolls them to get a number. 18 00:00:56,070 --> 00:00:59,230 So, I'm going to test a few things in this module. 19 00:00:59,230 --> 00:01:04,710 The first thing I want to test is whether or not a die up here is created correctly. 20 00:01:04,710 --> 00:01:13,176 So, let's set up a new file here that we're gonna call test.py. 21 00:01:13,176 --> 00:01:20,060 And we need to to import unittest and we need to import dice so 22 00:01:20,060 --> 00:01:24,590 we have everything set up, and lets do a class DieTests. 23 00:01:24,590 --> 00:01:32,300 Unittest.TestCase, and we're gonna use the setup method. 24 00:01:33,620 --> 00:01:40,370 So def setUp, and I'm gonna create just a couple of dice directly. 25 00:01:40,370 --> 00:01:45,750 I'm gonna make a d6, which is dice.Die with six sides. 26 00:01:45,750 --> 00:01:49,740 And I'm gonna make a d8, which is dice.Die with eight sides. 27 00:01:52,810 --> 00:01:57,180 Okay. So now, let's test the creation of a die. 28 00:02:00,380 --> 00:02:03,000 So they've been created and 29 00:02:03,000 --> 00:02:09,030 I should now be able to do self.assertEqual(self.d6.sides, 6). 30 00:02:09,030 --> 00:02:12,760 The number six should have six sides. 31 00:02:13,785 --> 00:02:19,724 And I just do self.assertIn(self.d6.value, 32 00:02:19,724 --> 00:02:24,695 range(1, 7) because remember with range, we have to specify a higher end 33 00:02:24,695 --> 00:02:27,865 that's one higher than the number we actually want as the highest end. 34 00:02:29,470 --> 00:02:31,130 So I've got everything in here. 35 00:02:31,130 --> 00:02:32,800 Now, it should be impossible for 36 00:02:32,800 --> 00:02:37,090 this test to fail because these, this is exactly how we're creating the dice. 37 00:02:37,090 --> 00:02:38,370 It should just work. 38 00:02:38,370 --> 00:02:42,510 But it's always good to have tests like this so that if your die creation, 39 00:02:42,510 --> 00:02:45,560 your whatever your object is, the creation changes. 40 00:02:45,560 --> 00:02:47,120 Your tests will warn you about it. 41 00:02:47,120 --> 00:02:49,010 And then you can either fix your tests or 42 00:02:49,010 --> 00:02:52,280 you can fix your code, whichever one is now out of date. 43 00:02:52,280 --> 00:02:53,120 Okay. 44 00:02:53,120 --> 00:02:55,730 So I'm not gonna bother with the if name main thing. 45 00:02:55,730 --> 00:02:57,970 I'm just gonna run the tests. 46 00:02:57,970 --> 00:03:00,050 So python -m unittest. 47 00:03:02,490 --> 00:03:03,730 Ope. 48 00:03:03,730 --> 00:03:04,800 I need to get into that directory. 49 00:03:06,520 --> 00:03:07,460 Dice. There we go. 50 00:03:07,460 --> 00:03:11,610 Python -m unittest tests.py. 51 00:03:13,600 --> 00:03:14,720 Ran one test, test was fine. 52 00:03:14,720 --> 00:03:15,220 All right. 53 00:03:16,490 --> 00:03:20,520 I also want to test that I can add multiple dice together. 54 00:03:21,530 --> 00:03:23,500 So, let's write a quick little test for that. 55 00:03:25,200 --> 00:03:29,063 So, def test_add(self) : 56 00:03:29,063 --> 00:03:36,944 self.assertIsInstance(self.d6+self.d8, int). 57 00:03:36,944 --> 00:03:41,880 So what does IsInstance does? 58 00:03:41,880 --> 00:03:46,500 So, IsInstance is like the IsInstance function, in, 59 00:03:46,500 --> 00:03:51,530 the shell, which says tell me if this variable is an instance of this class. 60 00:03:51,530 --> 00:03:55,600 Well, assertIsInstance works the same way, but it's an assertion. 61 00:03:55,600 --> 00:04:00,750 So run this insertion, make sure that the first item, this one right here, 62 00:04:02,210 --> 00:04:07,570 is a member of this class an int or an instance of this class and end. 63 00:04:07,570 --> 00:04:11,340 And then we're good, it comes back as either true or false. 64 00:04:11,340 --> 00:04:12,050 Okay? 65 00:04:12,050 --> 00:04:16,040 So let's also before we go any further in this. 66 00:04:18,500 --> 00:04:21,845 Let's write some tests for the roll class. 67 00:04:21,845 --> 00:04:28,626 So, RollTests(unittest.TestCase) 68 00:04:28,626 --> 00:04:30,915 : I want to make a couple other things here as well. 69 00:04:32,985 --> 00:04:35,135 So that they are always around. 70 00:04:35,135 --> 00:04:39,775 So self.hand1 = dice.Roll('1d2') because 71 00:04:39,775 --> 00:04:44,215 the smallest die we can have is a two-sided die. 72 00:04:44,215 --> 00:04:52,134 And self.hand3 = dice.Roll('3D6') okay. 73 00:04:52,134 --> 00:04:54,095 So hand one, cause there's one die in it. 74 00:04:54,095 --> 00:04:55,870 Hand three, cause there's three dice in it. 75 00:04:57,100 --> 00:04:59,500 And I want to be able to test the upper and 76 00:04:59,500 --> 00:05:05,200 lower boundaries of these total rolls, right? 77 00:05:05,200 --> 00:05:08,870 So these are gonna be a lot like the ones we did on the rock paper scissors game. 78 00:05:08,870 --> 00:05:12,880 But instead of the greater and less, we're gonna use assert greater equal or 79 00:05:12,880 --> 00:05:17,710 assert less equal so that we don't have to add on that extra number. 80 00:05:17,710 --> 00:05:22,492 So anyway, let's do test_lower(self) : and we're going to do 81 00:05:22,492 --> 00:05:31,180 self.assertGreaterEqual(int(self.hand3), 3). 82 00:05:31,180 --> 00:05:32,360 Cuz we have three dice. 83 00:05:32,360 --> 00:05:34,320 The lowest number on each of them is one. 84 00:05:34,320 --> 00:05:38,350 So the lowest that those three dice can add up to is three. 85 00:05:39,800 --> 00:05:45,211 And then let's also do [SOUND] test_upper(self) 86 00:05:45,211 --> 00:05:51,004 : self.assertLessEqual(int(self.hand3), 87 00:05:51,004 --> 00:05:55,281 18) because three six highest dice, 88 00:05:55,281 --> 00:05:59,430 six is the highest number for each one, 89 00:05:59,430 --> 00:06:06,381 six plus six plus six is 18, or less if they're not there. 90 00:06:06,381 --> 00:06:09,540 So we can do this int call. 91 00:06:09,540 --> 00:06:12,720 Because we defined the dunder nth method in our class. 92 00:06:13,740 --> 00:06:17,370 This is great because if we ever change our class to where we can't make an nth of 93 00:06:17,370 --> 00:06:20,150 it, then this is gonna immediately blow up. 94 00:06:20,150 --> 00:06:22,260 And we're gonna go, oh, this doesn't work right. 95 00:06:23,470 --> 00:06:28,490 Now our class also has a dunder contains method. 96 00:06:28,490 --> 00:06:32,460 And our die class has a dunder EQ method that's defined. 97 00:06:32,460 --> 00:06:40,600 So we can write a test to make sure that as given die is inside of a given hand. 98 00:06:40,600 --> 00:06:42,090 So let's test that out too. 99 00:06:43,950 --> 00:06:49,780 So let's do test_membership(self) : and we need to make a couple of things here. 100 00:06:49,780 --> 00:06:56,000 So let's do our test_die = dice.Die(2) two sides. 101 00:06:56,000 --> 00:07:04,136 And test_die.value = self.hand1.results(0).value so 102 00:07:04,136 --> 00:07:07,770 we're making a fake die. 103 00:07:07,770 --> 00:07:11,360 We're giving it the same number as whatever's in hand one. 104 00:07:11,360 --> 00:07:15,725 And then we're gonna do self.assertIn(test_die, 105 00:07:15,725 --> 00:07:21,540 self.hand1.results) So, we're just making sure that 106 00:07:21,540 --> 00:07:27,300 a die with the value of the first or only die in hand1 is in hand1. 107 00:07:27,300 --> 00:07:30,090 We're cheating a little bit, but it's okay. 108 00:07:31,360 --> 00:07:32,820 There are some ways around this. 109 00:07:32,820 --> 00:07:34,310 We could do mocking and stuff like that. 110 00:07:34,310 --> 00:07:36,790 But that's not important at this point. 111 00:07:36,790 --> 00:07:38,250 Okay, let's run these tests. 112 00:07:39,460 --> 00:07:44,780 So we come back down here and we run our tests again. 113 00:07:44,780 --> 00:07:47,140 All five tests pass, everything's good. 114 00:07:47,140 --> 00:07:48,770 So this is actually really good. 115 00:07:48,770 --> 00:07:52,420 It covers most of the functionality in our two classes that we'd want to test. 116 00:07:53,430 --> 00:07:56,760 We do have a couple of try accept blocks we want to test, but 117 00:07:56,760 --> 00:07:59,000 we'll cover those in the next video. 118 00:07:59,000 --> 00:08:01,180 I love working with simple assertions like this. 119 00:08:01,180 --> 00:08:04,410 They give me a lot more confidence about what's going on in my code, because I can 120 00:08:04,410 --> 00:08:07,970 make sure that my collection objects are holding exactly what I expect them to.