#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.