blob: c9422a551c9587d855300b48f3744f56eb92d86b [file] [log] [blame] [view]
Alexander Dorokhinea113c042016-12-05 15:07:55 -08001# Espresso Snippet Example
2
Alexander Dorokhine0f203a52017-05-24 16:23:47 -07003This tutorial shows you how to create snippets that automate the UI of another
4app using Espresso.
Alexander Dorokhinea113c042016-12-05 15:07:55 -08005
David T.H. Kaoa6f42522017-08-15 21:52:46 -07006The same approach can be used to create any snippet app that needs to access
7the classes or resources of any other single app.
Alexander Dorokhinea113c042016-12-05 15:07:55 -08008
9## Overview
10
11To build a snippet that instruments another app, you have to create a new
12[product flavor](https://developer.android.com/studio/build/build-variants.html#product-flavors)
13of your existing app with the snippet code built in.
14
15The snippet code cannot run from a regular test apk because it requires a custom
16`testInstrumentationRunner`.
17
18## Tutorial
19
201. In the `build.gradle` file of your existing app, create a new product flavor called `snippet`.
21
22 ```
23 android {
24 defaultConfig { ... }
25 productFlavors {
26 main {}
27 snippet {}
28 }
29 }
30 ```
31
321. Link against Mobly Snippet Lib in your `build.gradle` file
33
34 ```
35 dependencies {
Xianyuan Jia1a6913a2021-09-23 14:37:22 -070036 snippetCompile 'com.google.android.mobly:mobly-snippet-lib:1.3.1'
Alexander Dorokhinea113c042016-12-05 15:07:55 -080037 }
38 ```
39
401. Create a new source tree called `src/snippet` where you will place the
41 snippet code.
42
431. In Android Studio, use the `Build Variants` tab in the left hand pane to
44 switch to the snippetDebug build variant. This will let you edit code in the
45 new tree.
46
471. Write your snippet code in a new class under `src/snippet/java`
48
49 ```java
50 package com.my.app;
51 ...
52 public class EspressoSnippet implements Snippet {
Alexander Dorokhine0f203a52017-05-24 16:23:47 -070053 @Rpc(description="Pushes the main app button.")
54 public void pushMainButton() {
Alexander Dorokhinea113c042016-12-05 15:07:55 -080055 onView(withId(R.id.main_button)).perform(click());
56 }
57
58 @Override
59 public void shutdown() {}
60 }
61 ```
62
631. Create `src/snippet/AndroidManifest.xml` containing an `<instrument>` block
64 and any classes that implement the `Snippet` interface in `meta-data`
65
66 ```xml
67 <?xml version="1.0" encoding="utf-8"?>
68 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
69 <application>
70 <meta-data
71 android:name="mobly-snippets"
72 android:value="com.my.app.EspressoSnippet" />
73 </application>
74
75 <instrumentation
76 android:name="com.google.android.mobly.snippet.SnippetRunner"
77 android:targetPackage="com.my.app" />
78 </manifest>
79 ```
80
811. Build your apk by invoking the new `assembleSnippetDebug` target.
82
831. Install the apk on your phone. You do not need to install the main app's
84 apk; the snippet-enabled apk is a complete replacement for your app.
85
861. In your Mobly python test, connect to your snippet .apk in `setup_class`
87
88 ```python
89 class HelloWorldTest(base_test.BaseTestClass):
90 def setup_class(self):
91 self.ads = self.register_controller(android_device)
92 self.dut1 = self.ads[0]
93 self.dut1.load_snippet(name='snippet', package='com.my.app')
94 ```
95
966. Invoke your needed functionality within your test
97
98 ```python
99 def test_click_button(self):
Jeremy Klein2c96b102017-08-21 18:32:48 -0700100 self.dut1.snippet.pushMainButton()
Alexander Dorokhinea113c042016-12-05 15:07:55 -0800101 ```
102
103## Running the example code
104
105This folder contains a fully working example of a snippet apk that uses espresso
106to automate a simple app.
107
1081. Compile the example
109
adorokhine787e6a72017-01-10 18:19:50 -0800110 ./gradlew examples:ex2_espresso:assembleSnippetDebug
Alexander Dorokhinea113c042016-12-05 15:07:55 -0800111
1121. Install the apk on your phone
113
Ang Li6486fbb2019-01-28 21:33:17 -0800114 adb install -r ./examples/ex2_espresso/build/outputs/apk/snippet/debug/ex2_espresso-snippet-debug.apk
Alexander Dorokhinea113c042016-12-05 15:07:55 -0800115
Alexander Dorokhine0f203a52017-05-24 16:23:47 -07001161. Use `snippet_shell` from mobly to trigger `pushMainButton()`:
adorokhinea37aeec2017-01-10 22:34:15 -0800117
118 snippet_shell.py com.google.android.mobly.snippet.example2
119
120 >>> print(s.help())
121 Known methods:
Alexander Dorokhine0f203a52017-05-24 16:23:47 -0700122 pushMainButton(boolean) returns void // Pushes the main app button, and checks the label if this is the first time.
adorokhinea37aeec2017-01-10 22:34:15 -0800123 startMainActivity() returns void // Opens the main activity of the app
124
125 >>> s.startMainActivity()
Alexander Dorokhine0f203a52017-05-24 16:23:47 -0700126 >>> s.pushMainButton(True)
127
1281. Press ctrl+d to exit the shell and terminate the app.