summaryrefslogtreecommitdiffstats
path: root/docs/html/training/testing/ui-testing/uiautomator-testing.jd
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/training/testing/ui-testing/uiautomator-testing.jd')
-rw-r--r--docs/html/training/testing/ui-testing/uiautomator-testing.jd520
1 files changed, 520 insertions, 0 deletions
diff --git a/docs/html/training/testing/ui-testing/uiautomator-testing.jd b/docs/html/training/testing/ui-testing/uiautomator-testing.jd
new file mode 100644
index 0000000..e314b70
--- /dev/null
+++ b/docs/html/training/testing/ui-testing/uiautomator-testing.jd
@@ -0,0 +1,520 @@
+page.title=Testing UI for Multiple Apps
+page.tags=testing,ui automator
+trainingnavtop=true
+
+@jd:body
+
+<!-- This is the training bar -->
+<div id="tb-wrapper">
+<div id="tb">
+ <h2>Dependencies and Prerequisites</h2>
+
+ <ul>
+ <li>Android 4.3 (API level 18) or higher</li>
+ <li><a href="{@docRoot}tools/testing-support-library/index.html">
+ Android Testing Support Library</a></li>
+ </ul>
+
+ <h2>This lesson teaches you to</h2>
+
+ <ol>
+ <li><a href="#setup">Set Up UI Automator</a></li>
+ <li><a href="#build">Create a UI Automator Test Class</a></li>
+ <li><a href="#run">Run UI Automator Tests on a Device or Emulator</a></li>
+ </ol>
+
+ <h2>You should also read</h2>
+
+ <ul>
+ <li><a href="{@docRoot}reference/android/support/test/package-summary.html">
+UI Automator API Reference</a></li>
+ </ul>
+
+ <h2>Try it out</h2>
+
+ <ul>
+ <li><a href="https://github.com/googlesamples/android-testing"
+class="external-link">UI Automator Code Samples</a></li>
+ </ul>
+</div>
+</div>
+
+<p>A user interface (UI) test that involves user interactions across multiple apps lets you
+verify that your app behaves correctly when the user flow crosses into other apps or into the
+system UI. An example of such a user flow is a messaging app that lets the user enter a text
+message, launches the Android contact picker so that the users can select recipients to send the
+message to, and then returns control to the original app for the user to submit the message.</p>
+
+<p>This lesson covers how to write such UI tests using the
+UI Automator testing framework provided by the
+<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
+The UI Automator APIs let you interact with visible elements on a device, regardless of
+which {@link android.app.Activity} is in focus. Your test can look up a UI component by using
+convenient descriptors such as the text displayed in that component or its content description. UI
+Automator tests can run on devices running Android 4.3 (API level 18) or higher.</p>
+
+<p>The UI Automator testing framework is an instrumentation-based API and works
+with the
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">
+ {@code AndroidJUnitRunner}</a>
+test runner.
+</p>
+
+<h2 id="setup">Set Up UI Automator</h2>
+<p>Before you begin using UI Automator, you must:</p>
+
+ <ul>
+ <li>
+ <strong>Install the Android Testing Support Library</strong>. The UI Automator API is
+ located under the {@code com.android.support.test.uiautomator} package. These classes allow
+ you to create tests that use the Espresso testing framework. To learn how to install the
+ library, see <a href="{@docRoot}tools/testing-support-library/index.html#setup">
+ Testing Support Library Setup</a>.
+ </li>
+
+ <li>
+ <strong>Set up your project structure.</strong> In your Gradle project, the source code for
+ the target app that you want to test is typically placed under the {@code app/src/main}
+ folder. The source code for instrumentation tests, including
+ your UI Automator tests, must be placed under the <code>app/src/androidTest</code> folder.
+ To learn more about setting up your project directory, see
+ <a href="{@docRoot}tools/projects/index.html">Managing Projects</a>.
+ </li>
+
+ <li>
+ <strong>Specify your Android testing dependencies</strong>. In order for the
+ <a href="{@docRoot}tools/building/plugin-for-gradle.html">Android Plug-in for Gradle</a> to
+ correctly build and run your UI Automator tests, you must specify the following libraries in
+ the {@code build.gradle} file of your Android app module:
+
+ <pre>
+dependencies {
+ androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
+ androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.0.0'
+}
+</pre>
+ </li>
+ </ul>
+
+<p>To optimize your UI Automator testing, you should first inspect the target app’s UI components
+and ensure that they are accessible. These optimization tips are described in the next two
+sections.</p>
+
+<h3 id="inspecting-ui">Inspecting the UI on a device</h3>
+<p>Before designing your test, inspect the UI components that are visible on the device. To
+ensure that your UI Automator tests can access these components, check that these components
+have visible text labels,
+<a href="http://developer.android.com/reference/android/view/View.html#attr_android:contentDescription">
+{@code android:contentDescription}</a>
+values, or both.</p>
+
+<p>The {@code uiautomatorviewer} tool provides a convenient visual interface to inspect the layout
+hierarchy and view the properties of UI components that are visible on the foreground of the device.
+This information lets you create more fine-grained tests using UI Automator. For example, you can
+create a UI selector that matches a specific visible property. </p>
+
+<p>To launch the {@code uiautomatorviewer} tool:</p>
+
+<ol>
+ <li>Launch the target app on a physical device.</li>
+ <li>Connect the device to your development machine.</li>
+ <li>Open a terminal window and navigate to the {@code &lt;android-sdk&gt;/tools/} directory.</li>
+ <li>Run the tool with this command:
+<pre>$ uiautomatorviewer</pre>
+ </li>
+</ol>
+
+<p>To view the UI properties for your application:</p>
+
+<ol>
+ <li>In the {@code uiautomatorviewer} interface, click the <strong>Device Screenshot</strong>
+button.</li>
+ <li>Hover over the snapshot in the left-hand panel to see the UI components identified by the
+{@code uiautomatorviewertool}. The properties are listed in the lower right-hand panel and the
+layout hierarchy in the upper right-hand panel.</li>
+ <li>Optionally, click on the <strong>Toggle NAF Nodes</strong> button to see UI components that
+are non-accessible to UI Automator. Only limited information may be available for these
+components.</li>
+</ol>
+
+<p>To learn about the common types of UI components provided by Android, see
+<a href="{@docRoot}guide/topics/ui/index.html">User Interface</a>.</p>
+
+<h3>Ensuring your Activity is accessible</h3>
+<p>The UI Automator test framework depends on the accessibility features of the Android framework
+to look up individual UI elements. As a developer, you should implement these minimum
+optimizations in your {@link android.app.Activity} to support UI Automator:</p>
+
+<ul>
+<li>Use the
+<a href="{@docRoot}reference/android/view/View.html#attr_android:contentDescription">
+ {@code android:contentDescription}</a>
+attribute to label the {@link android.widget.ImageButton}, {@link android.widget.ImageView},
+{@link android.widget.CheckBox} and other user interface controls.</li>
+<li>Provide an <a href="{@docRoot}reference/android/widget/TextView.html#attr_android:hint">{@code android:hint}</a>
+attribute instead of a content description for {@link android.widget.EditText} fields.</li>
+<li>Associate an <a href="http://developer.android.com/reference/android/widget/TextView.html#attr_android:hint">
+ {@code android:hint}</a>
+attribute with any graphical icons used by controls that provide feedback to the user
+(for example, status or state information).</li>
+<li>Use the {@code uiautomatorviewer} tool to ensure that the UI component is accessible to the
+testing framework. You can also test the application by turning on accessibility services like
+TalkBack and Explore by Touch, and try using your application using only directional controls.</li>
+</ul>
+
+<p>Generally, app developers get accessibility support for free, courtesy of
+the {@link android.view.View} and {@link android.view.ViewGroup}
+classes. However, some apps use custom view elements to provide a richer user experience. Such
+custom elements won't get the accessibility support that is provided by the standard Android UI
+elements. If this applies to your app, make sure that it exposes the custom-drawn UI element to
+Android accessibility services by implementing the
+{@link android.view.accessibility.AccessibilityNodeProvider} class.</p>
+
+<p>If the custom view element contains a single element, make it accessible by
+<a href="{@docRoot}guide/topics/ui/accessibility/apps.html#accessibility-methods">implementing
+accessibility API methods</a>.
+If the custom view contains elements that are not views themselves (for example, a
+{@link android.webkit.WebView}, make sure it implements the
+{@link android.view.accessibility.AccessibilityNodeProvider} class. For container views that
+extend an existing container implementation
+(for example, a {@link android.widget.ListView}), implementing
+{@link android.view.accessibility.AccessibilityNodeProvider} is not necessary.</p>
+
+<p>For more information about implementing and testing accessibility, see
+<a href="{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications Accessible</a>.</p>
+
+<h2 id="build">Create a UI Automator Test Class</h2>
+
+<p>To build a UI Automator test, create a class that extends
+{@link android.test.InstrumentationTestCase}. Implement the following programming model in your
+UI Automator test class:</p>
+
+<ol>
+<li>Get a
+ <a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a>
+ object to access the device you want to test, by calling the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#getInstance(android.app.Instrumentation)">
+{@code getInstance()}</a>
+method and passing it an {@link android.app.Instrumentation} object as the argument.</li>
+<li>Get a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>
+object to access a UI component that is displayed on the device
+ (for example, the current view in the foreground), by calling the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#findObject(android.support.test.uiautomator.UiSelector)">
+ {@code findObject()}</a>
+method.
+</li>
+<li>Simulate a specific user interaction to perform on that UI component, by calling a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>
+method; for example, call
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#performMultiPointerGesture(android.view.MotionEvent.PointerCoords[]...)">
+ {@code performMultiPointerGesture()}</a>
+to simulate a multi-touch gesture, and
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#setText(java.lang.String)">{@code setText()}</a>
+to edit a text field. You can call on the APIs in steps 2 and 3 repeatedly as necessary to test
+more complex user interactions that involve multiple UI components or sequences of user actions.</li>
+<li>Check that the UI reflects the expected state or behavior, after these user interactions are
+ performed. </li>
+</ol>
+
+<p>These steps are covered in more detail in the sections below.</p>
+
+<h3 id="accessing-ui-components">Accessing UI Components</h3>
+<p>The
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a>
+ object is the primary way you access and manipulate the state of the
+device. In your tests, you can call
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a>
+methods to check for the state of various properties, such as current orientation or display size.
+Your test can use the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a>
+object to perform device-level actions, such as forcing the device into a specific rotation,
+pressing D-pad hardware buttons, and pressing the Home and Menu buttons.</p>
+
+<p>It’s good practice to start your test from the Home screen of the device. From the Home screen
+(or some other starting location you’ve chosen in the device), you can call the methods provided by
+the UI Automator API to select and interact with specific UI elements. </p>
+
+<p>The following code snippet shows how your test might get an instance of
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html">{@code UiDevice}</a>
+and simulate a Home button press:</p>
+
+<pre>
+import android.test.InstrumentationTestCase;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.By;
+
+public class CalculatorUiTest extends InstrumentationTestCase {
+
+ private UiDevice mDevice;
+
+ public void setUp() {
+ // Initialize UiDevice instance
+ mDevice = UiDevice.getInstance(getInstrumentation());
+
+ // Start from the home screen
+ mDevice.pressHome();
+ mDevice.wait(Until.hasObject(By.pkg(getHomeScreenPackage()).depth(0)),
+ }
+}
+</pre>
+
+<p>Use the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiDevice.html#findObject(android.support.test.uiautomator.UiSelector)">{@code findObject()}</a>
+method to retrieve a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>
+which represents a view that matches a given selector criteria. You can reuse the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>
+instances that you have created in other parts of your app testing, as needed. Note that the
+UI Automator test framework searches the current display for a match every time your test uses a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>
+instance to click on a UI element or query a property.</p>
+
+<p>The following snippet shows how your test might construct
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>
+instances that represent a Cancel button and a OK button in an app.</p>
+
+<pre>
+UiObject cancelButton = mDevice.findObject(new UiSelector()
+ .text("Cancel"))
+ .className("android.widget.Button"));
+UiObject okButton = mDevice.findObject(new UiSelector()
+ .text("OK"))
+ .className("android.widget.Button"));
+
+// Simulate a user-click on the OK button, if found.
+if(okButton.exists() &#38;&#38; okButton.isEnabled()) {
+ okButton.click();
+}
+</pre>
+
+<h4 id="specifying-selector">Specifying a selector</h4>
+<p>If you want to access a specific UI component in an app, use the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a>
+class. This class represents a query for specific elements in the
+currently displayed UI. </p>
+
+<p>If more than one matching element is found, the first matching element in the layout hierarchy
+is returned as the target
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>.
+When constructing a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a>,
+you can chain together multiple properties to refine your search. If no matching UI element is
+found, a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObjectNotFoundException.html">
+{@code UiAutomatorObjectNotFoundException}</a> is thrown. </p>
+
+<p>You can use the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html#childSelector(android.support.test.uiautomator.UiSelector)">{@code childSelector()}</a>
+method to nest multiple
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a>
+instances. For example, the following code example shows how your test might specify a search to
+find the first {@link android.widget.ListView} in the currently displayed UI, then search within that
+{@link android.widget.ListView} to find a UI element with the text property Apps.</p>
+
+<pre>
+UiObject appItem = new UiObject(new UiSelector()
+ .className("android.widget.ListView")
+ .instance(1)
+ .childSelector(new UiSelector()
+ .text("Apps")));
+</pre>
+
+<p>As a best practice, when specifying a selector, you should use a Resource ID (if one is assigned
+to a UI element) instead of a text element or content-descriptor. Not all elements have a text
+element (for example, icons in a toolbar). Text selectors are brittle and can lead to test failures
+if there are minor changes to the UI. They may also not scale across different languages; your text
+selectors may not match translated strings.</p>
+
+<p>It can be useful to specify the object state in your selector criteria. For example, if you want
+to select a list of all checked elements so that you can uncheck them, call the
+<a href="{@docRoot}reference/android/support/test/uiautomator/By.html#checked(boolean)">
+{@code checked()}</a>
+method with the argument set to {@code true}.</p>
+
+<h3 id="performing-actions">Performing Actions</h3>
+
+<p>Once your test has obtained a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>
+object, you can call the methods in the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>
+class to perform user interactions on the UI component represented by that
+object. You can specify such actions as:</p>
+
+<ul>
+<li>
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#click()">
+ {@code click()}</a>
+: Clicks the center of the visible bounds of the UI element.</li>
+<li>
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#dragTo(int, int, int)">
+ {@code dragTo()}</a>
+: Drags this object to arbitrary coordinates.</li>
+<li>
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#setText(java.lang.String)">
+ {@code setText()}</a>
+: Sets the text in an editable field, after clearing the field's content.
+Conversely, the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#clearTextField()">
+ {@code clearTextField()}</a>
+method clears the existing text in an editable field.</li>
+<li>
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeUp(int)">
+ {@code swipeUp()}</a>
+: Performs the swipe up action on the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html">{@code UiObject}</a>.
+Similarly, the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeDown(int)">
+ {@code swipeDown()}</a>,
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeLeft(int)">
+ {@code swipeLeft()}</a>, and
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiObject.html#swipeRight(int)">
+ {@code swipeRight()}</a>
+methods perform corresponding actions.</li>
+</ul>
+
+<p>The UI Automator testing framework allows you to send an
+{@link android.content.Intent}
+or launch an {@link android.app.Activity}
+without using shell commands, by getting a
+{@link android.content.Context}
+object through
+{@link android.app.Instrumentation#getContext() getContext()}.</p>
+
+<p>The following snippet shows how your test can use an
+{@link android.content.Intent} to launch the app under test. This approach is useful when you are
+only interested in testing the calculator app, and don't care about the launcher.</p>
+
+<pre>
+public void setUp() {
+ ...
+
+ // Launch a simple calculator app
+ Context context = getInstrumentation().getContext();
+ Intent intent = context.getPackageManager()
+ .getLaunchIntentForPackage(CALC_PACKAGE);
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ // Clear out any previous instances
+ context.startActivity(intent);
+ mDevice.wait(Until.hasObject(By.pkg(CALC_PACKAGE).depth(0)), TIMEOUT);
+}
+</pre>
+
+<h4 id="actions-on-collections">Performing actions on collections</h4>
+
+<p>Use the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html">
+ {@code UiCollection}</a>
+class if you want to simulate user interactions on a
+collection of items (for example, songs in a music album or a list of emails in an Inbox). To
+create a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html">
+ {@code UiCollection}</a>
+object, specify a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiSelector.html">{@code UiSelector}</a>
+that searches for a
+UI container or a wrapper of other child UI elements, such as a layout view that contains child UI
+elements.</p>
+
+<p>The following code snippet shows how your test might construct a
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiCollection.html">
+ {@code UiCollection}</a>
+to represent a video album that is displayed within a {@link android.widget.FrameLayout}:</p>
+
+<pre>
+UiCollection videos = new UiCollection(new UiSelector()
+ .className("android.widget.FrameLayout"));
+
+// Retrieve the number of videos in this collection:
+int count = videos.getChildCount(new UiSelector()
+ .className("android.widget.LinearLayout"));
+
+// Find a specific video and simulate a user-click on it
+UiObject video = videos.getChildByText(new UiSelector()
+ .className("android.widget.LinearLayout"), "Cute Baby Laughing");
+video.click();
+
+// Simulate selecting a checkbox that is associated with the video
+UiObject checkBox = video.getChild(new UiSelector()
+ .className("android.widget.Checkbox"));
+if(!checkBox.isSelected()) checkbox.click();
+</pre>
+
+<h4 id="actions-on-scrollable-views">Performing actions on scrollable views</h4>
+<p>Use the
+<a href="{@docRoot}reference/android/support/test/uiautomator/UiScrollable.html">
+ {@code UiScrollable}</a>
+class to simulate vertical or horizontal scrolling across a display. This technique is helpful when
+a UI element is positioned off-screen and you need to scroll to bring it into view.</p>
+
+<p>The following code snippet shows how to simulate scrolling down the Settings menu and clicking
+on an About tablet option:</p>
+
+<pre>
+UiScrollable settingsItem = new UiScrollable(new UiSelector()
+ .className("android.widget.ListView"));
+UiObject about = settingsItem.getChildByText(new UiSelector()
+ .className("android.widget.LinearLayout"), "About tablet");
+about.click();
+</pre>
+
+<h3 id="verifying-results">Verifying Results</h3>
+<p>The {@link android.test.InstrumentationTestCase} extends {@link junit.framework.TestCase}, so
+you can use standard JUnit <a href="http://junit.org/javadoc/latest/org/junit/Assert.html"
+class="external-link">{@code Assert}</a> methods to test
+that UI components in the app return the expected results. </p>
+
+<p>The following snippet shows how your test can locate several buttons in a calculator app, click
+on them in order, then verify that the correct result is displayed.</p>
+
+<pre>
+private static final String CALC_PACKAGE = "com.myexample.calc";
+
+public void testTwoPlusThreeEqualsFive() {
+ // Enter an equation: 2 + 3 = ?
+ mDevice.findObject(new UiSelector()
+ .packageName(CALC_PACKAGE).resourceId("two")).click();
+ mDevice.findObject(new UiSelector()
+ .packageName(CALC_PACKAGE).resourceId("plus")).click();
+ mDevice.findObject(new UiSelector()
+ .packageName(CALC_PACKAGE).resourceId("three")).click();
+ mDevice.findObject(new UiSelector()
+ .packageName(CALC_PACKAGE).resourceId("equals")).click();
+
+ // Verify the result = 5
+ UiObject result = mDevice.findObject(By.res(CALC_PACKAGE, "result"));
+ assertEquals("5", result.getText());
+}
+</pre>
+
+<h2 id="run">Run UI Automator Tests on a Device or Emulator</h2>
+<p>UI Automator tests are based on the {@link android.app.Instrumentation} class. The
+<a href="https://developer.android.com/tools/building/plugin-for-gradle.html">
+ Android Plug-in for Gradle</a>
+provides a default directory ({@code src/androidTest/java}) for you to store the instrumented test
+classes and test suites that you want to run on a device. The plug-in compiles the test
+code in that directory and then executes the test app using a test runner class. You are
+strongly encouraged to use the
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a>
+class provided in the
+<a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>
+as your default test runner. </p>
+
+<p>To run UI Automator tests in your Gradle project:</p>
+
+<ol>
+<li>Specify
+<a href="{@docRoot}reference/android/support/test/runner/AndroidJUnitRunner.html">{@code AndroidJUnitRunner}</a>
+as the default test instrumentation runner in your {@code build.gradle} file:
+<pre>
+android {
+ defaultConfig {
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+}</pre>
+</li>
+<li>Run your tests from the command-line by calling the {@code connectedCheck}
+ (or {@code cC}) task:
+<pre>./gradlew cC</pre>
+</li>
+</ol> \ No newline at end of file