#100DaysOfCode in Python Transcripts
Chapter: Days 10-12: Testing your code with pytest
Lecture: Mocking randomness / pytest-cov
0:00 Alright. Back to our guessing game.
0:02 So, how do we want to test this program?
0:04 Ideally, you want to test one function or functionality
0:08 in one pytest function.
0:11 So let's start with the Get Random Number.
0:14 I'm going to open a file test on the scoreguess.py.
0:20 Again, using pytest I have the convenience to not
0:23 having to import any module to run the test.
0:26 What I do need is to import the actual program.
0:29 So from guess import get random number and the game class.
0:35 Now, one thing I want to show you in this video is how to
0:38 mock an object. Because Get Random Number, as you can see
0:42 at the right, uses a random integer from start to end.
0:45 And random returns to something randomly every time.
0:49 So how do you actually test that? And the way to do that
0:52 in testing land is to mock an object.
0:54 And for this I'm just going to use the unittest
0:57 patch method on the mock module
1:00 because it's a perfect fit for this scenario.
1:05 So from unittest.mock, import patch.
1:10 I actually need to import to random module
1:12 because that's the one we're going to mock.
1:15 And you can use it as patch object
1:20 and that's to random module. Just specify the function
1:24 or method you want to patch.
1:29 And then in your test function
1:35 you can pass in an argument and you can give that argument
1:38 a fixed return value. And that's key because
1:42 instead of having random return something else every time
1:46 you can give it a fixed value.
1:49 So it's kind of an override of what randint() normally does
1:53 which is randomness. Now we're saying every time
1:56 random gets called it gives us 17,
2:00 and it makes that at least we can call our function,
2:02 which is get random number, and we know that it returns 17.
2:08 Yeah, and this is pretty basic, but it should show you
2:11 how you can override certain things in your program you
2:14 cannot really control and I have another example later
2:17 about the input function where we ask for user input,
2:21 which is another area that can be anything,
2:24 so you want to mock that out.
2:27 So with this code written,
2:28 let's go back to the command line and run this test.
2:31 And I'm using Control Z on a Mac with foreground to
2:35 toggle back and forth between
2:37 my file editor and the terminal.
2:40 And here I can just run pytest, and that's funny
2:44 because the previous example I put in a hello subdirectory
2:47 and it's actually cool that we see this because
2:49 pytest is smart enough to look recursively for test files.
2:54 So in this case it found two and ran them both.
2:57 So I'm going to move this out to somewhere else,
3:02 because we now want to focus on the guessing game.
3:05 And yeah it runs fine, and what I also want to see
3:08 from now on is how much coverage we have of our tests.
3:13 So we installed
3:16 pytest-cov and to use it was a bit of a
3:21 trial-and-error for me, but I found this syntax
3:24 to work well for me. So I want a coverage report
3:27 term missing coverage dot current directory.
3:31 And the term missing is cool because
3:33 it starts to index all the--
3:35 okay, I actually have to give it something more specific
3:39 because it starts to look in my virtual environment.
3:41 Alright, what I did was in the end moving the files into a
3:45 subdirectory so we got our venv
3:47 and we got our guess new subdirectory with the
3:50 script and the test file in there.
3:53 And when I specify a subdirectory in the minus minus scuff
3:57 argument then it just rounds on our code,
4:00 and what's cool about the missing argument is that
4:02 it shows the lines in the code that are not having
4:05 test yet, which is of course is a lot
4:07 because we just got started.
4:09 But even so, we have 24 percent coverage so
4:11 we are up for a good start. And you can then
4:14 map those lines back to the actual program so
4:18 this is not tested 29.
4:22 This is not tested, et cetera.
4:25 One final thing, as I use Vim I'm going to use the
4:27 coverage command quite a lot so
4:29 in my Vim RC, which I mapped to VRC to edit it,
4:35 I have a comma T which maps to save the file or
4:39 run a command with the exclamation mark
4:41 and then I run this command and I'm going to--
4:43 yeah, I think that's fine because we're going to work
4:46 in the guess directory from now on
4:48 and the venv is not sitting there
4:50 so the dot should work there. And we can confirm that by
4:53 going into guess, run a test, run a coverage report
5:01 with a dot. Yeah that's fine.
5:05 So when I'm writing my tests, I can just hit comma T,
5:11 it saves the file and it runs my coverage.
5:14 So that's a bit of Vim trick or shortcut
5:18 for Pycharm or another editor. There must be a similar way
5:21 to do this but this is my way of
5:23 running coverage with one keystroke in Vim.