{"id":462,"date":"2020-06-26T11:01:04","date_gmt":"2020-06-26T18:01:04","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/surface-duo\/?p=462"},"modified":"2020-07-13T06:55:58","modified_gmt":"2020-07-13T13:55:58","slug":"surface-duo-testing-tips-tricks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/surface-duo\/surface-duo-testing-tips-tricks\/","title":{"rendered":"Surface Duo testing tips &#038; tricks"},"content":{"rendered":"<p>Hello Microsoft Surface Duo developers,<\/p>\n<p>Today\u2019s post contains some tips to help automate the Surface Duo emulator for testing.<\/p>\n<h2>Use the latest emulator<\/h2>\n<p>Tip number one: install the <a href=\"https:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=100847\">latest emulator from Microsoft Developer Center<\/a> to ensure you have all our latest fixes, feature enhancements, and performance improvements. The Surface Duo emulator preview is available for Windows, macOS, and Linux. See the documentation for <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/get-duo-sdk\">additional setup instructions<\/a>.<\/p>\n<h2>Android emulator drag &amp; drop<\/h2>\n<p>Another simple tip is that you can drag and drop items onto the running Surface Duo emulator! APK files will be installed automatically, and image files will be saved and are accessible from the image gallery. This is useful for easily loading photos onto your emulator for testing.<\/p>\n<h2>Android Debug Bridge (ADB)<\/h2>\n<p>ADB is an important tool for developers because it allows you to interact with Android devices and emulators. The <a href=\"https:\/\/developer.android.com\/studio\/command-line\/adb\">full ADB documentation<\/a> is online but here are some useful commands:<\/p>\n<ul>\n<li><strong>adb kill-server<\/strong> and <strong>adb start-server <\/strong>\u2013 stop and start the ADB service if needed<\/li>\n<li><strong>adb devices<\/strong> \u2013 list the devices available (including emulators and phones or tablets attached to your computer)<\/li>\n<li><strong>adb install<\/strong> \u2013 install APK files<\/li>\n<li><strong>adb shell <\/strong> \u2013 execute commands on the Android system, for example:\n<ul>\n<li><strong>adb shell pm list packages <\/strong> &#8211; list all the packages installed<\/li>\n<li><strong>adb shell pm path com.example.someapp<\/strong> \u2013 gets the file system path of the package specified<\/li>\n<\/ul>\n<\/li>\n<li><strong>adb pull<\/strong> \u2013 extract files from the emulator or device<\/li>\n<\/ul>\n<p>Another use for ADB is simulating input commands, such as automating <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/use-emulator?tabs=java#span-your-app-in-the-emulator\">spanning<\/a> of an app. These screenshots illustrate the process of spanning by grabbing the handle at the bottom of the window, and dragging it towards the hinge until the span indicator covers both screens:<\/p>\n<p><img decoding=\"async\" width=\"1200\" height=\"258\" class=\"wp-image-463\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-13.png\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-13.png 1200w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-13-300x65.png 300w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-13-1024x220.png 1024w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/word-image-13-768x165.png 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/p>\n<p>You can simulate this gesture with ADB, using the following command:<\/p>\n<pre>adb shell input touchscreen swipe 675 1780 1350 1500 3000<\/pre>\n<p>The first four values are the start and end coordinates of the drag gesture, and the final value is elapsed time (ms). The time is important because if you drag too fast, the app is \u201cflung\u201d to the other screen rather than spanned. We found 3 seconds worked well.<\/p>\n<h2>Espresso user interface testing<\/h2>\n<p><a href=\"https:\/\/developer.android.com\/training\/testing\/ui-automator\">UiAutomator<\/a> and <a href=\"https:\/\/developer.android.com\/training\/testing\/espresso\">Espresso<\/a> are both from AndroidX libraries, and can be used together to perform spanning or unspanning actions as part of a user interface test script. UiAutomator can interact with the system and Espresso can be used implement the UI tests. For a Surface Duo test scenario that requires spanning:<\/p>\n<ul>\n<li>Use UiAutomator to do the app swipe-gesture so we are able to span the app.<\/li>\n<li>Use Espresso to test the user interface.<\/li>\n<\/ul>\n<p>Here\u2019s a small test sample, so you can see how it&#8217;s done and what you need:<\/p>\n<pre>import\u202fandroidx.test.espresso.Espresso.onView \r\nimport\u202fandroidx.test.espresso.assertion.ViewAssertions.matches \r\nimport\u202fandroidx.test.espresso.matcher.ViewMatchers.isDisplayed \r\nimport\u202fandroidx.test.espresso.matcher.ViewMatchers.withText \r\nimport\u202fandroidx.test.ext.junit.runners.AndroidJUnit4 \r\nimport\u202fandroidx.test.platform.app.InstrumentationRegistry \r\nimport\u202fandroidx.test.rule.ActivityTestRule \r\nimport\u202fandroidx.test.uiautomator.UiDevice \r\nimport\u202forg.junit.Rule \r\nimport\u202forg.junit.Test \r\nimport\u202forg.junit.runner.RunWith \r\n\r\n@RunWith(AndroidJUnit4::class) \r\nclass\u202fExampleInstrumentedTest\u202f{ \r\n\r\n\u202f\u202f\u202f\u202f@get:Rule \r\n\u202f\u202f\u202f\u202fval\u202factivityRule\u202f=\u202fActivityTestRule(MainActivity::class.java) \r\n\r\n\u202f\u202f\u202f\u202f@Test \r\n\u202f\u202f\u202f\u202ffun\u202fisAppSpanned()\u202f{\r\n\u202f\u202f\u202f\u202f\u202f\u202f\u202f\u202fval\u202fdevice\u202f=\u202fUiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) \r\n\u202f\u202f\u202f\u202f\u202f\u202f\u202f\u202f\/\/ span the app (from the left side) \r\n\u202f\u202f\u202f\u202f\u202f\u202f\u202f\u202fdevice.swipe(675,\u202f1780,\u202f1350,\u202f900, 400) \r\n\u202f\u202f\u202f\u202f\u202f\u202f\u202f\u202f\/\/ unspan the app (back to the left) \r\n\u202f\u202f\u202f\u202f\u202f\u202f\u202f\u202f\/\/ device.swipe(2109, 1780, 675, 900, 200); \r\n\u202f\u202f\u202f\u202f\u202f\u202f\u202f\u202f\/\/ test a UI element \r\n\u202f\u202f\u202f\u202f\u202f\u202f\u202f\u202fonView(withText(\"your-text-to-test\")).check(matches(isDisplayed())) \r\n\u202f\u202f\u202f\u202f} \r\n}<\/pre>\n<p>UiAutomator performs the <a href=\"https:\/\/developer.android.com\/reference\/androidx\/test\/uiautomator\/UiDevice#swipe\">swipe<\/a> gesture to move the app\u2019s handle towards the hinge. The last parameter step\u00a0determines how long the gesture takes, and like the ADB equivalent, if the gesture is too fast, the app gets \u2018flung\u2019 rather than spanned.<\/p>\n<p>In our tests on the emulator and on the device, steps = 400 that is more or less 2 seconds, is working fine. Give it a try, if it doesn&#8217;t work perfectly for you try to adjust it a bit.<\/p>\n<p>Remember as well to <a href=\"https:\/\/developer.android.com\/training\/testing\/espresso\/setup#set-up-environment\" target=\"_blank\" rel=\"noopener noreferrer\">disable animations when running ui tests.<\/a><\/p>\n<p>We also recommend you do the gesture just once and then do all tests that need the spanned configuration, which is more reliable than doing multiple spanning and unspanning requests.<\/p>\n<h2>Hinge angle<\/h2>\n<p>If you\u2019re following our docs to <a href=\"https:\/\/docs.microsoft.com\/dual-screen\/android\/api-reference\/hinge-sensor?tabs=java\">react to the hinge sensor<\/a> changing, we currently have a solution in place to simulate that. In the Extended controls window, choose <strong>Virtual Sensors &gt; Additional sensors<\/strong> and slide the <strong>Pressure<\/strong> control between 0 and 360.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-470\" src=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/pressure-hinge-sensor-500.png\" alt=\"Image pressure used for hinge sensor\" width=\"500\" height=\"379\" srcset=\"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/pressure-hinge-sensor-500.png 500w, https:\/\/devblogs.microsoft.com\/surface-duo\/wp-content\/uploads\/sites\/53\/2020\/06\/pressure-hinge-sensor-500-300x227.png 300w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>We look forward to offering dedicated controls for dual-screen functionality in the future.<\/p>\n<h2>Camera<\/h2>\n<p>Today\u2019s final tip is from <a href=\"https:\/\/docs.microsoft.com\/en-us\/dual-screen\/android\/use-emulator?tabs=java#use-the-camera\">our docs<\/a>: configuring the Surface Duo emulator\u2019s camera. By default, the emulator uses an \u201cemulated\u201d camera image, which looks a bit cartoonish. Instead you can configure the emulator to pass through a camera attached to your computer, by first running this command to get a list of available cameras:<\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>Windows<\/strong><\/td>\n<td>%LOCALAPPDATA%\\Android\\Sdk\\emulator\\emulator -webcam-list<\/td>\n<\/tr>\n<tr>\n<td><strong>Mac<\/strong><\/td>\n<td>~\/Library\/Android\/sdk\/emulator\/emulator -webcam-list<\/td>\n<\/tr>\n<tr>\n<td><strong>Linux<\/strong><\/td>\n<td>~\/Android\/Sdk\/emulator\/emulator -webcam-list<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Review the output for entries like this: Camera &#8216;webcam0&#8217; is connected to device\u2026. If you have a Surface with multiple cameras, more than one entry will appear (eg. webcam0, webcam1). You can choose which camera (or cameras) to forward to the emulator.<\/p>\n<p>Update the <strong>config.ini<\/strong> file in the emulator\u2019s installation directory, adding the following lines:<\/p>\n<pre>hw.camera.back=virtualscene\r\nhw.camera.front=webcam0<\/pre>\n<p>Now when you restart the emulator and open the <strong>Camera<\/strong> app you should see yourself (or whatever the camera is pointing at). The <strong>virtualscene<\/strong> option shows a more realistic view than the emulated default, which might also be helpful for testing your apps.<\/p>\n<h2>Feedback<\/h2>\n<p>I hope these tips are useful and help you build and test high quality dual-screen apps.<\/p>\n<p>We\u2019d love to hear from you! Please leave us feedback or just share your testing tips using our <a href=\"http:\/\/aka.ms\/SurfaceDuoSDK-Feedback\">feedback forum<\/a>, or message me on <a href=\"https:\/\/twitter.com\/CesarValiente\">Twitter<\/a> or <a href=\"https:\/\/github.com\/CesarValiente\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hello Microsoft Surface Duo developers, Today\u2019s post contains some tips to help automate the Surface Duo emulator for testing. Use the latest emulator Tip number one: install the latest emulator from Microsoft Developer Center to ensure you have all our latest fixes, feature enhancements, and performance improvements. The Surface Duo emulator preview is available for [&hellip;]<\/p>\n","protected":false},"author":30297,"featured_media":473,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[365,46,571],"class_list":["post-462","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-surface-duo-sdk","tag-android-developer","tag-surface-duo","tag-testing"],"acf":[],"blog_post_summary":"<p>Hello Microsoft Surface Duo developers, Today\u2019s post contains some tips to help automate the Surface Duo emulator for testing. Use the latest emulator Tip number one: install the latest emulator from Microsoft Developer Center to ensure you have all our latest fixes, feature enhancements, and performance improvements. The Surface Duo emulator preview is available for [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/462","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/users\/30297"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/comments?post=462"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/posts\/462\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media\/473"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/media?parent=462"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/categories?post=462"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/surface-duo\/wp-json\/wp\/v2\/tags?post=462"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}