ตรวจสอบว่ากล่องโต้ตอบปรากฏขึ้นพร้อมกับ Espresso หรือไม่


87

ฉันพยายามที่จะเขียนการทดสอบบางอย่างกับใหม่หุ่นยนต์ทดสอบชุด (Espresso) แต่ฉันไม่พบข้อมูลใด ๆ เกี่ยวกับวิธีตรวจสอบว่ากล่องโต้ตอบปรากฏขึ้นและดำเนินการบางอย่างกับมันหรือไม่ (เช่นการคลิกปุ่มบวกและลบเป็นต้น) โปรดทราบว่ากล่องโต้ตอบอาจปรากฏขึ้นโดย a WebViewไม่ใช่โดยแอปพลิเคชันนั้นเอง

ความช่วยเหลือใด ๆ จะได้รับการชื่นชม ฉันต้องการลิงก์หรือโค้ดตัวอย่างสำหรับข้อมูลเบื้องต้น:

  1. ตรวจสอบว่ากล่องโต้ตอบปรากฏขึ้นหรือไม่
  2. คลิกที่ปุ่มโต้ตอบ
  3. โต้ตอบกับมุมมองภายในของกล่องโต้ตอบ (หากเป็นมุมมองที่กำหนดเอง)
  4. Preform คลิกภายนอกกล่องโต้ตอบและตรวจสอบว่ากำลังแสดงหรือไม่ (ตัวอย่างเช่นหากsetCancelable(false)ถูกเรียกในตัวสร้างไดอะล็อกและเราต้องการตรวจสอบ)

ขอบคุณในคำแนะนำ!


ข้อเสนอแนะใด ๆ เกี่ยวกับคำตอบของฉันด้านล่าง ??
ปฏิเสธ

คำตอบ:


