Join Chiu-Ki Chan for an in-depth discussion in this video RecipeActivityTest: An espresso test, part of Effective Android Testing for Mobile Developers.
- [Instructor] So far, we have been adding functionalities to our app. Let's write some tests to make sure that it is behaving as expected. We will be using the Espresso library, which we already included as a dependency when we wrote our instrumentation unit test. At that point, we only used Espresso to get access to the context. Espresso also lets us simulate user actions, such as typing and clicking, and also verify the state of the UI.
We will create an Espresso test for recipe activity. Scroll up, and point your cursor to recipe activity. Press command shift T to create a new test. Press okay, and then select the folder Android Test, because we want to run it on an android device. The first thing we need is a test rule. At rule, and then public, activity test rule.
After, type recipe activity. We will call this variable activity rule. Initialize it by calling new activity test rule, delete the type, because we don't need it. We will need to give it three parameters. The first one is the class of activity we want to use. In our case, RecipeActivity.class. The second parameter is whether we want to launch it with touch mode, which is true for us, and finally, we want to give it false in launch activity, meaning that we do not want it to be launched automatically.
This is because we will need to pass it an intent with the proper recipe ID. Next, we can add a test function. What should we test? Let's test a case when we launch this activity without a proper recipe ID. At test, remember, this tells J unit that this is a test method, public void, recipe not found. Inside the test method, we are going to launch the activity without an intent.
ActivityRule.launchActivity, and pass in null as the intent. Next, we want to verify that it will show recipe not found. onView, withId, R.id.description, and then, dot check matches withText, R.string.recipe not found. Let's run the test. Click on the green triangle next to the test method, and click run.
Use the same selection for future launches. It was very fast, but Espresso launched our activity, and verified that the text indeed says recipe not found. We will add one more test here. After the description check, we want to check that the title is not displayed. OnView withId, R.id.title, and then dot check, matches not isDisplayed.
We will need to import not, so alt enter, and static input method. Any one of these will be fine, so just choose the first one. Now, we can run the test again by clicking on the green triangle on top. Yay, it passed. Let's add another test method where we'll actually verify that when we click on the title it will save it as favorite. Close the bottom tab so we have more space, and then, after the recipe not found test method, add another one.
At test, public void, clickToFavorite. This time, we want to load a valid recipe, so we will need to pass an intent to the activity rule. Intent, intent, equal new intent, and then next, we are going to put an extra so that we can pass in the recipe ID. Intent.putExtra. The key is going to be the constant that we defined in recipe activity.
So, recipeActivity.KEY_ID. The value is going to be creamed carrots this time. Chocolate pudding is good, but let's switch it up to carrots. With this intent, we are going to launch the activity. ActivityRule.launchActivity intent. We want to verify that the title view starts off with not selected, and then, when you click on it, it changes to selected.
So, onView, withId, R.id.title, check that the title text is as expected as well. So, withText, creamed carrots, with capital and a space, and then afterward, we will check that it is not selected. Espresso has a fluid API, so you can just tack it on at the end without calling onView withId again.
Check matches not selected, and then we will perform a click on the title. After that, we expect it to become selected. Dot check, matches, isSelected. Let's run this test method by clicking on the green triangle on the gutter next to the method name. Choose run, using selection, and press okay. All right, that passed as well.
Notice that I have implemented recipe activity, and then right away, also implemented recipe activity test. This is good practice to verify the UI of your activity right after you write it.
- Why test?
- Local vs. on-device
- Code coverage
- UI testing
- Hermetic environment
- Dependency injection
- Testing with MVP