{"id":1755,"date":"2015-04-09T02:20:09","date_gmt":"2015-04-09T09:20:09","guid":{"rendered":"http:\/\/wiebe-elsinga.com\/blog\/?p=1755"},"modified":"2015-04-09T02:21:33","modified_gmt":"2015-04-09T09:21:33","slug":"whats-new-in-android-testing","status":"publish","type":"post","link":"http:\/\/wiebe-elsinga.com\/blog\/whats-new-in-android-testing\/","title":{"rendered":"What\u2019s new in Android Testing"},"content":{"rendered":"<div class=\"wpsso-pinterest-pin-it-image\" style=\"display:none !important;\">\n<\/div><!-- .wpsso-pinterest-pin-it-image -->\n\n<p><img loading=\"lazy\" src=\"http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/DroidconIT.jpg\" width=\"4096\" height=\"3040\" class=\"aligncenter size-full wp-image-1779\" data-wp-pid=\"1779\" srcset=\"http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/DroidconIT.jpg 4096w, http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/DroidconIT-300x223.jpg 300w, http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/DroidconIT-1024x760.jpg 1024w, http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/DroidconIT-800x594.jpg 800w\" sizes=\"(max-width: 4096px) 100vw, 4096px\" \/><\/p>\n<p>During Droidcon Italy <a href=\"https:\/\/plus.google.com\/+StephanLinzner\">Stephan Linzner<\/a> from Google explained upcoming features in the <a href=\"https:\/\/developer.android.com\/tools\/support-library\/index.html\">Android Testing Support Library<\/a>. Lets have a closer look at some:<br \/>\n<!--more--><br \/>\n<\/p>\n<h3>Test Filtering<\/h3>\n<p>If you want to suppress a test to run on certain target Api levels, just add the <code class=\"codecolorer bash default\"><span class=\"bash\"><span class=\"sy0\">@<\/span>SdkSuppress<\/span><\/code> annotation.<\/p>\n<div class=\"codecolorer-container java blackboard\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><div class=\"java codecolorer\">@SdkSuppress<span class=\"br0\">&#40;<\/span>minSdkVersion<span class=\"sy0\">=<\/span><span class=\"nu0\">15<\/span><span class=\"br0\">&#41;<\/span><br \/>\n@Test<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> featureWithMinSdk15<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; ...<br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>You can also filter tests to only run on a (physical) device by adding the <code class=\"codecolorer bash default\"><span class=\"bash\"><span class=\"sy0\">@<\/span>RequiresDevice<\/span><\/code> annotation.<\/p>\n<div class=\"codecolorer-container java blackboard\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><div class=\"java codecolorer\">@RequiresDevice<br \/>\n@Test<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> SomeDeviceSpecificFeature<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; ...<br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p><\/p>\n<h3>ActivityTestRule<\/h3>\n<p>Because <code class=\"codecolorer bash default\"><span class=\"bash\">ActivityInstrumentationTestCase2<\/span><\/code> will become deprecated you need to define a <code class=\"codecolorer bash default\"><span class=\"bash\"><span class=\"sy0\">@<\/span>Rule.<\/span><\/code><\/p>\n<blockquote><p>Rules allow very flexible addition or redefinition of the behavior of each test method in a test class<\/p><\/blockquote>\n<div align=\"right\" ><small>https:\/\/github.com\/junit-team\/junit\/wiki\/Rules<\/small><\/div>\n<p>\nSo in your test add a <code class=\"codecolorer bash default\"><span class=\"bash\"><span class=\"sy0\">@<\/span>Rule<\/span><\/code> annotation, and create an <code class=\"codecolorer bash default\"><span class=\"bash\">ActivityTestRule<\/span><\/code> for your Activity<\/p>\n<div class=\"codecolorer-container java blackboard\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><div class=\"java codecolorer\">@RunWith<span class=\"br0\">&#40;<\/span>AndroidJUnit4.<span class=\"kw1\">class<\/span><span class=\"br0\">&#41;<\/span><br \/>\n@LargeTest<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw1\">class<\/span> ChangeTextBehaviorTest <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; ...<br \/>\n<br \/>\n&nbsp; &nbsp; @Rule<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">public<\/span> ActivityTestRule<span class=\"sy0\">&lt;<\/span>MainActivity<span class=\"sy0\">&gt;<\/span> mActivityRule <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> ActivityTestRule<span class=\"sy0\">&lt;&gt;<\/span><span class=\"br0\">&#40;<\/span>MainActivity.<span class=\"kw1\">class<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; @Test<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> changeText_sameActivity<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ Type text and then press the button.<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; onView<span class=\"br0\">&#40;<\/span>withId<span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">editTextUserInput<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">perform<\/span><span class=\"br0\">&#40;<\/span>typeText<span class=\"br0\">&#40;<\/span>STRING_TO_BE_TYPED<span class=\"br0\">&#41;<\/span>, closeSoftKeyboard<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; onView<span class=\"br0\">&#40;<\/span>withId<span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">changeTextBt<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">perform<\/span><span class=\"br0\">&#40;<\/span>click<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"co1\">\/\/ Check that the text was changed.<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; onView<span class=\"br0\">&#40;<\/span>withId<span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">textToBeChanged<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">check<\/span><span class=\"br0\">&#40;<\/span>matches<span class=\"br0\">&#40;<\/span>withText<span class=\"br0\">&#40;<\/span>STRING_TO_BE_TYPED<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Now create your <code class=\"codecolorer bash default\"><span class=\"bash\">ActivityTestRule<\/span><\/code><\/p>\n<div class=\"codecolorer-container java blackboard\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><div class=\"java codecolorer\"><span class=\"kw1\">public<\/span> <span class=\"kw1\">class<\/span> ActivityTestRule<span class=\"sy0\">&lt;<\/span>T <span class=\"kw1\">extends<\/span> Activity<span class=\"sy0\">&gt;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">public<\/span> T getActivity<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">protected<\/span> Intent getActivityIntent<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">protected<\/span> <span class=\"kw4\">void<\/span> beforeActivityLaunched<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">protected<\/span> <span class=\"kw4\">void<\/span> afterActivityFinished<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p><\/p>\n<h3>Espresso-Intents<\/h3>\n<p>Espresso-Intents is like <a href=\"http:\/\/site.mockito.org\/\">Mockito<\/a> but for Intent, basically hermetic inter-app testing.<br \/>\nTo give you an example, lets say in your application when a user presses a &#8220;call&#8221; button, you want to know if the correct data will be send to the <code class=\"codecolorer bash default\"><span class=\"bash\">Intent.ACTION_CALL<\/span><\/code>. <\/p>\n<p><img loading=\"lazy\" src=\"http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/EspressoIntent.png\" alt=\"EspressoIntent\" width=\"1067\" height=\"573\" class=\"aligncenter size-full wp-image-1768\" data-wp-pid=\"1768\" srcset=\"http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/EspressoIntent.png 1067w, http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/EspressoIntent-300x161.png 300w, http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/EspressoIntent-1024x550.png 1024w, http:\/\/wiebe-elsinga.com\/blog\/wp-content\/uploads\/2015\/04\/EspressoIntent-800x430.png 800w\" sizes=\"(max-width: 1067px) 100vw, 1067px\" \/><\/p>\n<p>So first create an <code class=\"codecolorer bash default\"><span class=\"bash\">IntentsTestRule<\/span><\/code> and then verify that the Intent was sent using Espresso-Intents<\/p>\n<div class=\"codecolorer-container java blackboard\" style=\"overflow:auto;white-space:nowrap;width:100%;\"><div class=\"java codecolorer\">@RunWith<span class=\"br0\">&#40;<\/span>AndroidJUnit4.<span class=\"kw1\">class<\/span><span class=\"br0\">&#41;<\/span><br \/>\n@LargeTest<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw1\">class<\/span> DialerActivityTest <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; ...<br \/>\n&nbsp; &nbsp; @Rule<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">public<\/span> IntentsTestRule<span class=\"sy0\">&lt;<\/span>DialerActivity<span class=\"sy0\">&gt;<\/span> mRule <span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> IntentsTestRule<span class=\"sy0\">&lt;&gt;<\/span><span class=\"br0\">&#40;<\/span>DialerActivity.<span class=\"kw1\">class<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; @Test<br \/>\n&nbsp; &nbsp; <span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> typeNumber_ValidInput_InitiatesCall<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; onView<span class=\"br0\">&#40;<\/span>withId<span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">edit_text_caller_number<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">perform<\/span><span class=\"br0\">&#40;<\/span>typeText<span class=\"br0\">&#40;<\/span>VALID_PHONE_NUMBER<span class=\"br0\">&#41;<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; closeSoftKeyboard<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; onView<span class=\"br0\">&#40;<\/span>withId<span class=\"br0\">&#40;<\/span>R.<span class=\"me1\">id<\/span>.<span class=\"me1\">button_call_number<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span>.<span class=\"me1\">perform<\/span><span class=\"br0\">&#40;<\/span>click<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; intended<span class=\"br0\">&#40;<\/span>allOf<span class=\"br0\">&#40;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasAction<span class=\"br0\">&#40;<\/span>is<span class=\"br0\">&#40;<\/span>equalTo<span class=\"br0\">&#40;<\/span>Intent.<span class=\"me1\">ACTION_CALL<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hasData<span class=\"br0\">&#40;<\/span>equalTo<span class=\"br0\">&#40;<\/span>INTENT_DATA_PHONE_NUMBER<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span>,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; toPackage<span class=\"br0\">&#40;<\/span>PACKAGE_ANDROID_DIALER<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p><\/br><br \/>\nSo now you know&#8230;<br \/>\n<br \/>\nAll code can be found in <a href=\"https:\/\/github.com\/googlesamples\/android-testing\">android-testing github<\/a>:<\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/googlesamples\/android-testing\/tree\/master\/espresso\/BasicSample\">ActivityTestRule Sample<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/googlesamples\/android-testing\/tree\/master\/espresso\/IntentsBasicSample\">IntentsBasicSample<\/a><\/li>\n<li><a href=\"\">General Espresso Github samples by Google<\/a><\/li>\n<\/ul>\n<p>\nThanks <a href=\"https:\/\/plus.google.com\/+StephanLinzner\">Stephan Linzner<\/a> for the resources. #HappyTesting<\/p>\n","protected":false},"excerpt":{"rendered":"<p>During Droidcon Italy Stephan Linzner from Google explained upcoming features in the Android Testing Support Library. Lets have a closer look at some:<\/p>\n","protected":false},"author":1,"featured_media":1775,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[133,7],"tags":[154,149,150],"_links":{"self":[{"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/posts\/1755"}],"collection":[{"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/comments?post=1755"}],"version-history":[{"count":0,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/posts\/1755\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/media\/1775"}],"wp:attachment":[{"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/media?parent=1755"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/categories?post=1755"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/wiebe-elsinga.com\/blog\/wp-json\/wp\/v2\/tags?post=1755"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}