Масштабирование задач gradle для поддержки нескольких устройств - PullRequest
0 голосов
/ 26 ноября 2018

Моя текущая настройка для контрольно-измерительных приборов не может обрабатывать снимки экрана, сохраненные на каждом устройстве во время проверки.Он не знает, что делать, потому что обнаруживает несколько устройств, и поэтому все эти задачи не выполняются.Я пытаюсь выяснить, как его масштабировать, независимо от того, сколько устройств используется для выполнения моих тестов, будь то один или десяток, снимки экрана захватываются с каждого устройства и перемещаются в одну папку в моем отчете HTML.Я предполагаю, что мне нужно каким-то образом передать имя устройства при запуске ./gradlew cAT, чтобы оно могло связать его со всеми другими задачами, которые я запускаю в качестве префикса.

Так что это мой вопрос ивам больше не нужно читать, если вы уже знаете, как на него ответить.

У меня есть несколько предположений, в том числе:
1. Код захвата моего скриншота (см. ниже) настроен правильно(и не должен быть полностью списан)
2. Я правильно использую осколки.Пока я открываю кучу эмуляторов, беру их имена с помощью «adb devices» в терминале, который возвращает что-то вроде:

List of devices attached
emulator-5554   device
emulator-5556   device
emulator-5558   device

Затем я открываю три отдельных терминала и запускаю одну из следующих команд в каждом терминале.:

ANDROID_SERIAL=emulator-5554 ./gradlew cAT -Pandroid.testInstrumentationRunnerArguments.numShards=3 -Pandroid.testInstrumentationRunnerArguments.shardIndex=0
ANDROID_SERIAL=emulator-5556 ./gradlew cAT -Pandroid.testInstrumentationRunnerArguments.numShards=3 -Pandroid.testInstrumentationRunnerArguments.shardIndex=1
ANDROID_SERIAL=emulator-5558 ./gradlew cAT -Pandroid.testInstrumentationRunnerArguments.numShards=3 -Pandroid.testInstrumentationRunnerArguments.shardIndex=2

Затем на эмуляторах запускаются тесты, и gradle создает единый HTML-отчет о тестировании, объединяя все их результаты, как я полагаю, с магией.

Предыдущая настройка

На данный момент я просто запускаю его без шардинга.Я делаю скриншот, когда тест не пройден.Это сохраняется на устройстве.Я запускаю тесты с помощью стандартного ./gradlew connectedAndroidTest (или ./gradlew cAT) и выполняю следующие задачи: снять скриншоты с устройства и сохранить их в отчете HTML.Это что-то вроде беспорядка и может потребовать некоторой работы, но этот код выглядит следующим образом:

Файл TestCase, который делает снимок экрана при неудачном завершении теста:

@Rule
public TestName name = new TestName();

@Rule
public TestWatcher watchman = new TestWatcher() {
    @Override
    public void failed(Throwable e, Description description) {
        screenshotFailedTest(name.getMethodName());
    }};

public void screenshotFailedTest(String testName) {
    File path = new File(getScreenshotPath());
    if (!path.exists()) {
        path.mkdirs(); }
    UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
    device.takeScreenshot(new File(path, testName));
}

private String getScreenshotPath() {
    return Environment.getExternalStorageDirectory().getAbsolutePath() + "/screenshots/" + getTargetContext().getPackageName();
}

Задачи моего файла кошмарного градля, которыеобработайте снимки экрана на устройстве:

tasks.whenTaskAdded { task ->
if (task.name.startsWith('connectedAndroidTest') || (task.name.startsWith('connected') && task.name.contains('AndroidTest'))) {
    println "Starting Connected Android Tests"
    task.finalizedBy screenshotFailedTests
}}

task createScreenshotFolder(type: Exec) {
    commandLine './create_screenshot_folder.sh'
    // see script below
}

task copyScreenshots(type: Exec) {
    def adb = android.sdkDirectory.path + "/platform-tools/adb"
    executable "$adb"
    args "pull",
        "/storage/emulated/0/screenshots/<app.name>/",
        "${buildDir}/reports/androidTests/connected/flavors/INTERNAL/"
}

task removeScreenshotsFromDevice(type: Exec) {
    def adb = android.sdkDirectory.path + "/platform-tools/adb"
    executable "$adb"
    args "shell",
         "rm",
         "-r",
         "/storage/emulated/0/screenshots/<app.name>/"
}

task renameScreenshotFolder {
    doLast {
    file("${buildDir}/reports/androidTests/connected/flavors/INTERNAL/<app.name>").renameTo(file("${buildDir}/reports/androidTests/connected/flavors/INTERNAL/Screenshots"))
}}

task screenshotFailedTests {
    dependsOn 'createScreenshotFolder'
    dependsOn 'copyScreenshots'
    dependsOn 'removeScreenshotsFromDevice'
    dependsOn 'renameScreenshotFolder'
    tasks.findByName('copyScreenshots').mustRunAfter 'createScreenshotFolder'
    tasks.findByName('removeScreenshotsFromDevice').mustRunAfter 'copyScreenshots'
    tasks.findByName('renameScreenshotFolder').mustRunAfter 'removeScreenshotsFromDevice'
}

А затем скрипт create_screenshot_folder.sh, указанный выше:

# Call adb and check if folder exists, create if it doesn't
cd $ANDROID_HOME/platform-tools/
./adb shell "if [ -e /storage/emulated/0/screenshots/ ]; then echo Screenshot folder already exists; else mkdir /storage/emulated/0/screenshots/ && echo Creating screenshot folder; fi"

./adb shell "if [ -e /storage/emulated/0/screenshots/<app.name>/ ]; then echo The screenshot folder already exists; else mkdir /storage/emulated/0/screenshots/<app.name>/ && echo Creating screenshot folder; fi"

Это довольно грязно и, возможно, есть гораздо более простой способ сделать все этобез внешних библиотек, но, похоже, это нормально для одного устройства.

1 Ответ

0 голосов
/ 27 ноября 2018

вы пробовали запускать тесты через

. / Gradlew spoonTaskname

Это автоматически решает вопрос о разбиении, и вы можете удалить эту часть из вашей структуры.Также следует позаботиться о том, чтобы вытащить все скриншоты с эмуляторов / устройств и объединить их с окончательным отчетом.

...