Изображение логотипа Espresso от Pro Android Dev
Результат обучения
В этом посте мы разберем, как найти элемент, используя его свойство adjacent elements и матчер hasSibling
.
Обзор
В последней части нашей серии статей об espresso Hello, espresso! Часть 5 Автоматизация веб-видов 🕸️🌎, мы разобрали, как автоматизировать веб-виды с помощью espresso. Пожалуйста, перечитайте, если вы пропустили.
К этому моменту вы должны иметь представление о том, как автоматизировать тесты пользовательского интерфейса android с помощью espresso, и быть немного знакомы с его основным API.
В следующих нескольких постах мы рассмотрим, как реализовать распространенные сценарии в android-приложениях или рецептах.
Поехали.
Как найти элемент с помощью его брата или сестры
Большинство современных мобильных приложений разрабатываются по модульному принципу с многократно используемыми компонентами, где один и тот же компонент дублируется в списке, как элемент управления.
В некоторых случаях существует несколько элементов с одинаковыми ID
, и найти их с помощью R.id.x
не получится, поскольку espresso не знает, какой именно элемент мы пытаемся найти.
В таких случаях мы можем найти элементы, используя какое-то уникальное свойство соседнего (или сиблингового) элемента.
Давайте рассмотрим пример, чтобы понять, как это работает в действии.
Понимание тестируемого приложения
Для этого теста мы будем использовать приложение APIDemos
, которое было форкнуто из популярного проекта Appium (который сам был форкнут из репозитория Google).
Это приложение демонстрирует множество компонентов Android в качестве примеров и как таковое является вполне достойной игровой площадкой.
Допустим, мы хотим автоматизировать следующий сценарий:
GIVEN user opens Task list activity
WHEN user taps on checkbox with id `@id/tasklist_finished` for "Conquer world" item in checklist
THEN checkbox is enabled
ПРИМЕЧАНИЕ: Если вы вручную изучаете приложение с помощью эмулятора Android в android studio, вы можете попасть на этот экран, нажав на Accessibility > Accessibility Node Querying.
Если вы попытаетесь найти уникальный id для этого флажка, вы обнаружите, что таких флажков несколько в пределах@android:id/list
и мы не можем использовать этот атрибут.
Однако у каждого флажка есть элемент управления TextView
, который имеет уникальный текст, и мы можем использовать это свойство для идентификации элемента.
Давайте напишем наш тест
Мы запускаем нашу активность с помощью:
@Rule
public ActivityScenarioRule<TaskListActivity> activityScenarioRule =
new ActivityScenarioRule<>(TaskListActivity.class);
Давайте воспользуемся свойством, что у элемента-сестры есть уникальный текст, чтобы найти нужный элемент
String taskText = "Conquer World";
onView(allOf(withId(R.id.tasklist_finished), hasSibling(withText(taskText))))
Начнем с того, что скажем:
- Мы хотим найти представление, которое соответствует всем свойствам, обернув условия в
allOf
. - Далее мы говорим, что хотим найти элемент с id
withId(R.id.tasklist_finished)
(т.е. наш флажок). - Однако нам нужен только тот элемент, у которого есть брат или сестра с определенным текстом, указав
hasSibling(withText(taskText))
, который используетhasSibling
View matcher
Наконец, когда мы нашли элемент, мы хотим щелкнуть на нем и проверить, что состояние изменилось на checked, указав:
.perform(click())
.check(matches(isChecked()));
Ниже приведен полный тест:
package recipes;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.hasSibling;
import static androidx.test.espresso.matcher.ViewMatchers.isChecked;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import io.appium.android.apis.R;
import io.appium.android.apis.accessibility.TaskListActivity;
@RunWith(AndroidJUnit4.class)
public class FindElementUsingHasSiblingE2ETest {
@Rule
public ActivityScenarioRule<TaskListActivity> activityScenarioRule =
new ActivityScenarioRule<>(TaskListActivity.class);
@Test
public void testCanFindElementUsingSiblingMatcher() {
String taskText = "Conquer World";
// Find checkbox with id tasklist_finished that has sibling label with text Conquer World
onView(allOf(withId(R.id.tasklist_finished), hasSibling(withText(taskText))))
// Click on the checkbox
.perform(click())
// Verify the checkbox was ticked
.check(matches(isChecked()));
}
}
Ресурсы 📘
- Код приложения
- Код теста
- Читайте рецепты приготовления эспрессо
До того, как вы уйдете
Спасибо, что потратили свое время на чтение этого поста. 🙏
💡 Если вы нашли эту статью глубокой или полезной 👍🏼, то, пожалуйста, уделите несколько минут и поделитесь ею со своими друзьями и коллегами или в своих социальных сетях. Каждая публикация помогает этому развиваться, а «делиться — значит заботиться» 🫂 не так ли?
Пока вы не ушли 🙌🏼. Знаете ли вы?
- Я публикую информационный бюллетень ✉️, подпишитесь 👉 newsletter.automationhacks.ioto и получайте его в свой почтовый ящик.
- А также недавно открыл канал на YouTube 📺, Подпишитесь на 👉automation hacks, чтобы не пропустить выход нового видео.
Я углубляюсь в автоматизацию тестирования и тестирование программного обеспечения на обеих этих платформах, и вы можете найти подписку полезной для вашего учебного путешествия.
Есть вопросы 🤔 или отзывы 😉?
Пожалуйста, дайте мне знать в комментариях (обещаю, я читаю их все ✌🏼) или напишите мне в Twitter или LinkedIn по адресу@automationhacks
.
До следующего раза, счастливого тестирования 🕵🏻 и обучения! 🌱