Exceptions3:27 with Kenneth Love
If your code raises exceptions it's a good idea to test them to make sure they get raised properly. Luckily `unittest` provides a mechanism for this.
assertRaises(x) - Make sure the following code raises the
You can use
@unittest.expectedFailure on tests that you know will fail
with assertRaises(ValueError): int('a')
Sometimes we want our code to fail in certain ways. 0:00 We want to be sure and 0:02 raise a value error when someone sends us a string instead of a number. 0:03 We want to trigger a does not exist when a database record hasn't been created yet. 0:07 So of course we want to test that these exceptions get raised. 0:11 Let's look at the assert raises assertion. 0:14 So when we read our Roll class and we look here, we see the description is this. 0:18 And we have this die_pattern.match, which if we go look at die_pattern, 0:24 we see it has to be a number, and then the letter d and then another number. 0:27 And if it doesn't do that, we see it raises this value error. 0:32 So we know that, that'll happen, right? 0:37 If we pass in a bad value then we're gonna get this value error back. 0:40 So let's write a test to cover that, 0:44 to make sure that it works the way that we think it does. 0:46 So we're gonna write a def test_bad_description. 0:50 And we're gonna use what's called a context manager which is this width. 0:57 It's where we're able to control the context, 1:01 we're able to change variable inside, within here. 1:02 So we're gonna say self.assertRaises and it's going to raise a value error. 1:06 And then we're gonna call dice.Roll and we're gonna pass it in 2b6. 1:10 All right? We know that, that's wrong. 1:17 So 2b6 because the b and the d don't match, so we know this is wrong. 1:21 This assertion is 1:24 used a little bit differently than the others that we've used. 1:25 We had that width keyword I talked about, the context manager. 1:27 And then we're also passing in a value of what the exception is going to be. 1:31 And it's a block. 1:36 Within that block, then we call the code. 1:37 So if the code actually causes the exception, then the test passes and 1:39 if it doesn't then it fails. 1:44 It's slightly backwards thinking but you really get used to it. 1:45 So let's try running this one. 1:49 So that works. 1:52 So all of our tests have passed and it's because we're so 1:53 super smart, or it's because we know what the code's gonna do and 1:55 we're writing our test for exactly what the code's gonna do. 1:59 Let's write a new test that won't pass, 'kay? 2:02 So let's actually go up here to the we're gonna do it down here. 2:07 And we're gonna write def_test_small_die. 2:11 'Kay, so we're gonna have a small die in this. 2:15 So we're gonna do with self.assertRaises(ValueError). 2:19 So just like before we're expecting this to, 2:26 to fail, we're going to do Roll 1d2. 2:31 Now this is actually a totally acceptable die, we can roll a two sided die, 2:35 it's called a coin. 2:39 So, we know this is valid, so this test should fail. 2:41 So lets run this, and it fails. 2:44 The value error was not raised, 'kay? 2:47 So that's great, we, we know how this fails. 2:50 Now we can go in here and we can actually mark this as expected to fail, 2:52 if you look at the docs which I'll link to, you'll see that you can mark this. 2:56 That's kinda silly. 3:00 We know this one's going to fail because this is a bad test case. 3:02 So we're just gonna delete it. 3:06 Okay. 3:08 So, testing for exceptions though, as we've done here with assertRaises 3:09 is a great way of making sure that your code fails like you're expecting it to, 3:13 and like you want it to. 3:16 Somewhat related to assertRaises are the assertWarns and assertLogs assertions. 3:18 You can use these to make sure that warnings, or log entries, 3:23 are created by your code. 3:26
You need to sign up for Treehouse in order to download course files.Sign up