Android Espresso UI Testing Notes
There isn't much in official Google Android documentation. You'll have to play with a github sample to figure out how to apply it to your project.
for testing intents
http://collectiveidea.com/blog/archives/2015/06/11/testing-for-android-intents-using-espresso/
Good presentation by chiuki github
http://chiuki.github.io/advanced-android-espresso/#/
Walkthrough Working Sample Project
This github has a working espresso project
https://github.com/googlesamples/android-testing
Only the top level has a "download ZIP button", but sometimes the zip file has no files in it, only directory so use the git clone function (see below)
activity_show_text.xml
Screens comes up ready to type. Type something. Hit the down arrow at the bottom to exit keyboard and leave text in the blank.
To run the app: in the run menu you can pick whether to run the app, or one of the available tests
Connect the device. You'll need to
Creating project, there are two directories for the app and for tests (AndroidTest)
java
com.example.ahu.espressofirst
MainActivity
com.example.ahu.espressofirst (androidTest)
ApplicationTest
Developing Android unit and instrumentation tests - Tutorial
www.vogella.com/tutorials/AndroidTesting/article.html
Sep 9, 2015 - Links are provides for other test frameworks like Espresso. ... Instrumented tests for testing Java classes which use the Android API. 5. Androidproject structure and test folder creation ... The Android test system has been updated to be based on JUnit 4 and you can run unit tests either on the Java virtual ...
JUnit4 Rules with the ATSL - Google
https://google.github.io/android-testing-support-library/docs/rules/
Android Testing Support Library we are providing a set of JUnit rules to be used with ... are deprecated in favor of ActivityTestRule or ServiceTestRule .
There isn't much in official Google Android documentation. You'll have to play with a github sample to figure out how to apply it to your project.
for testing intents
http://collectiveidea.com/blog/archives/2015/06/11/testing-for-android-intents-using-espresso/
Good presentation by chiuki github
http://chiuki.github.io/advanced-android-espresso/#/
Espresso(Google)
Use Espresso to write concise, beautiful, and reliable Android UI tests like this:
which leads you here: https://google.github.io/android-testing-support-library/docs/espresso/index.html
Set up instructions
https://google.github.io/android-testing-support-library/docs/espresso/setup/index.html
Download Espresso
- Make sure you have installed the latest Android Support Repository under Extras (see instructions).
- Open your app’s
build.gradle
file. This is usually not the top-levelbuild.gradle
file butapp/build.gradle
. - Add the following lines inside dependencies:
- See the downloads section for more artifacts (espresso-contrib, espresso-web, etc.)
Set the instrumentation runner
- Add to the same build.gradle file the following line in
android.defaultConfig
:
Example build.gradle file
Analytics
In order to make sure we are on the right track with each new release, the test runner collects analytics. More specifically, it uploads a hash of the package name of the application under test for each invocation. This allows us to measure both the count of unique packages using Espresso as well as the volume of usage.
If you do not wish to upload this data, you can opt out by passing the following argument to the test runner:
disableAnalytics "true"
(see how to pass custom arguments).Add the first test
Android Studio creates tests by default in
src/androidTest/java/com.example.package/
Example JUnit4 test using Rules:
(But this doesn't tell how to do an espresso test, see github example below, nor how or where to create test class .java file for each activity class)
Running tests
In Android Studio
Create a test configuration
In Android Studio:
- Open Run menu -> Edit Configurations
- Add a new Android Tests configuration
- Choose a module
- Add a specific instrumentation runner:
Espresso Basics - how to tell Espresso to find a View
Cheat sheet: https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/index.html
- Finding a view with onView
- Performing an action on a view
- Checking if a view fulfills an assertion
- Get started with a simple test using onView
- Using onData with
AdapterView
controls (ListView
,GridView
, …) - Get started with a simple test using onData
- Debugging
The Espresso API encourages test authors to think in terms of what a user might do while interacting with the application - locating UI elements and interacting with them. At the same time, the framework prevents direct access to activities and views of the application because holding on to these objects and operating on them off the UI thread is a major source of test flakiness. Thus, you will not see methods like getView and getCurrentActivity in the Espresso API. You can still safely operate on views by implementing your own
ViewAction
s and ViewAssertion
s.
Here’s an overview of the main components of Espresso:
- Espresso – Entry point to interactions with views (via
onView
andonData
). Also exposes APIs that are not necessarily tied to any view (e.g.pressBack
). - ViewMatchers – A collection of objects that implement
Matcher<? super View>
interface. You can pass one or more of these to theonView
method to locate a view within the current view hierarchy. - ViewActions – A collection of
ViewAction
s that can be passed to theViewInteraction.perform()
method (for example,click()
). - ViewAssertions – A collection of
ViewAssertion
s that can be passed theViewInteraction.check()
method. Most of the time, you will use the matches assertion, which uses a View matcher to assert the state of the currently selected view. (continues at link)
- Matching a view next to another view
- Matching data using onData and a custom ViewMatcher
- Matching a specific child view of a view
- Matching a view that is a footer/header in a ListView
- Matching a view that is inside an ActionBar
- Asserting that a view is not displayed
- Asserting that a view is not present
- Asserting that a data item is not in an adapter
- Using registerIdlingResource to synchronize with custom resources
- Using a custom failure handler
- Using inRoot to target non-default windows
Cheat sheet: https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/index.html
Walkthrough Working Sample Project
This github has a working espresso project
https://github.com/googlesamples/android-testing
Only the top level has a "download ZIP button", but sometimes the zip file has no files in it, only directory so use the git clone function (see below)
Takes you here
Download the file
Run the file
Gets you here:
Click on the plus +
This is the main activity with two buttons to test.
activity_main.xml - design view
activity_main.xml - design view
Screens comes up ready to type. Type something. Hit the down arrow at the bottom to exit keyboard and leave text in the blank.
Change Text: - changes Hello Espresso to the new text .
Open activity and change text - brings up another activity with the next text in it.
Hit the left triangle to to back to main
Mainactivity.java
/* * Copyright 2015, The Android Open Source Project *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and *
limitations under the License. */
package com.example.android.testing.espresso.BasicSample; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.TextView; /** * An {@link Activity} that gets a text string from the user and
displays it back when the user * clicks on one of the two buttons.
The first one shows it in the same activity and the second *
one opens another activity and displays the message. */
public class MainActivity extends Activity implements View.OnClickListener { // The TextView used to display the message inside the Activity.
private TextView mTextView; // The EditText where the user types the message.
private EditText mEditText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set the listeners for the buttons.
findViewById(R.id.changeTextBt).setOnClickListener(this); findViewById(R.id.activityChangeTextBtn).setOnClickListener(this); mTextView = (TextView) findViewById(R.id.textToBeChanged); mEditText = (EditText) findViewById(R.id.editTextUserInput); } @Override public void onClick(View view) { // Get the text from the EditText view.
final String text = mEditText.getText().toString(); switch (view.getId()) { case R.id.changeTextBt: // First button's interaction: set a text in a text view.
mTextView.setText(text); break; case R.id.activityChangeTextBtn: // Second button's interaction: start an activity and send a message to it.
Intent intent = ShowTextActivity.newStartIntent(this, text); startActivity(intent); break; } } }
The test code is Android View under
com.example.android.testing.espresso.BasicSample(androidTest)
changeTextBehaviorTest.java
changeTextBehaviorTest.java
/* * Copyright 2015, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
package com.example.android.testing.espresso.BasicSample; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith; import android.app.Activity;
import android.support.test.espresso.action.ViewActions;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest; import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText; /** * Basic tests showcasing simple view matchers and actions like {@link ViewMatchers#withId},
* {@link ViewActions#click} and {@link ViewActions#typeText}.
* <p> * Note that there is no need to tell Espresso that a view is in a different {@link Activity}.
*/
@RunWith(AndroidJUnit4.class)@LargeTest public class ChangeTextBehaviorTest { public static final String STRING_TO_BE_TYPED = "Espresso"; /** * A JUnit {@link Rule @Rule} to launch your activity under test. This is a replacement * for {@link ActivityInstrumentationTestCase2}. * <p> * Rules are interceptors which are executed for each test method and will run before * any of your setup code in the {@link Before @Before} method. * <p> * {@link ActivityTestRule} will create and launch of the activity for you and also expose * the activity under test. To get a reference to the activity you can use * the {@link ActivityTestRule#getActivity()} method. */ @Rule
// Main Activity is the class to make tests for
// Each Activity will have a different test class file public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>( MainActivity.class); // this is one of two tests @Test public void changeText_sameActivity() { // Type text and then press the button.
onView(withId(R.id.editTextUserInput)) .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); onView(withId(R.id.changeTextBt)).perform(click()); // Check that the text was changed.
onView(withId(R.id.textToBeChanged)).check(matches(withText(STRING_TO_BE_TYPED))); } @Test public void changeText_newActivity() { // Type text and then press the button.
onView(withId(R.id.editTextUserInput)).perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard()); onView(withId(R.id.activityChangeTextBtn)).perform(click()); // This view is in a different Activity, no need to tell Espresso.
onView(withId(R.id.show_text_view)).check(matches(withText(STRING_TO_BE_TYPED))); }
Build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
applicationId "com.example.android.testing.espresso.BasicSample"
minSdkVersion 10
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
lintOptions {
abortOnError false
}
productFlavors {
}
}
dependencies {
// App dependencies
compile 'com.android.support:support-annotations:23.0.1'
compile 'com.google.guava:guava:18.0'
// Testing-only dependencies
// Force usage of support annotations in the test app, since it is internally used by the runner module.
androidTestCompile 'com.android.support:support-annotations:23.0.1'
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
}
To run the app: in the run menu you can pick whether to run the app, or one of the available tests
Connect the device. You'll need to
- Install generic or specific USB debugging driver onto your pc
- Enable developer options on device - settings, build version, tap until you can be developer
- Developer settings shows up - check enable USB debugging
- Hook up device to PC
Creating project, there are two directories for the app and for tests (AndroidTest)
java
com.example.ahu.espressofirst
MainActivity
com.example.ahu.espressofirst (androidTest)
ApplicationTest
Developing Android unit and instrumentation tests - Tutorial
www.vogella.com/tutorials/AndroidTesting/article.html
Sep 9, 2015 - Links are provides for other test frameworks like Espresso. ... Instrumented tests for testing Java classes which use the Android API. 5. Androidproject structure and test folder creation ... The Android test system has been updated to be based on JUnit 4 and you can run unit tests either on the Java virtual ...
5.1. Android project organization for tests
The preferred way of organizing tests is based on a convention. In your application project you should use the following base folder structure for your code organization, this is also the structure the project wizard creates.
app/src/main/java
- for your source code of your main application buildapp/src/test/java
- for any unit test which can run on the JVMapp/src/androidTest/java
- for any test which should run on an Android device
If you follow this conversion than the Android build system can automatically run the unit tests on the JVM and the Android tests on the Android device.
Warning To make Android Studio aware of your new dependency for unit or instrumentation tests you may have to select Unit Tests or Android Instrumentation Tests from the Build Variant view in Android Studio.
Level 23
http://developer.android.com/reference/android/test/suitebuilder/package-summary.htmlClasses
ActivityInstrumentationTestCase<T extends Activity> | This class was deprecated in API level 3. new tests should be written usingActivityInstrumentationTestCase2 , which provides more options for configuring the Activity under test |
ActivityInstrumentationTestCase2<T extends Activity> | This class provides functional testing of a single activity. |
ActivityTestCase | This is common code used to support Activity test cases. |
ActivityUnitTestCase<T extends Activity> | This class provides isolated testing of a single activity. |
AndroidTestCase | Extend this if you need to access Resources or other things that depend on Activity Context. |
AndroidTestRunner | |
ApplicationTestCase<T extends Application> | This test case provides a framework in which you can test Application classes in a controlled environment. |
InstrumentationTestCase | A test case that has access to Instrumentation . |
InstrumentationTestRunner | An Instrumentation that runs various types of TestCase s against an Android package (application). |
InstrumentationTestSuite | A TestSuite that injects Instrumentation into InstrumentationTestCase before running them. |
IsolatedContext | A mock context which prevents its users from talking to the rest of the device while stubbing enough methods to satify code that tries to talk to other packages. |
LoaderTestCase | A convenience class for testing Loader s. |
MoreAsserts | Contains additional assertion methods not found in JUnit. |
ProviderTestCase<T extends ContentProvider> | This class was deprecated in API level 3. this class extends InstrumentationTestCase but should extend AndroidTestCase. Use ProviderTestCase2, which corrects this problem, instead. |
ProviderTestCase2<T extends ContentProvider> | This test case class provides a framework for testing a single ContentProvider and for testing your app code with an isolated content provider. |
RenamingDelegatingContext | This is a class which delegates to the given context, but performs database and file operations with a renamed database/file name (prefixes default names with a given prefix). |
ServiceTestCase<T extends Service> | This test case provides a framework in which you can test Service classes in a controlled environment. |
SingleLaunchActivityTestCase<T extends Activity> | If you would like to test a single activity with an InstrumentationTestCase , this provides some of the boiler plate to launch and finish the activity in setUp() and tearDown() . |
SyncBaseInstrumentation | If you would like to test sync a single provider with an InstrumentationTestCase , this provides some of the boiler plate in setUp() and tearDown() . |
TouchUtils | Reusable methods for generating touch events. |
ViewAsserts | Some useful assertions about views. |
Level 19
http://cs.szpt.edu.cn/android/reference/android/test/package-summary.html
http://cs.szpt.edu.cn/android/reference/android/test/ActivityInstrumentationTestCase2.html
ActivityInstrumentationTestCase2
extends ActivityTestCase
java.lang.Object | |||||
↳ | junit.framework.Assert | ||||
↳ | junit.framework.TestCase | ||||
↳ | android.test.InstrumentationTestCase | ||||
↳ | android.test.ActivityTestCase | ||||
↳ | android.test.ActivityInstrumentationTestCase2<T extends android.app.Activity> |
Class Overview
This class provides functional testing of a single activity. The activity under test will be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity()) and you will then be able to manipulate your Activity directly.
Other options supported by this test case include:
- You can run any test method on the UI thread (see
UiThreadTest
). - You can inject custom Intents into your Activity (see
setActivityIntent(Intent)
).
This class replaces
ActivityInstrumentationTestCase
, which is deprecated. New tests should be written using this base class.
If you prefer an isolated unit test, see
ActivityUnitTestCase
.
Deprecated ActivityInstrumentationTestCase2
ActivityInstrumentationTestCase2 replaces {@link android.test.ActivityInstrumentationTestCase}, which is deprecated.
ActivityInstrumentationTestCase2 or ServiceTestCase are deprecated in favor of ActivityTestRule or ServiceTestRule.
JUnit4 Rules with the ATSL - Google
https://google.github.io/android-testing-support-library/docs/rules/
Android Testing Support Library we are providing a set of JUnit rules to be used with ... are deprecated in favor of ActivityTestRule or ServiceTestRule .
With the Android Testing Support Library we are providing a set of JUnit rules to be used with the
AndroidJUnitRunner
. JUnit rules provide more flexibility and reduce the boilerplate code required in tests.TestCase
s like ActivityInstrumentationTestCase2
or ServiceTestCase
are deprecated in favor of ActivityTestRule
or ServiceTestRule
.ActivityTestRule
This rule provides functional testing of a single activity. The activity under test will be launched before each test annotated with
@Test
and before any method annotated with @Before
. It will be terminated after the test is completed and all methods annotated with @After
are finished. The Activity under Test can be accessed during your test by calling ActivityTestRule#getActivity()
.
if you're actually going for Espresso 2.1. If that is true, also note that:
TestCases like ActivityInstrumentationTestCase2 or ServiceTestCase are deprecated in favor of ActivityTestRule or ServiceTestRule.
As it can also be seen here or here, the annotations are to be used in the following way: (will adjust your deprecated test class just because I'm nice)
//annotate JUnit4 test classes with
@RunWith(AndroiJunit4.class)
@LargeTest
public class FirstActivityTest {
//use the following annotation and declare an ActivityTestRule for your activity under test
@Rule
public ActivityTestRule<FirstActivity> mActivityRule = new ActivityTestRule(FirstActivity.class);
//use @Before to setup your test fixture
@Before
public void setUp() { ... }
//annotate all test methods with
@Test
public void testHelloWorld() { ... }
//release resources by using
@After
public void tearDown() { ... }
}
No comments:
Post a Comment