Статьи

Модульное тестирование Android

Этот пост посвящен модульному тестированию нативного приложения для Android. Работая над своим собственным скромным Android-приложением, я хотел добавить неинструментированные модульные тесты и был удивлен, насколько сложно было использовать фиктивные объекты. По общему признанию, инструментальные тесты, выполняемые на эмуляторе или реальном устройстве, вероятно, являются лучшим способом, но я хотел более быстрый способ убедиться, что моя внутренняя логика все еще работала, как ожидалось, при внесении изменений.

Тестируемый код

Вот один из примеров кода, который я пытался протестировать:

public class ViewOnTouchDragStartListener implements View.OnTouchListener {

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            ClipData clipData = ClipData.newPlainText("", "");
            View.DragShadowBuilder dsb = new View.DragShadowBuilder(view);
            view.startDrag(clipData, dsb, view, 0);
            view.setVisibility(View.INVISIBLE);
            return true;
        } else {
            return false;
        }
    }
}

Когда я начал писать свой тестовый метод, мой план был прост, просто используйте Mockito, чтобы создавать макеты для объектов View и MotionEvent, устанавливать ожидания, запускать тест и наблюдать за зеленой полосой. Вместо этого я получил множество ошибок RuntimeException («Stub!») . Поэтому я вернулся к чертежной доске (Google), которая привела меня к PowerMock. Я уже некоторое время использую Mockito, и я знал о PowerMock, который можно использовать для расширения возможностей таких платформ, как Mockito и EasyMock, для включения, среди прочего, насмешек над конструкторами, частными и статическими методами. Казалось, это именно то, что я искал, чтобы помочь с моими проблемами модульного тестирования Android.

Модульное тестирование займет два

Я скачал powermock-mockit-junit-1.4.10 (самый актуальный на момент написания статьи). Также доступны загрузки для работы с TestNG и EasyMock . После некоторой консультации с документацией вот мой улучшенный модульный тест

@RunWith(PowerMockRunner.class)
@PrepareForTest({MotionEvent.class, ClipData.class,ViewOnTouchDragStartListener.class,View.class})
public class ViewOnTouchDragStartListenerTest {
    private ViewOnTouchDragStartListener dragStartListener;
    private View view;
    private MotionEvent motionEvent;
    private ClipData clipData;
    private View.DragShadowBuilder dragShadowBuilder;

    @Before
    public void setUp() throws Exception {
        dragStartListener = new ViewOnTouchDragStartListener();
        view = PowerMockito.mock(View.class);
        PowerMockito.mockStatic(ClipData.class);
        clipData = PowerMockito.mock(ClipData.class);
        motionEvent = PowerMockito.mock(MotionEvent.class);
        dragShadowBuilder = PowerMockito.mock(View.DragShadowBuilder.class);
    }

    @Test
    public void testOnTouchActionDown() throws Exception {
        PowerMockito.when(motionEvent.getAction()).thenReturn(MotionEvent.ACTION_DOWN);
        when(ClipData.newPlainText("", "")).thenReturn(clipData);
        PowerMockito.whenNew(View.DragShadowBuilder.class).withArguments(view).thenReturn(dragShadowBuilder);
        boolean isActionDown = dragStartListener.onTouch(view, motionEvent);
        InOrder inOrder = inOrder(view);
        inOrder.verify(view).startDrag(Matchers.<ClipData>anyObject(), Matchers.<View.DragShadowBuilder>anyObject(), eq(view),eq(0));
        inOrder.verify(view).setVisibility(View.INVISIBLE);
        assertThat(isActionDown,is(true));
    }

Я нашел это довольно простым для реализации, и, что самое приятное, я стал зеленеть для всех своих модульных тестов! Я был впечатлен способностью PowerMock смоделировать вызов конструктора View.DragShadowBuilder внутри метода onTouch ViewOnTouchDragStartListener (строка 24 примера тестового кода и строка 5 примера кода, соответственно). Следует признать, что, вероятно, должен был существовать отдельный метод, который создавал бы и возвращал объект DragShadowBuilder, а затем использовал бы шпионскую функциональность PowerMock / Mockito, которая позволяет выборочно моделировать методы на реальных объектах.

Надеюсь, это поможет вам в тестировании устройств Android.

 

С http://codingjunkie.net/android-unit-testing/