#100DaysOfCode in Python Transcripts
Chapter: Days 10-12: Testing your code with pytest
Lecture: Testing (simulating) the game end-to-end
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
Alright for the final two test methods
0:02
that I actually want to run a whole game from end to end.
0:06
And I'm going to use the same technique as before
0:08
because we're still stuck with this input method
0:11
that requires us to input data which we don't have
0:15
in an automated way of running test with pytest.
0:18
So I'm going to do a patch of the input again
0:21
and I'm going to just simulate a whole game.
0:24
So I'm going to enter 4, 22, 9, 4, and 6.
0:31
They're going to play a win scenario
0:34
and I'm going to give it the input
0:35
which is the requirement of the patch
0:37
but I'm also going to capture the standard out
0:40
as I did before.
0:42
So I make a game.
0:45
And I need to give it a right answer
0:47
to make sense of these numbers.
0:49
So in this scenario win but at the fifth attempt,
0:53
which is 6. So the answer is 6.
0:58
I call the game and assert that the game state
1:02
is underscore win equals true.
1:08
Let's run this.
1:12
Okay. So what it actually did, calling game,
1:15
is it went through all these numbers
1:17
and when it got to the final one, the fifth attempt,
1:21
it asserted answers true, so the win was set to true.
1:25
And again, you can see in the call,
1:29
an actual look that when validate guess returns true,
1:33
which is on the previous test,
1:35
there is an intermediate variable win set to true
1:37
and it also sets the inner, or internal variable win,
1:40
to true. And that's what we are asserting here.
1:44
But what I'm also interested in
1:45
is how the output looks of the program.
1:48
So I can just again do capfd,
1:56
read out err,
1:57
and you can also just call this with zero indexing
2:00
then you don't need the throw-away variable at all.
2:04
And I have a bunch of expected states
2:08
which I'm going to copy in.
2:09
Let's actually assimilate this program.
2:11
So I have these steps I'm just going to
2:14
hard code the answer for a minute, 6.
2:19
So these are the steps.
2:22
So what the test is doing is pretty pretty cool.
2:24
So I'm simulating 4, 22, which is not in range.
2:30
9, 4, 6. So here you see the typical program,
2:37
and that's what we are asserting here
2:39
with these expected values.
2:41
So 4 is too low, number not in range.
2:43
9 is too high, already guessed.
2:45
6 is correct.
2:46
Plus an additional statement of it took you three guesses.
2:50
So let's reset this.
2:51
Let's clean the output from capfd a little,
2:54
with a list comprehension.
2:56
For line in out split by new line.
3:02
Only take lines with one or more characters.
3:05
So ignore blank lines basically.
3:11
And give me the strip lines. So I'm stripping off new lines.
3:18
Alright. And then we can just match it line by line.
3:22
I can use a zip to look over two sequences.
3:25
So you have line and expected in zip output and expected.
3:33
So this will look over expected
3:35
and look over output in parallel.
3:37
So the first value of output
3:39
would match the first value in expected and etc.
3:46
Alright. Look at that. What's my coverage?
3:52
94 percent, very nice.
3:54
So they're only a couple lines missing: 83, 87, 88
4:00
And 87 I'm okay with because this is just a calling code
4:04
if this is called as a script, which we've done before,
4:07
if I call it like this.
4:10
And line 83. Let's see if we can get
4:13
to this scenario as well.
4:15
So this is a lose scenario, where we tried it 5 times
4:18
and still did not assert the answer.
4:21
So let's set up a filled scenario.
4:25
Test, game, lose.
4:29
That's going to follow the same signature as above.
4:35
But I need more stamps.
4:38
So let's do a none, which should not count right away.
4:41
5, 9, 14, 11, 12, doesn't really matter
4:46
because what I need to do now
4:47
is to give it an answer that's just totally different.
4:50
So let's make a game.
4:53
And the game answer is 13. So it's not in all my guesses.
4:59
But this also test that none doesn't count
5:03
towards my guesses. So I can actually do 6 inputs
5:07
and this would be the fifth guess.
5:09
So I'm actually getting here in the first place.
5:13
Play the game.
5:16
I won't win this game.
5:23
And it should pass, right,
5:26
but the coverage should still be the same
5:29
because I'm not hitting that line yet.
5:31
I do. Yeah, I did.
5:32
So just to recap, this was line 83,
5:36
which corresponds to this line.
5:38
And what happened here, I played,
5:40
actually what I forgot is that this plays the whole game.
5:43
When I launch game, it goes through all these outputs.
5:46
And having guessed 5 times,
5:48
and not asserting this answer, I did get to the L's block.
5:52
I can actually show that. If I turn on non-capture mode.
5:57
See? It just prints the whole thing.
5:59
5's too low, 9 is too low, then I guessed 5 times.
6:02
Answer is 13. So I made it to this actual print statement.
6:06
And that was the final thing
6:08
to actually increase the coverage.
6:11
If you take main out, we have a 100% coverage
6:14
of our tests. You still need to have a critical eye
6:18
to your code and your tests
6:20
because one thing is to test it,
6:21
but, for example, I can get a 100%
6:24
on this earlier validation of the guesses,
6:27
sorry, this one,
6:29
but here I made sure that I'm going
6:31
into all the different kind of value errors.
6:33
Actually let's do an experiment.
6:35
If I'm not doing the not-a-number test,
6:38
would my coverage go down?
6:44
Wow, look at that, how cool.
6:46
So I took a test out
6:47
and now it's complaining that 35 and 36 are missing.
6:50
And 35 36 is they should be a number,
6:54
and that's the thing we just deleted.
6:56
So I had a string here,
6:58
and that not-a-number should raise an exception.
7:01
And coverage spotted that. So that's very cool,
7:03
that you can just pinpoint exactly which code
7:06
is not being tested versus which code it is.
7:08
But again, you still need to have a critical eye
7:10
of what you're testing.
7:11
Because one thing is to have all your lines, some were called,
7:14
but the other thing is how you call them.
7:16
What are you testing? Are you testing all the edge cases?
7:19
So testing is an art in itself.