{"id":2024,"date":"2014-11-20T11:35:00","date_gmt":"2014-11-20T16:35:00","guid":{"rendered":"http:\/\/qxf2.com\/blog\/?p=2024"},"modified":"2017-06-14T01:58:18","modified_gmt":"2017-06-14T05:58:18","slug":"android-unit-testing-robolectric-tutorial","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/android-unit-testing-robolectric-tutorial\/","title":{"rendered":"Android unit testing: Android testing framework and Robolectric"},"content":{"rendered":"<p><strong>Problem:<\/strong> There are not many good tutorials on Android unit testing<br \/>\n<br \/>\nAndroid applications are written in Java. So you probably think if you know JUnit, you can unit test Android applications. Surprise! JUnit is not sufficient for unit testing Android applications. Junit works when the code runs within a JVM. Android applications interact with the Android OS. So you need to learn and use a different testing framework.<br \/>\n<\/p>\n<hr>\n<h3>Why this post?<\/h3>\n<p><a href=\"http:\/\/www.qxf2.com\/?utm_source=android_unit_testing&#038;utm_medium=click&#038;utm_campaign=From%20blog\">Qxf2<\/a> likes <a href=\"http:\/\/en.wikipedia.org\/wiki\/Unit_testing\">unit testing<\/a>. Unit testing is one component of an effective testing strategy. Good <a href=\"http:\/\/martinfowler.com\/articles\/testing-culture.html\">unit testing<\/a> rocks. Android unit testing is still in its early days. There are not too many good tutorials that help testers get started with Android unit testing. This post is aimed at helping hands on testers get started with Android unit testing.<br \/>\n<br \/>\n<strong>NOTE:<\/strong> You can read our other posts on mobile app testing <a href=\"https:\/\/qxf2.com\/blog\/category\/mobile-automation\/\">here<\/a>.<br \/>\n<\/p>\n<hr>\n<h3>Overview<\/h3>\n<p>In this post we will show you two ways of writing and executing unit tests for Android applications:<br \/>\n1) <strong>Android testing framework<\/strong>: Android provides <a href=\"http:\/\/developer.android.com\/tools\/testing\/testing_android.html\">a testing framework<\/a> to run unit tests on both emulators and physical devices.<br \/>\n2) <strong>Robolectric<\/strong>: <a href=\"http:\/\/robolectric.org\/\">Robolectric<\/a> provides a unit test framework that allows you to run tests inside the JVM on your computer.<\/p>\n<p>We will use <a href=\"https:\/\/f-droid.org\/repository\/browse\/?fdid=com.evancharlton.mileage&#038;fdpage=23\">Mileage Tracker<\/a> app as our the application under test. We chose it because it was open source, the code base was relatively small and came with some unit tests. We will write a simple unit test and run it using both Android test framework and Robolectric.<\/p>\n<hr>\n<h3>Part I: Android testing framework<\/h3>\n<p>The <a href=\"https:\/\/developer.android.com\/tools\/testing\/index.html\">Android framework<\/a> provides a testing framework to test your application. Android test suites are based on JUnit 3. We can use JUnit to test a class that doesn&#8217;t call the Android API. We should use Android&#8217;s JUnit extensions to test Android components. At a high level our steps are:<br \/>\n<br \/>\n1. Set up Eclipse ADT<br \/>\n2. Import the test app to eclipse<br \/>\n3. Select a test and check the method<br \/>\n4. Run the test<br \/>\n<br \/>\n<strong>1. Set up Eclipse ADT<\/strong><br \/>\nDownload the Eclipse ADT and follow the instructions mentioned <a href=\"http:\/\/developer.android.com\/sdk\/installing\/index.html\">here<\/a><\/p>\n<p><strong>2. Import the test app to eclipse<\/strong><br \/>\nCreate a new &#8220;Android Project from Existing Code&#8221; and import the downloaded Mileage Tracker app to your eclipse. The Mileage Tracker app also has some sample tests which are already written. Set your root directory and check the projects to import as shown below.<\/p>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/import_mileage1.png\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/import_mileage1-300x287.png\" alt=\"Import Mileage Tracketr app to eclipse\" width=\"300\" height=\"287\" class=\"aligncenter size-medium wp-image-2047\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/import_mileage1-300x287.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/import_mileage1.png 518w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><strong>3. Select a test and check the method<\/strong><br \/>\nThe test project already has some tests written to check some of the apps functionality. We will focus on the test <em>VehicleListActivityTest.java<\/em> which checks the <em>canDelete()<\/em> method in <em>VehicleListActivity.java<\/em> in the package <em>com.evancharlton.mileage<\/em>. <\/p>\n<p>This method returns true if the <em>getAdapter().getCount()<\/em> is more than 1, else it returns false. This means that in the Vehicle tab you can delete any vehicle information only if there are more than one vehicle information present, else the delete option is not available.<\/p>\n<pre lang=\"java\">\r\n@Override\r\n\tpublic boolean canDelete(int position) {\r\n        return getAdapter().getCount() > 1;\r\n    }\r\n<\/pre>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Mileage-Delete-Function.png\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Mileage-Delete-Function-180x300.png\" alt=\"Delete in available only when there more than 2 vehicles\" width=\"180\" height=\"300\" class=\"aligncenter size-medium wp-image-2052\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Mileage-Delete-Function-180x300.png 180w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Mileage-Delete-Function.png 480w\" sizes=\"auto, (max-width: 180px) 100vw, 180px\" \/><\/a><\/p>\n<p>VehicleListActivityTest.java:<\/p>\n<pre lang=\"java\">\r\npackage com.evancharlton.mileage;\r\n\r\n\/**\r\n * Test to check that canDelete() in VehicleListActivity.java in the package com.evancharlton.mileage returns true if the getAdapter().getCount() is more than 1, else returns false. \r\n*A FakeAdapter class is created which extends BaseAdapter class so that we can set the count using setCount() function \r\n *\/\r\n\r\nimport com.evancharlton.mileage.adapters.FakeAdapter;\r\nimport com.evancharlton.mileage.tests.TestCase;\r\n\r\npublic class VehicleListActivityTest extends TestCase {\r\n\tprotected VehicleListActivity activity;\r\n\t\/\/ Creating an object of FakeAdaptor class\r\n\tprivate final FakeAdapter mMockAdapter = new FakeAdapter();\r\n\r\n\tprotected void setUp() throws Exception {\r\n\t\tsuper.setUp();\r\n\r\n\t\tactivity = new VehicleListActivity(mMockAdapter);\r\n\t}\r\n\r\n\tpublic void testCanDelete() {\r\n\t\tmMockAdapter.setCount(1); \r\n\t\t\/\/Since the vehicle count is set to 1 this will return false\r\n\t\tassertFalse(activity.canDelete(0));\r\n\r\n\t\tmMockAdapter.setCount(2);\r\n\t\t\/\/Since the vehicle count is set to 2 this will return true\r\n\t\tassertTrue(activity.canDelete(0));\r\n\t}\r\n}\r\n\r\n<\/pre>\n<p><strong> 4. Run the test<\/strong><br \/>\nRunning the test as Android JUnit involves building, deploying, and launching the app in an Android emulator or a physical device, hence the directory structure of MileageTest project is similar to that of Mileage Project. Please refer to this <a href=\"http:\/\/developer.android.com\/tools\/testing\/testing_eclipse.html#RunTestEclipse\">link<\/a> to set up the run configuration to run your tests either in device or an emulator. If you are running your test using emulator, follow this <a href=\"http:\/\/developer.android.com\/tools\/devices\/managing-avds.html\">link<\/a> for the process on how to create an emulator. <\/p>\n<p>Here is the snapshot of the test run as <strong>Android JUnit Test<\/strong>.<br \/>\n&#8211; VehicleListActivityTest for the mileage app.<br \/>\n<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_run.png\" data-rel=\"lightbox-image-2\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_run-300x168.png\" alt=\"AndroidJunit_run\" width=\"300\" height=\"168\" class=\"aligncenter size-medium wp-image-2031\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_run-300x168.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_run-1024x575.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_run.png 1366w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>-Result of the test (using an emulator)<br \/>\n<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_result.png\" data-rel=\"lightbox-image-3\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_result-300x168.png\" alt=\"androidjunittest_result\" width=\"300\" height=\"168\" class=\"aligncenter size-medium wp-image-2030\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_result-300x168.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_result-1024x575.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/AndroidJunit_result.png 1366w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>The console output as shown in the above screenshot shows that the MileageTest.apk is installed on the emulator for the test to be executed. <\/p>\n<hr>\n<h3>Part II: Android unit testing using Robolectric<\/h3>\n<p><a href=\"http:\/\/robolectric.org\/\">Robolectric<\/a> is a unit testing framework that allows you to write and run tests inside the JVM on your workstation. Robolectric makes this possible by rewriting Android SDK classes as they are being loaded and making it possible for them to run on a regular JVM. Running tests using the Android testing framework involves building, deploying and launching the app in an Android emulator or a physical device. The process is a bit slow. Robolectric addresses some of these concerns. At a high level our steps are:<br \/>\n<br \/>\n1. Download Robolectric jar and set up the test app in eclipse<br \/>\n2. Select a method to test<br \/>\n3. Write the test<br \/>\n4. Setting up the Run configuration<br \/>\n5. Running the test<br \/>\n<br \/>\n<strong>1. Download Robolectric jar and set up the test app in eclipse<\/strong><br \/>\nFollow the detailed steps given <a href=\"http:\/\/robolectric.org\/eclipse-quick-start\/\">here<\/a> to download the required jar and set up the Mileage Tracker app. In some cases you may require fest.jar and maps.jar files, you can refer to <a href=\"https:\/\/github.com\/codepath\/android_guides\/wiki\/Robolectric-Installation-for-Unit-Testing\">link<\/a> to set up Robolectric with these jars.<\/p>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/robolectric_dir_structure.png\" data-rel=\"lightbox-image-4\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/robolectric_dir_structure-300x168.png\" alt=\"robolectric_dir_structure\" width=\"300\" height=\"168\" class=\"aligncenter size-medium wp-image-2067\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/robolectric_dir_structure-300x168.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/robolectric_dir_structure-1024x575.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/robolectric_dir_structure.png 1366w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><strong>2. Select a method to test<\/strong><br \/>\nWe will test the same <em>canDelete()<\/em> method as mentioned above for Android unit test.<\/p>\n<p><strong>3. Write the test<\/strong><br \/>\nTo run our test using Robolectric, we will annotate the test using the @RunWith annotation.<\/p>\n<pre lang=\"java\">\r\npackage com.evancharlton.mileage;\r\n* Test to check that CanDelete() in VehicleListActivity.java in the package com.evancharlton.mileage returns true if the getAdapter().getCount() is more than 1, \r\n * else it returns false. A FakeAdapter class is created which extends BaseAdapter class so that we can set the count using setCount() function \r\n *\/\r\nimport static org.junit.Assert.*;\r\nimport org.junit.Before;\r\nimport org.junit.Test;\r\nimport org.junit.runner.RunWith;\r\nimport org.robolectric.Robolectric;\r\nimport org.robolectric.RobolectricTestRunner;\r\nimport org.robolectric.annotation.Config;\r\nimport com.evancharlton.mileage.VehicleListActivity;\r\n\r\n\/\/@Config annotation so that Robolectric emulate an SDK version, since Robolectric doesn't support API level 19 and above\r\n@Config(emulateSdk = 18) \r\n\/\/To run your test with Robolectric, you need to tell JUnit use the @RunWith annotation\r\n@RunWith(RobolectricTestRunner.class)\r\n\r\npublic class VehicleListActivityTest  {\r\n\t\r\n\tprotected VehicleListActivity activity;\r\n        private final MyAdapter testAdapter = new MyAdapter();\r\n\t\r\n\r\n    @Before\r\n    public void setup() throws Exception {\r\n\t\t\r\n        activity = new VehicleListActivity(testAdapter);\r\n    }\r\n    @Test\r\n    public void testCanDelete() throws Exception \r\n    {\r\n    \ttestAdapter.setCount(1);\r\n        \/\/Since the vehicle count is set to 1 this will return false\r\n        assertFalse(activity.canDelete(0));\r\n        testAdapter.setCount(2);\r\n\t\/\/Since the vehicle count is set to 2 this will return true\r\n\tassertTrue(activity.canDelete(0));\r\n    \t\r\n    }\r\n\r\n}\r\n<\/pre>\n<p><strong>4. Setting up the Run configuration<\/strong><br \/>\nYou can refer to the <strong>Setup Run Configuration<\/strong> section in this <a href=\"https:\/\/github.com\/codepath\/android_guides\/wiki\/Robolectric-Installation-for-Unit-Testing\">link<\/a> to configure it properly. Here is snapshot of the test run configuration for our test project.<br \/>\n<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_run.png\" data-rel=\"lightbox-image-5\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_run-300x229.png\" alt=\"Robolectric_run\" width=\"300\" height=\"229\" class=\"aligncenter size-medium wp-image-2036\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_run-300x229.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_run.png 836w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><strong>5. Running the test<\/strong><br \/>\nSelect the Run configuration which you created, run the test and verify the JUnit test result.<br \/>\n<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_result.png\" data-rel=\"lightbox-image-6\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_result-300x168.png\" alt=\"Robolectric_result\" width=\"300\" height=\"168\" class=\"aligncenter size-medium wp-image-2037\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_result-300x168.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_result-1024x575.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2014\/11\/Robolectric_result.png 1366w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<hr>\n<p>There you go. Android unit testing is not rocket science.<\/p>\n<hr>\n<script>(function() {\n\twindow.mc4wp = window.mc4wp || {\n\t\tlisteners: [],\n\t\tforms: {\n\t\t\ton: function(evt, cb) {\n\t\t\t\twindow.mc4wp.listeners.push(\n\t\t\t\t\t{\n\t\t\t\t\t\tevent   : evt,\n\t\t\t\t\t\tcallback: cb\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n})();\n<\/script><!-- Mailchimp for WordPress v4.10.1 - https:\/\/wordpress.org\/plugins\/mailchimp-for-wp\/ --><form id=\"mc4wp-form-1\" class=\"mc4wp-form mc4wp-form-6165 mc4wp-form-theme mc4wp-form-theme-blue\" method=\"post\" data-id=\"6165\" data-name=\"Newsletter\" ><div class=\"mc4wp-form-fields\"><div style=\"border:3px; border-style:dashed;border-color:#56d1e1;padding:1.2em;\">\r\n  <h1 style=\"text-align: center; padding-top: 20px; padding-bottom: 20px; color: #592b1b;\">Subscribe to our weekly Newsletter<\/h1>\r\n  <input style=\"margin: auto;\" type=\"email\" name=\"EMAIL\" placeholder=\"Your email address\" required \/>\r\n  <br>\r\n  <p style=\"text-align: center;\">\r\n    <input style=\"background-color: #890c06 !important; border-color: #890c06;\" type=\"submit\" value=\"Sign up\" \/>\r\n    \r\n  <\/p>\r\n  <p style=\"text-align: center;\">\r\n    <a href=\"http:\/\/mailchi.mp\/c9c7b81ddf13\/the-informed-testers-newsletter-20-oct-2017\"><small>View a sample<\/small><\/a>\r\n  <\/p>\r\n  <br>\r\n<\/div><\/div><label style=\"display: none !important;\">Leave this field empty if you're human: <input type=\"text\" name=\"_mc4wp_honeypot\" value=\"\" tabindex=\"-1\" autocomplete=\"off\" \/><\/label><input type=\"hidden\" name=\"_mc4wp_timestamp\" value=\"1777138848\" \/><input type=\"hidden\" name=\"_mc4wp_form_id\" value=\"6165\" \/><input type=\"hidden\" name=\"_mc4wp_form_element_id\" value=\"mc4wp-form-1\" \/><div class=\"mc4wp-response\"><\/div><\/form><!-- \/ Mailchimp for WordPress Plugin -->\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>Problem: There are not many good tutorials on Android unit testing Android applications are written in Java. So you probably think if you know JUnit, you can unit test Android applications. Surprise! JUnit is not sufficient for unit testing Android applications. Junit works when the code runs within a JVM. Android applications interact with the Android OS. So you need [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[48,38,15,54,47,71,61,66],"tags":[],"class_list":["post-2024","post","type-post","status-publish","format-standard","hentry","category-android","category-automation","category-how-to","category-junit","category-mobile","category-mobile-automation","category-testing","category-unit-testing"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/2024","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=2024"}],"version-history":[{"count":57,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/2024\/revisions"}],"predecessor-version":[{"id":6234,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/2024\/revisions\/6234"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=2024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=2024"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=2024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}