[MUSIC] We're going to start our exploration, automated testing with one particular type of testing called unit testing. Now, to give you a little bit of intuition about what unit testing is about. Let's assume that we have an application that is composed of a bunch of different classes or components that we've built. So these could be activities in our application, for example, in our Android application. And so we have all of these different components that may have dependencies on each other. Maybe we've got other components that are added. And if we went and we tested everything as a whole, so we automated the test in very large pieces of functionality, for example. Let's say, that we were going and we're running a test related to some feature of this component. And we run it in the context of all of these other components that it depends on. So this, although, we're testing a feature related to it, it also depends on this component, which depends on this component, which also depends on this component. So we have, let's say, component a, b, c, and d. Now, let's say, we go and run that test case. And it might be something like we saw before, where we're going to go and select a drop down, hit a button, and then we're going to expect a particular list to show up. And then we're going to want that list to be in a particular format, and have a particular set of content. So let's say, we run that test and it doesn't work. Well, the next question we need to ask ourselves is, why is this test not working? Well, here, we have a problem. Well, it's not necessarily a problem but it's something that as a programmer, it's not ideal. My test has just failed, and I've got a, b, c, and d to check, to see if one of them has a bug that's causing my particular test to fail. So when we're testing as a whole, whenever something fails, it's harder to root out the exact cause of where the failure's coming from, because a bug in any of the dependent components, could generate the failure. So one of the things that we can do is what's called unit testing. And the idea behind this is, that we want to go and separate out our components, and isolate them. So we'll go and try to cut this component off from its dependencies in some way and focus on it. And then test it in a way that if the test case fails, we can isolate and say, we know it's from this specific unit or component, or however you're dividing up your unit test. You can go and create a unit test for this one thing. And then when it fails, have greater confidence that this particular thing was the reason that the test failed, because of some bug that is isolated in this unit. Now, why is this idea of isolating things so helpful to developers? If we just have four components, it may not be as big of a deal to be able to isolate the source of a failure very quickly. But if you're involved in an application over a long period of time, if you're building some really complex application that has hundreds or thousands of components. And particularly, if you have components that are built by different developers, maybe not necessarily yourself, but also your partners, or your teammates at a business. Suddenly, when something fails, being able to know the source, or hopefully, pinpoint and reduce the set of locations that the failure could have arisen from, is a very, very helpful tool to a developer. And so this is part of the idea behind unit testing, is we want to isolate things. So that when tests fail, we have a really good sense of where we need to go look for the problem. And we can go and hopefully, hone in on one very specific behavior or feature or functionality that we need to go and investigate as having a problem. And one of the nice things is if we can go and we can get all the unit tests for each of these things done independently, it gives us a sense that at least from the individual specifications, they're probably doing the right thing. And then when we go and compose them and integrate them later, we can try to root out different types of failures. But this is, the real intuition is if you're unit testing, you're trying to make it one so that you can isolate failures. But another thing that we're able to do when we're doing unit testing is we talked about, we want a programmer to focus on the things that they really want to do, writing code, making the changes, solving the hard intellectual problems. And in order to do that, we want them to be able to write something, and then click a button, and then instantly or as quickly as possible, get a result. Well, unit testing helps us here as well because if we know, for example, that they're trying to iterate quickly on one specific component, they can start off by let's say, running tests on that component until they think they're right. And then they can run tests on all the other components. And if we isolate things, we tend to make it so that we can run things faster. Now, I want to stop for one second. When I'm saying, you can go and run the test on this component, that doesn't mean that you should neglect running the rest of the tests. You absolutely shouldn't consider yourself done with the change or that it works. You haven't run through all the other tests and shown you can pass it. But when you're iterating quickly, sometimes you want to just pick a particular test. It's failing and you know it's failing in this component. And you want to iterate on it quickly, and just fix it there, and be able to get results very quickly. And then go and run the rest of the test suite. So unit testing not only helps us to sort of isolate where problems may be coming from. But also, in many cases, it can help us to run tests quicker and to get feedback faster. And then when somebody else comes down the road, and they go in and make a change to your particular component. If your unit test for that component fails, often, it's going to give them a very good idea when they go and look at the test. What it is that you were expecting and the component is supposed to do that's no longer happening. And that knowledge that you have about how that component is supposed to behave is encoded into the test. So there's also a knowledge transfer aspect to it as well when you're working in teams. Somebody else can come along and see what the expectation of how that capability or function in that component was supposed to behave. And they can see it programmatically, they can see it in software code. And they can check if it's being done correctly by running that code, which is a huge benefit. It allows other developers to come and understand in a less ambiguous way what you're expecting to happen. And then if that failure is there, they can go and quickly check. And if you're somebody else who doesn't have the domain knowledge and understanding because they didn't building the system of all the dependencies between these components. If they see the isolated failure, it's probably going to be much easier for them to find it. And then if they had to go up and find it here. And this may help you, as the original creator, but it could help somebody else who doesn't have this understanding of the dependencies even more than it helps you.