[MUSIC] I want to take some time to walk you through a specific example of how you do integration testing in Android. In Android, typically integration tests are done with what are called instrumentation tests. And the way that you can think about an integration test in the Android is, anything that doesn't depend upon the classes provided by Android. So for example, any of your own code it doesn't indirectly reference some code on Android is something that you can go and test with the JUnit test, it's just a standard JUnit test. Anything that you have that depends upon some part of Android, you're going to end up writing an instrumentation test in order to do integration testing on this because you actually had to integrate with Android in order to test that functionality in your application. Now, to show you an example of this, what we've got is a simple geo utilities class that we've created. And the idea behind this is it's just a simple utility that allows us to get the address and then return the zip code of any latitude and longitude provided by the location services. So if you go and look up the current GPS location or network location, the latitude and longitude of the device. You can then pass that to this utility. And it will return the current ZIP code of where you are. Now this is a simple example. Maybe we want to use this to log where our users are, zip code wise, when they do certain things, and then display a map of that. And we have some interesting statistics about where they were geographically based on zip code rather than of just latitude and longitude or on some other type of data. But you can imagine that we might create this geo utilities class. And then we need to go and test it. So the initial thing we might do is go and create a new JUnit test. So in our test package down here, we could go and create a geo utils class. And we could try to go and create a unit test for it. So for example, we might say, we might create a method to setup the go-utils we are going to be testing. We could say go-utils and then we would have @ before, which tells JUnit there's something we're going to run before the test. And then we could go down here and test that xyz happens. So we could have some test that we're going to go and write, related to the GeoUtils. And so we could do something like take the GeoUtils get the current zip code for zero, zero. We want to know that when zero, zero happens, that we get a certain zip code back that we're expecting. And we'll just go ahead and make this throw an exception, and then we could say, cert equals some zip code that were expected and what we actually got. Now, there's only one problem with this test so far, and that is I haven't exactly constructed the GeoUtils yet. And we will see in a second that causes a problem. So, let's say I want to go and create and initialize the GeoUtils. So, I'm going to do a new and GeoUtils and what we see is that the GeoUtils, if we look at the constructor for it, it expects a context. And the problem is that's an android context. And here inside this JUnit test, we don't have a context. So normally we would be passing in something like the current activity that we're in, or depending on who was calling this, the caller would be doing something like get context in passing here. But we don't have access to any of those android things inside this JUnit test. So this is a case where we have to use an integration test in order to go and test this functionality that we added. Well since we can't test this GeoUtils class for the standard Android unit test, I mean standard JUnit test. We can test it with an android instrumentation test. I going to delete this, so I can get rid of it and I'll go ahead and get rid of this test which isn't going to work because we can't get a context. So instead I'm want to show you how we actually go about testing this. So we need to do a couple of things in order to be able to run instrumentation test. So the first thing is we have to create a test case that runs with, and uses the at run with android J unit 4.class annotation. So, what this is telling android is that we're going to run this as an instrumentation test. And what an instrumentation test is is it's a test that rather than running locally here inside of the Android Studio. Android Studio is actually going to launch an Android emulator or use a Android device you have connected to your machine. And then, run this test inside of that Android device either that emulator or that actual Android phone that you have connected. Run the test inside that device where it has access to the context another capabilities of Android and then tell you what the result of running that test was on that emulator or that device. So this is a really sophisticated and powerful thing where we're actually taking a test and we're running it inside the device or the emulator. So, what we're going to do, is now, we're going to go back and try what we were doing before and show you how we can create these GeoUtils that we want to, that we couldn't get access to the things we needed before. So, we've got our GeoUtils member variable just like before, and we're going to create our setup method. We'll annotate this without the four, which is what we would normally do. And now what we can do is we can get access to a context in order to set up our GeoUtils. And the way that we do this is we're going to use an InstrumentationRegistry.getContext. And what this is doing is giving us back a context that we can us for testing within our instrumentation test. And once we've gotten that context, we can say GeoUtils equals new GeoUtils and we can pass in that context. So this right here is showing the big difference immediately between the standard JUnit test and the instrumentation test or integration test that we're writing right here. And that is we're integrating in and getting access to capabilities of the Android, in this case a context within our test. Now, lets go and a simple test for this, first let's write a test that will fail, so we're going to add a test and we'll do test a test that should fail. Let's just go ahead and create that. We're going to expect this thing to fail. And what we're going to do is say string zip code equals get current zip code, and I don't know what's the zip code of 00 is but I'm betting that if I pick a random zip code and I passed in when I get back from 00 to 0. It's not going to be correct. So, what we've done is we've created a simple test and again we're running this as an instrumentation test so that we can get access to a context which is an Android thing that we need and rely on that isn't available in a standard JUnit test. So once we have created this thing, we can run it and what you can notice is when we went to run it, it asked us which of the connected devices we want to run it on. In this case, we're going to run it on an emulator that we created the Nexus 6P. And Android is actually going and going to load the tests into this emulator here and run them. And we see that we have a great old build running at the bottom here, when it's actually having to load our code into that emulator in order to run the instrumentation test. Now, it'll take a minute to run this, and you can see that instrumentation tests are typically going to be much slower to run, then your JUnit pass. So, for example this log-in utils test that we wrote over here. It's something that we can run really quickly inside of our Android studio. So, we don't have to have an emulator running or a device connected. We don't have to wait for the code to get deployed and it makes it able for us to run the test much faster, depending on if you have an emulator running or not, how long the build takes and how long it takes to deploy the emulator. Running these instrumentation tests can take a while. So when you're thinking about structuring your tests, you might want to think through or even when you're thinking about how you structure your code. Know that the instrumentation test that you run are going to be slower and now you can see that we're actually going and it's installing our example down here into the emulator. So this is still taking quite a while. But you want to think about how to structure your code to make it so you can run most of your test quickly. So if you don't have to, Go through and write all instrumentation test, you should. And if can structure your code in a way that it allows you to factor out a lot of your test and to just standard J unit test, that's going to be better. Now, as expected, our test failed, it actually failed in a slightly different way than we expected, which is good because that's why we have testing this. Because we don't always know what the outcome is going to be of our code and so this gives us information about it. Now, I've got the latitude and longitude for Nashville, Tennessee which is where Vanderbilt is, and so I'm going to upgrade this test with the information for Vanderbilt. All right? Let's add our new test case that we'll actually pass. So that we can see some success, as well as some failure or a test case that we expect to pass. We'll see if it actually passed. And we'll test Nashville, Tennessee zip code from lat long lat through exception. Now, these are fictitious tests. You'd want to think through this more carefully if you were writing a complex set of tests for your app. But I’m going to go ahead and just add a simple test that will tell me if I’ve got the zip code right. So this happens to be latitude and longitude for the zip code of Vanderbilt. So if you center in on this, it should give us back the Vanderbilt zip code, which we expect that to be 37212. So as you can see, we've added this instrumentation test. Now, we're going to actually be using a real part of android. So not only have we gotten a context, but we know in this GeoUtils class that we go and look at it, that in order to call this getCurrentZipCode method we've got to reel Android's geo coder that we're using to get the address of the user and get the postal code. And the interesting thing was our first test showed us that this logic right here has some flaws with it, in that we're expecting the list to always be populated but that's not always the case. So anyways, we're going to go back here. We've got our test that we've just added. We'll go ahead and run that test again on our virtual device. And it may take little bit of time. And then we should see that the test passes, unlike the one before. If we look at the results of readiness test we can see that our integration test that's in Android instrumentation test, pass. And it was actually run inside of the emulator. It used the real Android Geocoder in order to get the address associated with this latitude and longitude and return address. And as we saw before there's just no way that we could've done this inside of a pure JUnit test because we need to integrate with the larger Android framework in order to be able to run this test correctly and do something with out GeoUtils class. So we saw how we can create the instrumentation test, itself. And we also have to do a little bit more work in our app to make sure that it supports instrumentation testing, in our Android Studio project. So what you need to do to make sure that you can do instrumentation testing is you need to make sure in your build.cradle file that if you go and look at the default config, and this section should be produced automatically when you create a new Android project. You want to make sure that you have this line for test instrumentation runner and this is needed in order to be able to have the ability to push your test into the Android emulator and run them there. So you need to have that line and make sure that that is there. You also need to make sure that you have the correct compile time dependencies. And that is Android test compile time dependencies. So down here, this is an example of the ones that you're going to probably need the support annotations for your test, the runner, but another one that we'll talk about later in another video is Espresso, which is particularly useful for doing UI testing of Android. So there's a couple of things you need to do before you go and start building instrumentation tests in order to make sure that they'll run. And in fact, if you actually go and take away this things and the way that you'll know that you're project isn't setup correctly for instrumentation testing is if you don't have this things here present in your project and I can go ahead and just comment them out to try to show you this. If I comment those out and I sync my project what we're going to see in a second is that, once this finishes reloading. That now we can see that we can't resolve the Android JUnit for Class, so this @Run with Android JUnit 4 isn't working anymore. And if you see something like that, like cannot resolve symbol Android JUnit 4 or instrumentation registry isn't resolved that typically means that there's some issue in your build.gradle file that you need to go and resolve. You're missing something that you need from a testing perspective and if I go and add this back, save it, we'll be able to go and see in a second after it finishes that our geo utils test works again. So if you run into cases where this Android JUnit four, the run with isn't being recognized, or the instrumentation test, the instrumentation registry get contacts that that isn't recognized, it's in class not found, that's typically because you have something wrong in your build.cradle.