#100DaysOfCode in Python Transcripts
Chapter: Days 10-12: Testing your code with pytest
Lecture: Mocking user input and exceptions
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
The second thing I want to test is the guess method.
0:02
It takes a user input and input is not static,
0:06
you can change and it can be random.
0:08
Even worse, when you run this program
0:10
it's waiting at the prompt to get input
0:11
so your test would hang, quickly demo this.
0:17
Let's make a game object, and run it.
0:26
Actually it's not hanging, it's throwing an error,
0:29
pretty soon, reading from standard input
0:31
output is captured, so that's cool.
0:33
And look at the output, it's pretty verbose
0:35
which is a nice feature of pytest.
0:38
But anyway, we definitely don't want to use input
0:40
literally in tests, so I'm going to use patch again.
0:44
And I'm going to patch the built-ins input,
0:50
and this is another way of marking.
0:52
Here I can give it side effects.
0:56
And a list of expected returns in a row.
1:00
Because I'm having all these exceptions here,
1:02
I'm going to give it a bunch of inputs
1:04
to go through all these scenarios and see
1:06
if each scenario throws the value error
1:09
or accepts the guess as a correct one.
1:11
And will also show you how you can check for
1:14
exceptions in pytest which are important
1:17
because raising exceptions is a common Python pattern.
1:21
So what we're doing here is setting up
1:23
a sequence of return values as if input was
1:26
called that many times.
1:28
So it will return a 11, then 12 as a string,
1:31
then bob, then 12,
1:36
then five minus one, 21
1:40
seven and None.
1:43
And those are the values that we're going to work with,
1:45
and you have to give it an argument,
1:47
it can be called anything.
1:49
And now we have some return data from input to work with.
1:52
So I'm making a game, and again,
1:54
the constructor sets defaults
1:56
for all the internal variables,
1:57
so that should be fine,
1:59
and then I can start to make assertions.
2:02
And the first two side effects or returns are good.
2:10
and again I will show you guess,
2:11
so guess goes through getting an input,
2:14
looking for all the bad inputs and raise a value error
2:17
if so, and if it's good it ends up adding
2:19
it to it's internal set which is the underscore guesses,
2:23
and returning the guess.
2:24
So 11 is good,
2:30
12 is a string should be fine
2:33
because that can be converted into a int.
2:36
The second one, bob, is not a number.
2:38
And the way in pytest to check if an exception is raised
2:42
is to use pytest, and you need to import that,
2:48
and do a with pytest.raises,
2:51
the name of the exception and then the statement
2:57
that would trigger that exception.
2:59
So the next return value from input in the row
3:03
is bob's string, if I call guess with that
3:06
it should raise a value error
3:07
and we're telling pytest to check if
3:10
it actually raises that exception.
3:12
And the same is true for the next one with is 12.
3:16
If I guess again, the guess is already in the guesses set
3:20
and the function manually raises a value error.
3:23
I can just copy this and it will be the same.
3:26
So every new call of guess triggers this input statement
3:31
or call, which triggers a new value in the return list.
3:35
So 12 is done, five should be fine.
3:42
Right let's run what we have so far
3:44
because it's a lot of code and see if it works.
3:50
All right that looks good.
3:51
So now let's do the complete list again.
3:55
And after five comes minus one and 21
3:59
which should be two exceptions because
4:00
they are out of range.
4:08
Another good one, and finally None should not be a good one,
4:15
that falls into this one, if not guess
4:17
raise a value error, please enter a number.
4:19
So we wrap up with...
4:24
So that's save, Control + Z, pytest
4:29
you're still happy.
4:30
I mean if it would say...
4:34
Game guess returns None when given None it will fail.
4:41
So we have please enter a number
4:43
so it actually raised a value error,
4:45
and it was not catching that.
4:47
Here I do, and it works.
4:52
So that's how I use mocking to circumvent
4:56
this input function waiting for input.
4:59
I'm going through all these scenarios
5:01
by giving various side effects.
5:03
Next up, validate guess.