Unit Testing Android Applications

Preview:

Citation preview

Tests, Stubs, Mocks

Effective Unittesting for android

Goals of test automation

Improve quality Understand the SUT Reduce the risk Easy to run Easy to write Easy to maintain

SubjectUnderTest

Principles in test automation

Write the test first. Each test should be:

– Small and simple– Independent to other test– Repeatable– Self-checking Fully Automated

First do “State verification” and then “Behavior Verification”.

Which part can be automated?

System Under Test

It may have Depended-on components

Image From: xunit Test Patterns, G. Meszaros

What are we talking about?

Pattern: Test Double Also known as: Imposter Problem: How can we verify logic

independently when code it depends on is unusable? How can we avoid Slow Tests?

Solution: We replace a component on which the SUT depends with a "test-specific equivalent."

WHAT?

Test Doubles: Dummy Object: Temporary Object that does not influence the SUT Test Stub: Hand coded object used for testing Test Spy: Verification occurs after the test method has been called Mock Object: Expectations configured before calling tests Fake Object: Typically, it implements the same functionality as the real

DOC but in a much simpler way, no expectation are configured.

Mock? Why? Mock - a simulated object that

mimics the behavior of a real object in controlled ways.

Four phase testing

Image From: xunit Test Patterns, G. Meszaros

Test structureSetup

Execute

Verify

Effective test automation

After test generation by considering all paths and the features and organization specified, our test still may have these bad smells:– Slow Tests– Test Code Duplication– Obscure Tests– Buggy Tests

Image SRC: www.dilbert.com

Mockito, how to drink it? framework basics

import static org.mockito.Mockito.*; //mock creationLinkedList mockedList = mock(LinkedList.class);

//using mock objectmockedList.add("one");mockedList.clear();

//verificationverify(mockedList).add("one");verify(mockedList).clear();

Stub - Mockito can mock concrete classes, not only interfaces

Mockito, how to drink it? framework basics

Return value thenReturn()when(mock.someMethod("some arg")).thenReturn("foo");

Stubbing voids requires doReturn() doReturn("bar").when(mock).foo();

What else to use

PowerMock (private, final,static methods)

Jmockit (constructors and static methods mocking)

Hamcrest (library of matcher objects (also known as constraints or predicates) allowing 'match' rules to be defined declaratively)

ANDROID UNIT TESTING

EXAMPLE: JUNIT + ROBOLECTRIC for Android

Android unit testing is tricky:– android.jar only contains mocked out .class

files which leads to java.lang.RuntimeException: Stub!

TIPS:– Keep things simple by trying to make as many

services as possible not dependent on the parts of the Android platform that are not compatible with a conventional JVM.

– Robolectric to the rescue

Unit test depending on Android api

@RunWith(RobolectricTestRunner.class)public class PopularRoutesAdapterTest { private PopularRoutesAdapter adapter;

@Before public void setUp() { adapter = new PopularRoutesAdapter(

Robolectric.buildActivity(Activity.class).create().get(); }

@Test public void testAddItem() { assertEquals(0, adapter.getCount()); adapter.addItem(new Route("Arnhem")); assertEquals(1, adapter.getCount()); }

Special test runner coming with Robolectric

Activity class is mocked by Robolectric

General rules to remember

Mock it outside your code If you cannot test your code -> then probably

you should change it ;) cause its badly written

Test first Only one concrete class , mock the rest Only mock your neirest neighbour (Law of

Demeter -> dont talk with strangers) Think ;) and then write

Robo-WTFRobolectric

Has Java implementations of class files for most of the Android API

Enables true unittesting, being not dependent on any network, hardware, device or database

Roboguice

Guice for RobolectricDependency Injection

based in Google GuiceCode bases DI instead

of XML (like in Spring)

Deckard

Combination of – Gradle / Maven– Robolectric– Junit

Example adds– Roboguice– Mockito

DEMO

Developers Not Writing Tests

Symptoms:– No tests can be found when you ask to see the

• unit tests for a task,• customer tests for a User Story,

– Lack of clarity about what a user story or task really means Impact:

– Lack of safety net– Lack of focus

Possible Causes:– Hard to Test Code?– Not enough time?– Don’t have the skills?– Have been told not to?– Don’t see the value?

Robolectric for unittesting

Espresso for scenario-testing

Recommended