unit testing android applications
TRANSCRIPT
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
Resources
https://github.com/ddoa/dea-code-examples/android-deckard-unittest/
http://pages.cpsc.ucalgary.ca/~maurer/uploads/SENG515615F2007/XUnitTestPattern.ppt
http://code.google.com/p/mockito/ https://docs.google.com/presentation/d/1J0W
iFJI9wSkc3UMsNXYv8ixX5orjkYzduwyOalzEkjU/embed?hl=pl&size=l#slide=id.p5