125
  1. ในการตรวจสอบว่ากล่องโต้ตอบปรากฏขึ้นหรือไม่คุณสามารถตรวจสอบได้ว่า View with a text that present inside the dialog is shown:

    onView(withText("dialogText")).check(matches(isDisplayed()));
    

    หรือขึ้นอยู่กับข้อความที่มีรหัส

    onView(withId(R.id.myDialogTextId)).check(matches(allOf(withText(myDialogText), isDisplayed()));
    
  2. หากต้องการคลิกที่ปุ่มโต้ตอบให้ทำสิ่งนี้ (ปุ่ม 1 - ตกลงปุ่ม 2 - ยกเลิก):

    onView(withId(android.R.id.button1)).perform(click());
    

    อัปเดต

  3. ผมคิดว่าเป็นไปได้ที่เอสเพรสโซ่ตั้งแต่มีการสนับสนุนหลายหน้าต่าง
  4. ไม่แน่ใจเกี่ยวกับการคลิกนอกมุมมองไดอะล็อกที่กำหนดเอง แต่สำหรับการตรวจสอบว่ากำลังแสดงอยู่หรือไม่คุณต้องสร้างตัวจับคู่แบบกำหนดเองของคุณและตรวจสอบภายใน

3
ขั้นตอนที่ 1 ไม่ได้ผลสำหรับฉันใน ProgressDialog เพียงพยายามตรวจสอบชื่อและข้อความของกล่องโต้ตอบ
Tim Boland

1
เอสเพรสโซกับการนำเข้าแบบคงที่คืออะไร? วิธีการเหล่านั้นมาจากคลาสใด เหตุใดคุณจึงใช้การนำเข้าแบบคงที่กับคำตอบสแต็กโอเวอร์

2
@jvrodrigues ทุกการสอน Espresso เดียวใช้การนำเข้าแบบคงที่ ฉันขอแนะนำให้คุณคุ้นเคยกับมัน (แม้ว่าฉันจะเข้าใจความยุ่งยาก) สิ่งนี้ช่วยได้: google.github.io/android-testing-support-library/docs
AutonomousApps

สำหรับขั้นตอนที่ 4 แทนที่จะคลิกนอกกล่องโต้ตอบคุณสามารถเรียก "pressBack ();" ซึ่งปิดกล่องโต้ตอบ มันเทียบเท่ากับการใช้ปุ่มย้อนกลับของฮาร์ดแวร์
Ethan

@denys โปรเจ็กต์ถูกย้ายแล้ว ดูเหมือนว่าลิงค์จะตาย
Neon Warge

67

ตอนนี้ฉันใช้สิ่งนี้และดูเหมือนว่าจะใช้ได้ดี

onView(withText(R.string.my_title))
    .inRoot(isDialog()) // <---
    .check(matches(isDisplayed()));

28

หากคุณมี AlertDialog เช่นนั้น:

ป้อนคำอธิบายภาพที่นี่

คุณสามารถตรวจสอบว่ามีการแสดงส่วนประกอบหรือไม่:

int titleId = mActivityTestRule.getActivity().getResources()
        .getIdentifier( "alertTitle", "id", "android" );

onView(withId(titleId))
        .inRoot(isDialog())
        .check(matches(withText(R.string.my_title)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.text1))
        .inRoot(isDialog())
        .check(matches(withText(R.string.my_message)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.button2))
        .inRoot(isDialog())
        .check(matches(withText(android.R.string.no)))
        .check(matches(isDisplayed()));

onView(withId(android.R.id.button3))
        .inRoot(isDialog())
        .check(matches(withText(android.R.string.yes)))
        .check(matches(isDisplayed()));

และดำเนินการ:

onView(withId(android.R.id.button3)).perform(click());

2
ข้อความในกรณีของฉันมีรหัสและชื่อมีรหัสที่ซ่อนอยู่ของandroid.R.id.message android.R.id.alertTitle
Jason Robinson

2
หากคุณใช้ AlertDialog (หรือ DialogFragment) ที่มาจากไลบรารีการสนับสนุน AppCompat ให้ใช้สิ่งนี้:int alertDialogTitleId = android.support.v7.appcompat.R.id.alertTitle;
Mr-IDE

ในกรณีที่ทุกคนต้องการที่จะรู้ค่าพารามิเตอร์stackoverflow.com/a/15488321/1713366 หากคุณไม่ทราบชื่อหรือประเภท def ให้ลองcheck()ใช้มุมมองที่ไม่มีอยู่และดูที่ลำดับชั้นของโครงร่างบน logcat defType = nameคุณจะเห็นพวงของเหล่านี้ ตัวอย่างเช่นmessage=hello worldพารามิเตอร์ของคุณควรมีลักษณะดังนี้"hello world", "message", "your package name"
Jcorretjer

3

ในการตอบคำถาม 4 ซึ่งคำตอบที่ยอมรับไม่ได้ฉันได้แก้ไขโค้ดต่อไปนี้ซึ่งพบที่นี่ใน Stack Overflow ( ลิงก์ ) เพื่อทดสอบว่ามีการแสดง Toast

@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @IdRes int id) {
    return onView(withId(id)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}

รหัสidผ่านคือรหัสของรายการที่Viewแสดงอยู่ในกล่องโต้ตอบของคุณ คุณสามารถเขียนวิธีการดังนี้:

@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @NonNull String text) {
    return onView(withText(text)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}

ตอนนี้กำลังมองหาViewสตริงข้อความที่มีเฉพาะ

ใช้มันดังนี้:

getRootView(getActivity(), R.id.text_id).perform(click());

3

ปุ่มรหัส Rid.button1 และ R.id.button2 จะไม่เหมือนกันในทุกอุปกรณ์ รหัสอาจมีการเปลี่ยนแปลงตามเวอร์ชันของระบบปฏิบัติการ

วิธีที่ถูกต้องในการบรรลุเป้าหมายนี้คือการใช้ UIAutomator รวม UIAutomator dependency ใน build.gradle ของคุณ

// Set this dependency to build and run UI Automator tests
  androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'

และใช้

// Initialize UiDevice instance
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

// Search for correct button in the dialog.
UiObject button = uiDevice.findObject(new UiSelector().text("ButtonText"));
if (button.exists() && button.isEnabled()) {
    button.click();
}

1
อันที่จริงandroid.R.id.button1, android.R.id.button2และandroid.R.id.button3สำหรับ "บวก", "เป็นกลาง" และ "เชิงลบ" เป็นสัญลักษณ์ทั่วโลกที่สามารถนำมาใช้ หากคุณเลือกที่จะเลือกปุ่มผ่านทางข้อความของพวกเขา - ซึ่งมีทั้งหมดปรับ - คุณไม่จำเป็นต้อง UIAutomator onView(withText("ButtonTest")).perform(click())แต่สามารถทำเช่นเดียวกันกับเอสเพรสโซ่ของ
Thomas Keller

ฉันใช้โซลูชันนี้กับกรอบการทดสอบ Robotium และฉันสามารถเลือกปุ่มกล่องโต้ตอบ Android OS ได้อย่างง่ายดาย ช่วยฉันประหยัดเวลาได้มาก ขอบคุณ jaydeepw!
Ray

@ThomasKeller ฉันเคยใช้รหัส button1, button2 ในอดีตการทดสอบของฉันพังเมื่อฉันใช้งานบนอุปกรณ์ต่างๆ กล่องโต้ตอบที่แสดงคือการควบคุมระบบ ไม่ใช่การควบคุม / UI ของคุณ สำหรับสิ่งที่อยู่นอก UI ของคุณขอแนะนำให้ใช้ UIAutomator
JaydeepW

แค่นั้นแหละ. ขอบคุณมาก.
1lb3r

3

เผื่อว่าใครเจอคำถามนี้เหมือนผม คำตอบทั้งหมดจะใช้ได้กับกล่องโต้ตอบที่มีปุ่มโต้ตอบเท่านั้น อย่าพยายามใช้สิ่งนี้สำหรับกล่องโต้ตอบความคืบหน้าโดยไม่มีการโต้ตอบกับผู้ใช้ เอสเปรสโซรอให้แอปเข้าสู่สถานะว่าง ตราบใดที่กล่องโต้ตอบความคืบหน้าปรากฏขึ้นแสดงว่าแอปไม่ได้ทำงาน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.