How to test Android Apps: Instrumentation Testing

移动互联 Bloco

Although you should avoid having your code tied to Android components, it’s not always possible. Maybe it’s Activity
code, or a component that needs Context
. But you still should test it.

Those tests will have to run on an emulator or a real device. They are going to be slower. But they are important nevertheless.

Here’s how you can do that:

Testing with application context

Sometimes you just need Context
to test your code, and not a full activity. For example, testing a database integration, or a file resource loader. For those cases, you can use the
ApplicationTestCase

.

An example:

public class DatabaseTest extends ApplicationTestCase {

    private Database database;

    public DatabaseTest() {
        super(AndroidApplication.class);
    }

    @Override
    public void setUp() throws Exception {
        createApplication();
        database = new Database(getContext());
    }

    public void testSaveCard() throws Exception {
        assertEquals(database.countCards(), 0);
        Card card = new Card("1234");
        database.saveCard(card);
        assertEquals(database.countCards(), 1);
    }

    @Override
    public void tearDown() throws Exception {
        database.deleteAllCards();
    }

}

In this example, we’re testing a Database
class that needs a Context
. After creating the application, we can use the getContext()
method to get the application Context
and pass it on as an argument. The rest of the code is just a general example.

Testing activities

If you want to test an activity, or a specific view, you need to launch an Activity. These tests are even slower than Application tests. But it’s important to have these instrumentation tests, that run like an user interacting with your app.

Instrumentation tests are tedious to write, and often run into race conditions. To ease the load, you should use a UI testing library to help you. The most popular right now is Espresso
, from the Android Testing Support Library. It helps you find views, perform actions, wait for the consequences and check state.

Here’s an example of an Activity instrumentation test.

@RunWith(AndroidJUnit4.class)
public class CalculatorActivityTest {

    @Rule
    public ActivityTestRule activityTestRule =
        new ActivityTestRule(CalculatorActivity.class);

    @Test
    public void testSum() throws Exception {
        onView(withId(R.id.calculator_input))
            .perform(typeText("2 + 2"))
        onView(withText("="))
            .perform(click());
        onView(withId(R.id.calculator_result))
            .check(matches(withText("4")));
    }

}

The example tests a calculator, with an input EditText
, a button with the =
caption and n result TextView
. Espresso can find views by id, text, content description, hint, view hierarchy and other
ViewMatchers

. It can perform actions like clicking, swiping, general navigation and other
ViewActions

. Finally, Espresso can assert state using the same ViewMatchers
, or other
ViewAssertions

.

Waiting

Espresso already does a good job knowing when to wait before assertions. But if you have custom animations, or another special conditions to wait for, you will need to add them.

Espresso comes with
IdlingResource

for that, but I’ve found it a bit too complex for most cases. I ended up implementing a simple Wait helper
. Here’s how you can use it:

new Wait(new Wait.Condition() {
    @Override
    public boolean check() {
        return someView.isEnabled();
    }
}).waitForIt();

Resources

How to test Android Apps

  1. Introduction
  2. Architecture
  3. Unit Testing
  4. Instrumentation Testing
  5. Other details
稿源:Bloco (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 移动互联 » How to test Android Apps: Instrumentation Testing

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录