Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Testing Bootstrap, with Genymotion

Eyal LEZMY
December 05, 2014

Android Testing Bootstrap, with Genymotion

This presentation introduces a small bootstrap to test Android applications on Android.
This talk is supposed to give good a good demo about what to test and how to test it.
At the end, we showed how to take profit of the Genymotion advanced features to automate your test and increase significantly their coverage.

Eyal LEZMY

December 05, 2014
Tweet

More Decks by Eyal LEZMY

Other Decks in Programming

Transcript

  1. Agenda 01 Context 02 What and Why? 03 How? 04

    Android Tests 05 Testing with Genymotion
  2. Assures the quality Of a software system Validates the requirements

    Part of the development cycle Often forgotten Or not seriously done Definition What && Why?
  3. You can say: IT WORKS! Early bug is cheaper Find

    edge cases in your code Force to write cleaner code Because you limit the code dependency What && Why? The Truth
  4. Helps Refactoring Because we love it Protects the features Make

    it easy, not scary Highlight the bugs What and where What && Why? Break it down
  5. Not a the last minute Test early, often & automatically

    Use continuous integration Test locally before shipping code Test when it is upstream Ship with the tests written When && How? Code little Test little
  6. A bug found is a test Extend existing tests when

    you correct it Be serious Test should be as good as production code Some advices When && How?
  7. Test Driven Development Write tests before business code We don’t

    do TDD For whole projects Sometimes it fits! Paralleling dev for interdependent modules Did you say TDD? When && How?
  8. Slower Run on device UI testing Quite Fast Run on

    JVM Mock framework Fast Pure JUnit Robolectric Android Test Framework Android Tests
  9. Run test on the JVM Good old Java Use latest

    Junit Good for unit testing Android Tests Pure Junit JUnit
  10. apply plugin: 'java' dependencies { … testCompile('junit:junit:4.12-beta-2') } Add the

    dependency Android Tests Configure module Procedure: - create a separate “pure java” module - put the Java classes under main/ - put the Junit tests under /test
  11. public class CalculatorTest { protected Calculator calculator; @Before public void

    setUp() { calculator = new Calculator(2); } @Test public void testSumUpReturnsCorrectResult() { int result = calculator.sumUp(1); assert (result == 3); } @After public void tearDown() { //no op} } Android Tests Write tests
  12. Run the gradle task from the command line. Make sure

    the command is ran at the root of the project directory. Run all the tests for the whole project: $./gradlew test Run only the tests for the pure java module: $./gradlew :myjavamodulename:test Android Tests Run the tests
  13. Run test on the JVM Run the test on the

    JVM Combines with a mocking framework Use the shadow objects Good for unit/integration testing Android Tests Robolectric
  14. apply plugin: 'com.android.application' apply plugin: 'robolectric' buildScript { repositories {

    jcenter() } dependencies { classpath 'org.robolectric:robolectric-gradle-plugin:0.12.+' } } … Add the dependency Android Tests Configure build.gradle (1/2) Apply the plugin
  15. … robolectric { include '**/*Test.class' exclude '**/espresso/**/*.class' } dependencies {

    … androidTestCompile( 'org.robolectric:robolectric:2.3') androidTestCompile( 'junit:junit:4.12-beta-2') … } Add the dependencies Android Tests Configure build.gradle (2/2) Configure the plugin
  16. @RunWith(CustomRobolectricTestRunner.class) public class MainActivityRoboTest { @Test public void testWhenActivityCreatedBatteryLevelViewIsVisible() throws

    Exception { MainActivity activity = new MainActivity(); ActivityController.of(activity).attach().create(); int visibility = activity.findViewById(R.id.battery_level_view).getVisibility(); assertEquals(visibility, View.VISIBLE); } } Android Tests Write tests Use a custom runner
  17. Run the gradle task from the command line. Make sure

    the command is ran at the root of the project directory. Run all the tests for the whole project: $./gradlew test Run only the tests for the android module: $./gradlew :myandroidmodulename:test Android Tests Run the tests
  18. Test the UI Espresso for the win Run the test

    on a real device Good for integration/functional testing Android Test Framework Android Tests
  19. … android { defaultConfig { … testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner" } }

    dependencies { … androidTestCompile "com.google.android:android-espresso-bundled:1.1.0-SNAPSHOT" } Android Tests Configure build.gradle (2/2)
  20. public class MainActivityEspressoTest extends ActivityInstrumentationTestCase2<MainActivity> { @Override public void setUp()

    throws Exception { super.setUp(); mainActivity = getActivity(); batteryLevelView = mainActivity.findViewById(R.id.battery_level_view); } public void testBatteryLevelViewIsShown() { assertOnScreen(mainActivity.getWindow().getDecorView(), batteryLevelView); } } Android Tests Write tests
  21. Run the gradle task from the command line. Make sure

    the command is ran at the root of the project directory. Make sure a device is connected to the workstation. Run all the instrumentation tests for the whole project: $./gradlew connectedAndroidTest Android Tests Run the tests
  22. Android Tests How to not get INSANE dependencies { ...

    androidTestCompile('junit:junit:4.12-beta-2') { exclude group: 'org.hamcrest' } androidTestCompile('org.robolectric:robolectric:2.3') { exclude module: 'classworlds' exclude module: 'commons-logging' exclude module: 'httpclient' ... } } packagingOptions { exclude 'META-INF/LICENSE.txt' exclude 'LICENSE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' }
  23. Genymotion Tools Change in orientation Change in configuration Keyboard available

    System language Battery life External ressources Network access GPS SMS Bluetooth What to test? According to Google
  24. Genymotion Tools Orientation Landscape, Portrait, Angle, ... Radio Full telephony

    & SMS Network Simulate Wifi, 4G, 3G, Edge, … Java API Very soon
  25. repositories { maven{ url "http://api.genymotion.com/repositories/releases/" } ... } Add the

    Java API repository Add the Java API dependency dependencies { androidTestCompile "com.genymotion.api:genymotion-api:1.0.0" } Genymotion Tools Configure build.gradle
  26. public class TestGps extends ActivityInstrumentationTestCase2<SampleActivity> { public void testGpsWarning() {

    //Avoid the test if not a Genymotion device if (!GenymotionManager.isGenymotionDevice()) return; GenymotionManager.getGenymotionManager(context) .getGps() .setLatitude(64.13367829) .setLongitude(-21.8964386); //Your tests assertEquals(view.getVisibility(), View.GONE); } Test if Genymotion device Set the GPS Position Genymotion Tools TestGPS.java Test your app there! Let’s go to Dalvik
  27. Genymotion Tools Based on command line GMTool Define your devices

    Template, screen size, ... Customize your device Flash, Install, push, pull Start the device Before your test task Gradle Pugin Coming soon!
  28. buildscript { repositories { maven { url "comming soon" }

    } apply plugin: "genymotion" genymotion { device( template: "Google Nexus 5 - 4.4.4 - API 19 - 1080x1920", ) device( name: "Nexus 7", template: "Google Nexus 7 - 4.2.2 - API 17 - 800x1280", ) Add the plugin repository Apply the gradle plugin Genymotion Tools build.gradle Define the target devices
  29. device( name: "Nexus 10", template: "Google Nexus 10 - 4.3

    - API 18 - 2560x1600", density: "XHDPI", width: 800, height: 600, virtualKeyboard: true, flash: "PATH_TO/test.zip", install: "PATH_TO/test.apk", pushBefore: ["PATH_TO/test.txt", "PATH_TO/test2.txt"], pullAfter: ["/system/build.prop":"PATH_TO/res/"], logcat: "PATH_TO/res/Nexus 10.logcat", stopWhenFinish: false, deleteWhenFinish: false, ... ) Edit the device on the fly Override /system/ Genymotion Tools build.gradle push/pull files before/after tests Install apps Route logcat to a file And more!
  30. Test samples https://github.com/flo-genymobile/JustTestIt Genymotion Java API sample https://github.com/Genymobile/genymotion-binocle Genymotion Gradle

    plugin sample Coming soon What to test, according to Google http://developer.android.com/tools/testing/what_to_test.html References & Links