Refactor hw7 mobile tests to meet course requirements
This commit is contained in:
@@ -1,137 +1,68 @@
|
||||
# OTUS Homework 7: Mobile (Selenide + Appium)
|
||||
# OTUS Homework 7: Mobile Testing
|
||||
|
||||
Автотесты мобильного приложения Wishlist через Selenide + Appium и инфраструктура эмулятора через Docker Compose.
|
||||
Проект содержит мобильные UI-тесты для приложения Wishlist на базе `selenide-appium`.
|
||||
|
||||
## Что реализовано
|
||||
- 3 сценария из ТЗ: списки желаний, подарки, резервирование подарка другого пользователя.
|
||||
- Архитектура: базовый тест + экранные объекты (screens).
|
||||
- Конфигурируемые capabilities через system properties.
|
||||
- Подготовка тестовых данных через БД перед каждым тестом.
|
||||
- Скрипты для сбора Logcat.
|
||||
Реализованы сценарии:
|
||||
- создание и редактирование списка желаний;
|
||||
- создание и редактирование подарка;
|
||||
- изменение статуса резервирования подарка другого пользователя.
|
||||
|
||||
## Стек и версии
|
||||
- Java 21, Maven.
|
||||
- Selenide: 7.3.1
|
||||
- Appium Java Client: 9.3.0 (UiAutomator2)
|
||||
- Selenium: 4.25.0
|
||||
- JUnit: 5.10.2
|
||||
- PostgreSQL JDBC: 42.7.10
|
||||
- apk-parser: 2.6.10
|
||||
- SLF4J: 2.0.13
|
||||
- Docker Compose (эмулятор Android + Appium)
|
||||
## Архитектура
|
||||
- `Guice` для DI.
|
||||
- `JUnit 5 Extension` вместо базового тестового класса.
|
||||
- `AbsPageObject` -> `AbsBasePage` / `BaseMobileComponent`.
|
||||
- `BlockingQueue` для распределения тестов по эмуляторам.
|
||||
- код инфраструктуры и page object находится в `src/main/java`;
|
||||
- в `src/test/java` находятся только тестовые классы.
|
||||
|
||||
## Структура проекта
|
||||
- `src/test/java/ru/otus/mobile/tests` — тесты.
|
||||
- `src/test/java/ru/otus/mobile/screens` — экранные объекты.
|
||||
- `src/test/java/ru/otus/mobile/config` — конфигурация Appium/Android.
|
||||
- `src/test/java/ru/otus/mobile/driver` — фабрика драйвера.
|
||||
- `src/test/java/ru/otus/mobile/db` — reset SQL и JDBC-клиент.
|
||||
- `docker-compose.yml` — эмулятор Android с Appium.
|
||||
- `scripts/` — утилиты (Logcat).
|
||||
## Инфраструктура
|
||||
`docker-compose.yml` поднимает:
|
||||
- `wiremock` для раздачи `wishlist.apk`;
|
||||
- `android-emulator` с Appium и VNC.
|
||||
|
||||
## Инфраструктура (Docker Compose)
|
||||
Эмулятор и Appium поднимаются одной командой:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
Приложение не маунтится в эмулятор и не ставится через ADB.
|
||||
APK скачивается Appium по capability `app`.
|
||||
Источник APK для Wiremock: файл `wishlist-349317-5fd795.apk` в корне проекта.
|
||||
Эмулятор запускается без `privileged`, доступ к аппаратной виртуализации передается через `/dev/kvm`.
|
||||
|
||||
Порты:
|
||||
- Appium: `http://localhost:4723`
|
||||
- noVNC: `http://localhost:6080`
|
||||
## Тестовые аккаунты
|
||||
Тесты используют заранее созданные аккаунты:
|
||||
- `user1us / user1us`
|
||||
- `user2us / user2us`
|
||||
- `user3us / user3us`
|
||||
- `user4us / user4us`
|
||||
|
||||
APK берется из файла `./wishlist-349317-5fd795.apk`, копируется в `./apk/wishlist.apk` и монтируется в контейнер по пути `/apk/wishlist.apk`.
|
||||
После старта контейнеров APK автоматически устанавливается в эмулятор и приложение стартует.
|
||||
`user4us` используется как владелец подарка в тесте резервирования.
|
||||
|
||||
## Подготовка данных через БД
|
||||
Для повторяемости тестов перед каждым тестом выполняется SQL‑сброс данных аккаунта.
|
||||
Данные доступа к БД **не хранятся в репозитории** — нужно передать через env или `-D`.
|
||||
Аккаунты можно создать заранее (регистрация через приложение) или доверить это автотестам.
|
||||
Если логин/пароль не переданы через параметры запуска, тест сгенерирует логины, создаст пользователей через reset‑SQL в БД (если их нет), затем выполнит логин. Регистрация через приложение используется как fallback, если вход не удался.
|
||||
## Подготовка
|
||||
Нужно задать доступ к БД, иначе `mvn test` завершится ошибкой:
|
||||
|
||||
Переменные/свойства:
|
||||
- `DB_URL` или `-Ddb.url`
|
||||
- `DB_USER` или `-Ddb.user`
|
||||
- `DB_PASSWORD` или `-Ddb.password`
|
||||
- `DB_RESET_SQL` или `-Ddb.reset.sql` — SQL c параметрами `?` (username, email, password_hash, username). Если не задано, используется встроенный reset‑SQL (удаляет wishlists/gifts и создает пользователя при отсутствии).
|
||||
|
||||
Пример (PowerShell, значения подставить свои):
|
||||
```powershell
|
||||
$env:DB_URL = "jdbc:postgresql://<host>:5432/<db>"
|
||||
$env:DB_USER = "<user>"
|
||||
$env:DB_PASSWORD = "<password>"
|
||||
$env:DB_RESET_SQL = "<one-statement reset sql with ? placeholders>"
|
||||
```
|
||||
|
||||
## Как запускать
|
||||
### Полный прогон (обязательная последовательность)
|
||||
1) Поднять инфраструктуру:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
Убедиться, что Docker Desktop/Engine запущен. Если Appium недоступен, тесты падают быстро с понятной ошибкой.
|
||||
|
||||
2) Задать доступ к БД (обязательно, иначе тесты упадут):
|
||||
```powershell
|
||||
$env:DB_URL="jdbc:postgresql://sql.otus.kartushin.su:5432/wishlist"
|
||||
$env:DB_USER="student"
|
||||
$env:DB_PASSWORD="student"
|
||||
```
|
||||
|
||||
3) Запустить все тесты (логины/пароли можно не задавать):
|
||||
## Запуск
|
||||
1. Поднять окружение:
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
2. Дождаться статуса `healthy` у `wiremock` и `android-emulator`:
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
Тесты не ждут загрузку эмулятора сами. Готовность окружения проверяется на уровне Docker Compose.
|
||||
|
||||
3. Запустить тесты:
|
||||
|
||||
```bash
|
||||
mvn test
|
||||
```
|
||||
|
||||
Если логины не заданы, они будут сгенерированы автоматически, пользователь будет создан через БД (если отсутствует) и выполнится вход.
|
||||
Регистрация через приложение используется только как fallback, если вход не удался.
|
||||
|
||||
Опционально: задать логины/пароли тестовых пользователей (если зарегистрированы вручную):
|
||||
```bash
|
||||
mvn "-Dlogin.username.wishlists=<user1>" "-Dlogin.password.wishlists=<pass1>" \
|
||||
"-Dlogin.username.gifts=<user2>" "-Dlogin.password.gifts=<pass2>" \
|
||||
"-Dlogin.username.reservation=<user3>" "-Dlogin.password.reservation=<pass3>" \
|
||||
"-Dreservation.owner=<user4>" \
|
||||
test
|
||||
```
|
||||
|
||||
### Один тест
|
||||
```bash
|
||||
mvn "-Dtest=ru.otus.mobile.tests.WishlistsTest" test
|
||||
```
|
||||
|
||||
### Запуск через Docker Compose
|
||||
```bash
|
||||
mvn -Dappium.url=http://localhost:4723 -Dapp.path=/apk/wishlist.apk -Dapp.package=ru.otus.wishlist -Dapp.activity=ru.otus.wishlist.MainActivity test
|
||||
```
|
||||
|
||||
### Полный пример запуска (Appium + БД)
|
||||
```bash
|
||||
mvn -Dappium.url=http://localhost:4723 -Dapp.path=/apk/wishlist.apk -Dapp.package=ru.otus.wishlist -Dapp.activity=ru.otus.wishlist.MainActivity -Ddb.url=jdbc:postgresql://<host>:5432/<db> -Ddb.user=<user> -Ddb.password=<password> test
|
||||
```
|
||||
|
||||
## Параметры запуска
|
||||
- `-Dappium.url` — URL Appium (default: `http://localhost:4723`)
|
||||
- `-Dapp.path` — путь до APK (default: `/apk/wishlist.apk`)
|
||||
- `-Dapp.package` — package приложения (если APK недоступен локально)
|
||||
- `-Dapp.activity` — main activity (если APK недоступен локально)
|
||||
- `-Ddevice.name` — имя устройства (default: `Android Emulator`)
|
||||
- `-Dplatform.version` — версия Android (опционально)
|
||||
- `-Dudid` — UDID (опционально)
|
||||
- `-DnoReset` — не сбрасывать состояние (default: `false`)
|
||||
- `-DnewCommandTimeout` — timeout Appium, сек (default: `120`)
|
||||
- `-Dlogin.username.<account>` — логин для конкретного теста (например `login.username.wishlists`)
|
||||
- `-Dlogin.password` — пароль (default: `Admin123`)
|
||||
- `-Dlogin.password.hash` — bcrypt‑хэш пароля для reset‑SQL (default в коде)
|
||||
|
||||
## Сбор Logcat
|
||||
PowerShell:
|
||||
```powershell
|
||||
.\scripts\collect-logcat.ps1
|
||||
```
|
||||
|
||||
Bash:
|
||||
```bash
|
||||
./scripts/collect-logcat.sh
|
||||
```
|
||||
|
||||
Логи сохраняются в файл `logcat.txt` в корне проекта.
|
||||
## Логи
|
||||
После выполнения тестов logcat сохраняется в файл `logcat.txt` в корне проекта через Selenium/Appium logs API.
|
||||
|
||||
Reference in New Issue
Block a user