The Happy Path and Beyond7:40 with Craig Dennis
The happy path makes sure that code works the way it was intended to work.
[MUSIC] 0:00 Now that we know how to test, it's time to start looking at the more difficult 0:04 question, and that is what to test. 0:08 Remember, this is the part where we developers haven't been replaced yet. 0:11 What we've looked at thus far is what is known as the happy path. 0:16 You should be able to determine what that path is by asking yourself this question. 0:19 If this code ran correctly, how would I know? 0:23 I'd like to take a moment to practice a skill once more. 0:27 Along with all the other parts we learned in the how to test stage. 0:30 Why don't we take a look at the other component that we broke out, the chooser? 0:34 Specifically, let's take a look at the alpha numeric chooser. 0:38 Okay, so we will press the double shift. 0:42 We'll do Shift, Shift and then I'll start looking for 0:45 alpha, there we go, AlphaNumericChooser.java, there it is. 0:48 Okay, so let's go over some key concepts here. 0:53 First off, this extends a class called AbstractChooser. 0:57 Let's open that up too. 1:01 This might be the first time you've seen this keyword here, abstract. 1:04 What this means, basically, is that the class cannot be instantiated. 1:09 You must extend it and 1:13 override some required methods that are also marked with the abstract keyword. 1:15 See the icon over here? 1:20 This shows who uses the subclass, and 1:22 then down here this shows who implements each one of these methods. 1:25 So this one is an abstract method. 1:28 Okay, and you'll notice that over here it doesn't have any definition. 1:31 Just says what it throws. 1:34 But it's abstract, you must extend and override this. 1:38 Wow, so this class, this abstract class also has an inner class named Location. 1:41 Inner classes are helpful sometimes to create classes that depend on certain 1:49 variables in a surrounding class, or parent class. 1:53 Do you see here how it's using maxRows and maxColumns from the AbstracChooser class? 1:57 The AbstractChooser takes a maxRows and a maxColumns and that's the outside class. 2:02 And the inside class here, this location, uses the maxRows and the maxColumns, 2:06 because it's in the right scope. 2:11 Also look here, the constructor for Location is protected. 2:13 So no one other than the code in this package can create a location, only us. 2:18 So you've used something like this before, remember map.entry in the map interface? 2:24 It looks like all this is doing is grabbing a row and 2:29 column, validating that it's allowed, and then returning it. 2:32 It's a pretty dumb object, right? 2:37 Now, you might not have seen any of these concepts before, and 2:39 I wanted to use them to show you and reiterate, that doesn't matter. 2:42 You are testing the behavior, not the implementation, remember? 2:47 We're not gonna test that all that stuff is true, 2:52 we're just gonna test the behavior. 2:55 So let's just do that, right? 2:56 What is the happy path that comes out of here? 2:58 Well the public API says one thing, 3:00 It says locationFromInput, and it returns a location. 3:04 So how about we make sure that if we choose something valid 3:09 it returns the expected row and column, sound good? 3:13 So we wanna test the elementation specifically, so 3:16 let's switch over to the AlphanumericChooser. 3:19 So see we can mouse over here and here we'll jump back over there? 3:22 Cool. 3:26 So, let's create a new test over here, so again that's Cmd+Shift+T or 3:27 Shift+Ctrl+T in Windows. 3:32 And I'm gonna choose Create New Test. 3:34 JUnit four, it's got the right class name, it's in the right passage. 3:38 This time let's go ahead and let's make a before method. 3:42 And let's just go ahead and have it generate this test. 3:44 We're gonna rename it, we know that it's gonna give us a wrong name. 3:46 So let's go ahead and create that. 3:49 First things first, let's rename that. 3:52 Let's say validInputReturnsProperLocation. 3:54 All right, so how about in the Before up here 4:03 we have it create the chooser for us, right? 4:08 So we're gonna say, chooser= new AlphaNumericChooser. 4:12 And remember that that takes the max rows as 26 rows for the alphabet, 4:17 we'll just do that. 4:22 And then 10 columns that's a big vending machine. 4:23 Let's do that. 4:27 And it says can't resolve chooser, so 4:28 let's have it go ahead and create the field chooser for us. 4:31 Cool, okay, so we've got the arrange covered in the before method there, 4:35 now let's do the act. 4:39 So let's go ahead and get one of those locations out right, 4:41 that was that inner class. 4:45 We'll call it loc and we'll use the chooser that got instantiated and 4:46 we'll say location from input. 4:50 And let's just pass in the input, we'll pass in B4, and 4:52 now let's assert that we got the right location back. 4:57 So we want to make sure that B4 returns the second row, 5:02 right, A, B, and the fourth column. 5:07 So that's array indices 1 and 3, right? 5:10 Okay, so we're really only testing one behavior, but 5:15 we're probably gonna do it in two assert statements. 5:18 That's okay because we're testing the behavior. 5:21 There's two assert statements but it's the same behavior, right? 5:23 Okay, so let's do an assert,Equals, and 5:26 remember it goes expected and actual. 5:30 So we expect 1 for the row. 5:34 And we expect 2, or sorry, we expect 3 for the column, right? 5:40 So that's B4. 5:44 Cool, let's test it, awesome. 5:52 Here we can see our new test is showing up here and it looks like it passed, great. 5:56 It's kinda handy sometimes to always make sure that it fails too. 6:00 So cool, we can make sure that it fails. 6:06 You know what though? 6:09 Let's think about this, what if one these assertions, 6:10 one of these two assertions fail? 6:12 It's not gonna be obvious how it failed, right? 6:13 Let's break it and let's see. 6:16 All right, so if I say let's change this to 3. 6:17 It's just gonna say that it's an assertion error and expected 3 but it was 1. 6:24 But it's not clear, there's two assertions, not clear. 6:28 Is it talking about the row or is it talking about the column? 6:30 So this is a great use of the optional message parameter. 6:33 So what should do is you put on the positive version of what was expected. 6:38 So let's do that, so this would be here, this would be the proper row and 6:41 put in here, this is the proper column. 6:49 Okay, and then we refresh and run again, and we'll see that it says proper row. 6:54 So now, somebody, if this test fails, 7:01 they'll know, because of that message that we put in there, what that is. 7:02 It's a nice touch, right? 7:06 Fix that back. 7:08 There, now we know what's going on. 7:12 There are definitely more descriptive assertion patterns that we can use, and 7:13 are available to us, and we'll touch all those briefly here in a bit. 7:17 Looking at these class, if we come back here to this class, 7:21 there are some exceptions that are thrown in here. 7:24 We should probably try to test those too. 7:27 What a happy path we've found. 7:30 Exceptions are also part of the happy path. 7:32 So after this quick break, 7:34 let's learn how to properly test all expectations of our public facing API. 7:35
You need to sign up for Treehouse in order to download course files.Sign up