PROFESSIONAL ANDROID
APP DEVELOPMENT
Testing
Why?
Reliable Software
Writing new code (new features or
refactoring) without having to worry over
breaking the pre-existing code
Testing Types
Black-box, used when we don’t know
implementation details.
• Acceptance testing
• System testing
Testing Types
White-box, when we do know the structure,
design and implementation.
• Unit testing
• Integration testing
Testing Types
How many tests?
Unit Tests
Small(contrary to end-to-end)
Many (literally, they have to be A LOT)
Testing different environments
Quick
Mocks
Simulated objects that imitate real
object’s behavior, in a controlled way.
Stubs
It allows us to isolate dependencies.
Mockito
A framework that allows us to write
test over a simple and
comprehensible API.
Tests are readable and with clear
verification errors.
Using Mockito
public class MockitoTest {
@Mock
private Dependecy dependency;
private TestSubject subject;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
subject = new TestSubject(dependency);
}
@Test
public void testSomething() {
subject.doSomething();
verify(dependecy).methodCalledInsideDoSomething();
}
}
Using Mockito
public class MockitoTest {
@Test
public void testSomehting(){
List mockedList = mock(List.class);
mockedList.add("one");
mockedList.clear();
verify(mockedList).add("one");
verify(mockedList).clear();
}
}
Using Mockito
public class MockitoTest {
@Test
public void testSomehting(){
LinkedList mockedList = mock(LinkedList.class);
when(mockedList.get(0)).thenReturn("first");
//first
System.out.println(mockedList.get(0));
//null
System.out.println(mockedList.get(999));
}
}
BDD
Given
When
Then
Given an initial context, when an
event occurs, then we ensure some
specific result.
BDD
Seller seller = mock(Seller.class);
Shop shop = new Shop(seller);
public void shouldBuyBread() throws Exception {
//given
given(seller.askForBread()).willReturn(new Bread());
//when
Goods goods = shop.buyBread();
//then
assertThat(goods, containBread());
}
Mockito
Adding Support
build.gradle file
dependencies {
testCompile 'org.mockito:mockito-all:1.10.19'
}
Unit testing on Android
Mockito is a testing framework for
Java, it cannot “imitate” the Android
component’s behaviour.
java.lang.RuntimeException("Stub!
")
Robolectric
A unit test framework that allows the
execution of Android's JVM code. Uploads
Android classes on Java projects.
Using Robolectric
@RunWith(RobolectricTestRunner.class)
public class MyActivityTest {
@Test
public void clickingButton_shouldChangeResultsViewText() throws Exception {
MyActivity activity = Robolectric.setupActivity(MyActivity.class);
Button button = (Button) activity.findViewById(R.id.button);
TextView results = (TextView) activity.findViewById(R.id.results);
button.performClick();
assertThat(results.getText().toString()).isEqualTo("Robolectric Rocks!");
}
}
Obtaining an Activity
Most of the time, this works
Activity activity = Robolectric.buildActivity(MyAwesomeActivity.class).create().get();
But we can also access other events within the
life cycle
ActivityController controller =
Robolectric.buildActivity(MyAwesomeActivity.class).create().start();
Activity activity = controller.get();
// revisar que algo no ha ocurrido
activityController.resume();
// revisar que ya ocurrió
Obtaining an Activity
Full Life-Cycle Creation
Activity activity =
Robolectric.buildActivity(MyAwesomeActivity.class).create().start().resume().visible
().get();
We can also simulate the calling Intent
Intent intent = new Intent(Intent.ACTION_VIEW);
Activity activity =
Robolectric.buildActivity(MyAwesomeActivity.class).withIntent(intent).create().get()
;
Shadow classes
Modification or extension of real classes...
… But they are not proxies, fakes, mocks or
stubs
At least they’re not called sheeps :-)
Shadows
@Implements(ImageView.class)
public class ShadowImageView extends ShadowView {
...
@Implementation
public void setImageResource(int resId) {
// implementation here.
}
}
Accessing real objects
@Implements(Point.class)
public class ShadowPoint {
@RealObject private Point realPoint;
...
public void __constructor__(int x, int y) {
realPoint.x = x;
realPoint.y = y;
}
}
Robolectric
Adding support
build.gradle file
dependencies {
compile 'org.robolectric:robolectric:3.0'
}
How do I start?
Simplify the architecture (Or have one!)
Establish a test strategy
Take advantage of the mocks and stubs
Are there any other tools?
Many more
PowerMockito
Hamcrest
AssertJ Android
Robotium
UI Testing
Espresso
Firebase Test Lab
https://facebook.github.io/screenshot-tests-for-android/
More info:
• http://mockito.org/
• http://robolectric.org/
• https://github.com/robolectric/robolectric/tree/master/robolectri
c-shadows/shadows-core/src/main/java/org/robolectric/shadows
• https://developer.android.com/training/testing/unit-
testing/index.html
• https://www.youtube.com/watch?v=GnNMpMBQscM