Android
एस्प्रेसो के साथ यूआई का परीक्षण
खोज…
टिप्पणियों
एस्प्रेसो
एस्प्रेसो चीट शीट आपको अपने परीक्षण लिखने में मदद करेगी और आप क्या परीक्षण करना चाहते हैं:
https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/
हमेशा संदर्भ के लिए एक अच्छी जगह आधिकारिक दस्तावेज है:
https://google.github.io/android-testing-support-library/docs/espresso/index.html
Google द्वारा उन्नत एस्प्रेसो वीडियो सुझाव: https://www.youtube.com/watch?v=isihPOY2vS4
समस्या निवारण
- स्क्रॉल करने का प्रयास करते समय, पहले कीबोर्ड को बंद करना सुनिश्चित करें:
वॉचआउट: "एस्प्रेसो" संस्करण का उपयोग नहीं करने पर व्यूएशन के बाहर उपयोग किए जाने पर कुछ भी नहीं होगा। यह स्पष्ट नहीं हो सकता है यदि आपके पास ViewAction संस्करण पर आयात किया गया है क्योंकि उनके पास समान विधि नाम है।
ViewActions.closeSoftKeyboard;
Espresso.closeSoftKeyboard();
- व्यक्तिगत रूप से एक सूट में एक साथ परीक्षण चलाते समय, ध्यान रखें कि पिछले परीक्षण की गतिविधि अभी भी चल रही हो सकती है। वर्तमान परीक्षण onResume () से पहले बुलाए जाने वाले पिछले परीक्षण के onDestroy () पर भरोसा न करें। यह पता चला है कि यह वास्तव में एक बग है : http://b.android.com/201513
एस्प्रेसो सेट करें
अपने Android एप्लिकेशन मॉड्यूल की build.gradle
. build.gradle
फ़ाइल में अगली निर्भरताएँ जोड़ें:
dependencies {
// Android JUnit Runner
androidTestCompile 'com.android.support.test:runner:0.5'
// JUnit4 Rules
androidTestCompile 'com.android.support.test:rules:0.5'
// Espresso core
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
// Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2'
//UI Automator tests
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.2.2'
}
AndroidJUnitRunner
को testInstrumentationRunner
पैरामीटर के लिए build.gradle
फ़ाइल में निर्दिष्ट करें।
android {
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}
इसके अतिरिक्त, इरादे का समर्थन करने के लिए यह निर्भरता जोड़ें
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'
और इसे वेबव्यू परीक्षण समर्थन के लिए जोड़ें
// Espresso-web for WebView support
androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2.2'
एस्प्रेसो टेस्ट क्लास बनाएं
अगले java class को src / androidTest / java में रखें और इसे चलाएं।
public class UITest {
@Test public void Simple_Test() {
onView(withId(R.id.my_view)) // withId(R.id.my_view) is a ViewMatcher
.perform(click()) // click() is a ViewAction
.check(matches(isDisplayed())); // matches(isDisplayed()) is a ViewAssertion
}
}
ओपन ड्राअरलेयरआउट
public final class DrawerLayoutTest {
@Test public void Open_Close_Drawer_Layout() {
onView(withId(R.id.drawer_layout)).perform(actionOpenDrawer());
onView(withId(R.id.drawer_layout)).perform(actionCloseDrawer());
}
public static ViewAction actionOpenDrawer() {
return new ViewAction() {
@Override public Matcher<View> getConstraints() {
return isAssignableFrom(DrawerLayout.class);
}
@Override public String getDescription() {
return "open drawer";
}
@Override public void perform(UiController uiController, View view) {
((DrawerLayout) view).openDrawer(GravityCompat.START);
}
};
}
public static ViewAction actionCloseDrawer() {
return new ViewAction() {
@Override public Matcher<View> getConstraints() {
return isAssignableFrom(DrawerLayout.class);
}
@Override public String getDescription() {
return "close drawer";
}
@Override public void perform(UiController uiController, View view) {
((DrawerLayout) view).closeDrawer(GravityCompat.START);
}
};
}
}
एस्प्रेसो सरल यूआई परीक्षण
UI परीक्षण उपकरण
दो मुख्य उपकरण जो आजकल ज्यादातर यूआई परीक्षण के लिए उपयोग किए जाते हैं वे हैं एपियम और एस्प्रेसो।
Appium | एस्प्रेसो |
---|---|
ब्लैकबॉक्स परीक्षण | सफेद / ग्रे बॉक्स परीक्षण |
आप जो देखते हैं वही आप परख सकते हैं | एप्लिकेशन के आंतरिक कामकाज को बदल सकते हैं और परीक्षण के लिए तैयार कर सकते हैं, उदाहरण के लिए परीक्षण चलाने से पहले डेटाबेस या साझाकरण के लिए कुछ डेटा सहेजें |
ज्यादातर परीक्षण और अंत उपयोगकर्ता प्रवाह के लिए एकीकरण अंत के लिए उपयोग किया जाता है | एक स्क्रीन और / या प्रवाह की कार्यक्षमता का परीक्षण |
लिखा जा सकता है तो परीक्षण iOS और Android पर निष्पादित किया जा सकता है | Android केवल |
अच्छी तरह से समर्थित | अच्छी तरह से समर्थित |
सेलेनियम ग्रिड के साथ कई उपकरणों पर समानांतर परीक्षण का समर्थन करता है | बॉक्स समानांतर परीक्षण से बाहर नहीं है, स्पून जैसे प्लगइन्स मौजूद हैं जब तक कि सच्चा Google समर्थन नहीं आता है |
एस्प्रेसो को प्रोजेक्ट में कैसे जोड़ा जाए
dependencies {
// Set this dependency so you can use Android JUnit Runner
androidTestCompile 'com.android.support.test:runner:0.5'
// Set this dependency to use JUnit 4 rules
androidTestCompile 'com.android.support.test:rules:0.5'
// Set this dependency to build and run Espresso tests
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
// Set this dependency to build and run UI Automator tests
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.2.2'
}
नोट यदि आप नवीनतम समर्थन लाइब्रेरी, एनोटेशन आदि का उपयोग कर रहे हैं, तो आपको टकराव से बचने के लिए पुराने संस्करणों को एस्प्रेसो से बाहर करने की आवश्यकता है:
// there is a conflict with the test support library (see http://stackoverflow.com/questions/29857695)
// so for now re exclude the support-annotations dependency from here to avoid clashes
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
exclude group: 'com.android.support', module: 'support-annotations'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
exclude module: 'support-v4'
exclude module: 'support-v7'
}
// exclude a couple of more modules here because of <http://stackoverflow.com/questions/29216327> and
// more specifically of <https://code.google.com/p/android-test-kit/issues/detail?id=139>
// otherwise you'll receive weird crashes on devices and dex exceptions on emulators
// Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
exclude group: 'com.android.support', module: 'support-annotations'
exclude group: 'com.android.support', module: 'design'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
exclude module: 'support-v4'
exclude module: 'support-v7'
}
//excluded specific packages due to https://code.google.com/p/android/issues/detail?id=183454
androidTestCompile('com.android.support.test.espresso:espresso-intents:2.2.2') {
exclude group: 'com.android.support', module: 'support-annotations'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
exclude module: 'support-v4'
exclude module: 'support-v7'
}
androidTestCompile('com.android.support.test.espresso:espresso-web:2.2.2') {
exclude group: 'com.android.support', module: 'support-annotations'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
exclude module: 'support-v4'
exclude module: 'support-v7'
}
androidTestCompile('com.android.support.test:runner:0.5') {
exclude group: 'com.android.support', module: 'support-annotations'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
exclude module: 'support-v4'
exclude module: 'support-v7'
}
androidTestCompile('com.android.support.test:rules:0.5') {
exclude group: 'com.android.support', module: 'support-annotations'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
exclude module: 'support-v4'
exclude module: 'support-v7'
}
इन आयातों के अलावा अन्य निर्माण के लिए android इंस्ट्रूमेंटेशन टेस्ट रनर को जोड़ना आवश्यक है। android.defaultConfig:
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
डिवाइस सेटअप
गैर परतदार परीक्षण के लिए अपने उपकरणों पर निम्न सेटिंग्स सेट करने की सिफारिश की जाती है:
- डेवलपर विकल्प / अक्षम एनिमेशन - परीक्षणों की परतदारता को कम करता है
- डेवलपर विकल्प / रुकें - यदि आपके पास परीक्षणों के लिए समर्पित उपकरण हैं तो यह उपयोगी है
- डेवलपर विकल्प / लकड़हारा बफर आकार - यदि आप अपने फोन पर बहुत बड़े परीक्षण सूट चलाते हैं तो उच्च संख्या पर सेट करें
- एक्सेसिबिलिटी / टच एंड होल्ड देरी - एस्प्रेसो में टैपिंग की समस्याओं से बचने के लिए लंबे समय तक
वास्तविक दुनिया हा से एक सेटअप काफी है? खैर अब जब कि रास्ते से बाहर thats कैसे एक छोटे से परीक्षण सेटअप करने के लिए एक नज़र रखना
परीक्षण लिखना
मान लेते हैं कि हमारे पास निम्न स्क्रीन है: स्क्रीन में शामिल हैं:
- पाठ इनपुट फ़ील्ड - R.id.textEntry
- बटन जो क्लिक किए जाने पर टाइप किए गए टेक्स्ट के साथ स्नैकबार दिखाता है - R.id.shownSnackbarBtn
- स्नैकबार जिसमें उपयोगकर्ता टाइप किया हुआ पाठ होना चाहिए - android.support.design.R.id.snackbar_text
अब एक वर्ग बनाते हैं जो हमारे प्रवाह का परीक्षण करेगा:
/**
* Testing of the snackbar activity.
**/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class SnackbarActivityTest{
//espresso rule which tells which activity to start
@Rule
public final ActivityTestRule<SnackbarActivity> mActivityRule =
new ActivityTestRule<>(SnackbarActivity.class, true, false);
@Override
public void tearDown() throws Exception {
super.tearDown();
//just an example how tear down should cleanup after itself
mDatabase.clear();
mSharedPrefs.clear();
}
@Override
public void setUp() throws Exception {
super.setUp();
//setting up your application, for example if you need to have a user in shared
//preferences to stay logged in you can do that for all tests in your setup
User mUser = new User();
mUser.setToken("randomToken");
}
/**
*Test methods should always start with "testXYZ" and it is a good idea to
*name them after the intent what you want to test
**/
@Test
public void testSnackbarIsShown() {
//start our activity
mActivityRule.launchActivity(null);
//check is our text entry displayed and enter some text to it
String textToType="new snackbar text";
onView(withId(R.id.textEntry)).check(matches(isDisplayed()));
onView(withId(R.id.textEntry)).perform(typeText(textToType));
//click the button to show the snackbar
onView(withId(R.id.shownSnackbarBtn)).perform(click());
//assert that a view with snackbar_id with text which we typed and is displayed
onView(allOf(withId(android.support.design.R.id.snackbar_text),
withText(textToType))) .check(matches(isDisplayed()));
}
}
जैसा कि आपने देखा कि 3-4 चीजें हैं जिन्हें आप अक्सर देख सकते हैं:
onView (withXYZ) <- उनके साथ व्यूमाचर्स आप स्क्रीन पर तत्वों को खोजने में सक्षम हैं
प्रदर्शन (क्लिक ()) <- viewActions, आप उन तत्वों पर कार्रवाई कर सकते हैं जिन्हें आपने पहले पाया था
चेक (माचिस (isisisplayed) ()) <- viewAssertions, जाँचें जो आप पहले मिले स्क्रीन पर करना चाहते हैं
ये सभी और कई अन्य यहां देखे जा सकते हैं: https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/index.html
Thats यह, अब आप या तो कक्षा के नाम / परीक्षण पर राइट क्लिक करके और रन टेस्ट या कमांड के साथ चयन कर सकते हैं:
./gradlew connectedFLAVORNAMEAndroidTest
नेविगेशन
@Test
public void testUpNavigation() {
intending(hasComponent(ParentActivity.class.getName())).respondWith(new Instrumentation.ActivityResult(0, null));
onView(withContentDescription("Navigate up")).perform(click());
intended(hasComponent(ParentActivity.class.getName()));
}
ध्यान दें कि यह एक वर्कअराउंड है और अन्य दृश्यों के साथ टकराएगा जिसमें समान सामग्री विवरण होता है।
किसी दृश्य पर क्रिया करना
प्रदर्शन पद्धति का उपयोग करके किसी दृश्य पर ViewActions
निष्पादित करना संभव है।
ViewActions
वर्ग सबसे आम कार्यों के लिए सहायक तरीके प्रदान करता है, जैसे:
ViewActions.click()
ViewActions.typeText()
ViewActions.clearText()
उदाहरण के लिए, दृश्य पर क्लिक करने के लिए:
onView(...).perform(click());
onView(withId(R.id.button_simple)).perform(click());
आप एक प्रदर्शन कॉल के साथ एक से अधिक क्रियाओं को निष्पादित कर सकते हैं:
onView(...).perform(typeText("Hello"), click());
तो देखने के लिए आप के साथ एक के अंदर स्थित है काम कर रहे हैं ScrollView
(लम्बवत या क्षैतिज), कार्रवाई है कि दृश्य की आवश्यकता होती है प्रदर्शित करने के लिए (जैसे पूर्ववर्ती पर विचार click()
और typeText()
के साथ) scrollTo()
। यह सुनिश्चित करता है कि अन्य कार्रवाई के लिए आगे बढ़ने से पहले दृश्य प्रदर्शित किया गया है:
onView(...).perform(scrollTo(), click());
दृश्य के साथ एक दृश्य ढूँढना
ViewMatchers
साथ आप वर्तमान दृश्य पदानुक्रम में दृश्य पा सकते हैं।
एक दृश्य खोजने के लिए, onView()
साथ onView()
पद्धति का उपयोग करें जो सही दृश्य का चयन करता है। onView()
विधियाँ ViewInteraction
ऑब्जेक्ट को ViewInteraction
।
उदाहरण के लिए, इसके R.id
द्वारा एक दृश्य खोजना R.id
ही सरल है:
onView(withId(R.id.my_view))
एक पाठ के साथ एक दृश्य ढूँढना:
onView(withText("Hello World"))
एस्प्रेसो कस्टम मैचर्स
डिफ़ॉल्ट रूप से एस्प्रेसो में कई मैचर्स होते हैं जो आपको उन विचारों को खोजने में मदद करते हैं जो आपको उनके साथ कुछ चेक या इंटरैक्शन करने की आवश्यकता होती है।
सबसे महत्वपूर्ण निम्नलिखित धोखा शीट में पाया जा सकता है:
https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/
मैचर्स के कुछ उदाहरण हैं:
- withId (R.id.ID_of_object_you_are_looking_for);
- withText ("कुछ पाठ जो आपको उम्मीद है कि वस्तु है");
- isDisplayed () <- चेक दृश्यमान दृश्य है
- doNotExist () <- जांचें कि दृश्य मौजूद नहीं है
ये सभी रोजमर्रा के उपयोग के लिए बहुत उपयोगी हैं, लेकिन अगर आपके पास अधिक जटिल विचार हैं, तो आपके कस्टम मिलान लिखने वाले परीक्षण को अधिक पठनीय बना सकते हैं और आप उन्हें विभिन्न स्थानों में पुन: उपयोग कर सकते हैं।
आपके द्वारा विस्तारित किए जा सकने वाले मिलान के 2 सबसे सामान्य प्रकार हैं: TypeSafeMatcher BoundedMatcher
TypeSafeMatcher को कार्यान्वित करने के लिए आपको उस उदाहरण की जांच करनी होगी। यदि आप जिस प्रकार के विरुद्ध दावा कर रहे हैं, उसे देखें कि यदि आप सही प्रकार से इसके गुण से मेल खाते हैं, तो आप इसके कुछ गुण मिलानकर्ता को प्रदान करते हैं।
उदाहरण के लिए, एक सुरक्षित दृश्य टाइप करने वाले सुरक्षित मिलान को टाइप करने योग्य है:
public class DrawableMatcher extends TypeSafeMatcher<View> {
private @DrawableRes final int expectedId;
String resourceName;
public DrawableMatcher(@DrawableRes int expectedId) {
super(View.class);
this.expectedId = expectedId;
}
@Override
protected boolean matchesSafely(View target) {
//Type check we need to do in TypeSafeMatcher
if (!(target instanceof ImageView)) {
return false;
}
//We fetch the image view from the focused view
ImageView imageView = (ImageView) target;
if (expectedId < 0) {
return imageView.getDrawable() == null;
}
//We get the drawable from the resources that we are going to compare with image view source
Resources resources = target.getContext().getResources();
Drawable expectedDrawable = resources.getDrawable(expectedId);
resourceName = resources.getResourceEntryName(expectedId);
if (expectedDrawable == null) {
return false;
}
//comparing the bitmaps should give results of the matcher if they are equal
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
Bitmap otherBitmap = ((BitmapDrawable) expectedDrawable).getBitmap();
return bitmap.sameAs(otherBitmap);
}
@Override
public void describeTo(Description description) {
description.appendText("with drawable from resource id: ");
description.appendValue(expectedId);
if (resourceName != null) {
description.appendText("[");
description.appendText(resourceName);
description.appendText("]");
}
}
}
माचिस का उपयोग इस तरह लपेटा जा सकता है:
public static Matcher<View> withDrawable(final int resourceId) {
return new DrawableMatcher(resourceId);
}
onView(withDrawable(R.drawable.someDrawable)).check(matches(isDisplayed()));
बाउंडेड मैचर्स भी ऐसे ही होते हैं, न तो आपको टाइप चेक करना होता है बल्कि, क्योंकि यह आपके लिए ऑटोमैटिकली किया जाता है:
/**
* Matches a {@link TextInputFormView}'s input hint with the given resource ID
*
* @param stringId
* @return
*/
public static Matcher<View> withTextInputHint(@StringRes final int stringId) {
return new BoundedMatcher<View, TextInputFormView>(TextInputFormView.class) {
private String mResourceName = null;
@Override
public void describeTo(final Description description) {
//fill these out properly so your logging and error reporting is more clear
description.appendText("with TextInputFormView that has hint ");
description.appendValue(stringId);
if (null != mResourceName) {
description.appendText("[");
description.appendText(mResourceName);
description.appendText("]");
}
}
@Override
public boolean matchesSafely(final TextInputFormView view) {
if (null == mResourceName) {
try {
mResourceName = view.getResources().getResourceEntryName(stringId);
} catch (Resources.NotFoundException e) {
throw new IllegalStateException("could not find string with ID " + stringId, e);
}
}
return view.getResources().getString(stringId).equals(view.getHint());
}
};
}
मैचर्स पर अधिक पढ़ा जा सकता है:
https://developer.android.com/reference/android/support/test/espresso/matcher/ViewMatchers.html
कुल मिलाकर एस्प्रेसो
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test:runner:0.5'
ViewMatchers - माचिस लागू करने वाली वस्तुओं का एक संग्रह Matcher<? super View>
इंटरफ़ेस। आप करने के लिए इनमें से किसी एक या एक से अधिक पारित कर सकते हैं onView
वर्तमान दृश्य पदानुक्रम में किसी दृश्य का पता लगाने की विधि।
ViewActions - का एक संग्रह ViewActions
को पारित किया जा सकता है कि ViewInteraction.perform()
विधि (उदाहरण के लिए, click()
)।
ViewAssertions - का एक संग्रह ViewAssertions
कि पारित किया जा सकता ViewInteraction.check()
विधि। अधिकांश समय, आप मैचों के दावे का उपयोग करेंगे, जो वर्तमान में चयनित दृश्य की स्थिति का दावा करने के लिए एक दृश्य मिलानकर्ता का उपयोग करता है।
एस्प्रेसो धोखा शीट गूगल द्वारा
EditText में टेक्स्ट डालें
onView(withId(R.id.edt_name)).perform(typeText("XYZ"));
closeSoftKeyboard();
दृश्य पर क्लिक करें
onView(withId(R.id.btn_id)).perform(click());
जाँच दृश्य प्रदर्शित किया जाता है
onView(withId(R.id.edt_pan_number)).check(ViewAssertions.matches((isDisplayed())));
एक परीक्षण सूट में परीक्षण कक्षाओं का एक समूह बनाएं
आप अपने इंस्ट्रूमेंटेड यूनिट परीक्षणों के निष्पादन को एक सुइट को परिभाषित कर सकते हैं।
/**
* Runs all unit tests.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({MyTest1.class ,
MyTest2.class,
MyTest3.class})
public class AndroidTestSuite {}
फिर AndroidStudio में आप ग्रेडल या नया कॉन्फ़िगरेशन सेट कर सकते हैं जैसे:
टेस्ट सूट को नस्ट किया जा सकता है।