Как разместить тестовые файлы Android (инструментальные) вне каталога проекта?

У меня есть проект Android (созданный Cordova), в который я хочу добавить (инструментальные) тесты. У него есть только один MainActivity.java, который нужно протестировать.

Обычно это означает добавление некоторых зависимостей к build.gradle и создание файла /src/androidTest/java/org/example/package/MainActivityTest.java с классом MainActivityTest и некоторыми методами тестирования. (В Android Studio я могу даже сгенерировать их, используя «Выполнить» -> «Записать тест эспрессо» - так просто и работает).

К сожалению, теперь у меня есть требование, чтобы эти тестовые файлы действительно находились вне каталога проекта. В существующем проекте Cordova должны быть только минимальные изменения (поскольку он регенерируется и обрабатывается как артефакт сборки). MainActivity.java лучше всего находиться в той же корневой папке, где находится проект Android в /android.

Как я могу этого добиться?


Изменения build.gradle можно добавить в файл build-extras.gradle, который уже включен в настоящий build.gradle, так что об этом позаботятся.

Но я понятия не имею, как разместить MainActivityTest.java вне структуры папок проекта и при этом запустить его внутри проекта.

Для iOS вы можете связать внешние файлы с проектом с абсолютными путями. Что-то подобное было бы идеально и здесь.

Я посмотрел на sourceSets, но я не уверен, как интегрировать это в проект Cordova Android, в котором уже есть это не по умолчанию (я думаю?) sourceSets:

android {
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
        }
    }
    ...
}     

person janpio    schedule 11.08.2017    source источник


Ответы (1)


Есть два способа:

  1. #P2# <блочная цитата> #P3# #P4#
  2. #P5#
    #P6# #P7# #P8#
    #P9#
    #P10# #P11# #P12#
    #P13#

Я создал ОБРАЗЕЦ ПРОЕКТА, чтобы продемонстрировать структуру тестов в обоих случаях.


build.gradle проекта/модуля должен использовать этот подключаемый модуль:

// A plugin used for test-only-modules
apply plugin: 'com.android.test'

Этот подключаемый модуль использует TestExtension (ссылка на его DSL ). С плагином TestExtension и 'com.android.test' ваш файл gradle будет выглядеть так:

apply plugin: 'com.android.test'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"
    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 26

        // The package name of the test app
        testApplicationId 'com.example.android.testing.espresso.BasicSample.tests'
        // The Instrumentation test runner used to run tests.
        testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'
    }
    // Set the target app project. The module specified here should contain the production code
    // test should run against.
    targetProjectPath ':app'
}

dependencies {
    // Testing-only dependencies
    // Force usage of support annotations in the test app, since it is internally used by the runner module.
    compile 'junit:junit:4.12'
    compile 'com.android.support:support-annotations:25.4.0'
    compile 'com.android.support.test:runner:1.0.1'
    compile 'com.android.support.test:rules:1.0.1'
    compile 'com.android.support.test.espresso:espresso-core:3.0.1'
}

Обратите внимание, что здесь не поддерживается никакой "androidTestCompile"!

Не забудьте создать AndroidManifest.xml. Это будет выглядеть так:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.android.testing.espresso.BasicSample.tests">

<!-- Specify runner and target application package -->
<instrumentation
    android:name="android.support.test.runner.AndroidJUnitRunner"
    android:functionalTest="false"
    android:handleProfiling="false"
    android:label="Tests for com.example.android.testing.espresso.BasicSample"
    android:targetPackage="com.example.android.testing.espresso.BasicSample"/>

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

</manifest>

Обратите внимание, что исходные файлы тестов находятся в папке main (не androidTest):

src-> main-> java-> package.name.folders

Затем вы можете связать этот тестовый проект с вашим проектом приложения в settings.gradle:

include ':module-androidTest'
project(':module-androidTest').projectDir = new File("../BasicSampleTests/test")

В Android Studio необходимо создать конфигурацию запуска Android Instrumented Tests. Это будет выглядеть так: введите здесь описание изображения Теперь запустите тесты:

введите описание изображения здесь

Если у вас есть проблемы со сборкой продуктов, вам следует добавить publishNonDefault в build.gradle вашего приложения:

android {
    ...
    defaultConfig {
       ...
    }
    publishNonDefault true
}
person Sheikh    schedule 27.09.2017
comment
Спасибо, не только для Cordova, все в порядке - проект Android должен быть настоящим проектом Android, так что это должно работать. Я рассмотрю это и доложу. - person janpio; 27.09.2017
comment
@janpio, обратите внимание на эти примеры Google. - person Sheikh; 27.09.2017
comment
Я сделал, не могу заставить его работать. Чтение этого имеет смысл, но я получаю самые странные ошибки Gradle, даже с недавно созданным суперпростым проектом. Также не нашел проекта с рабочим примером :( - person janpio; 03.10.2017
comment
Небольшой прогресс: пример android-testing-templates от Google теперь работает. Однако, как только я пробую это в проекте без ароматизаторов, он терпит неудачу: / Studio = Текущий проект не может быть запущен и .gradlew = Не удалось завершить сеанс: INSTALL_FAILED_VERSION_DOWNGRADE - person janpio; 03.10.2017
comment
привет, @janpio, я переписал свой ответ. Также я создал простой пример проекта и добавил на него ссылку. Кстати, у меня также было много проблем со сборкой и проблемами с конфигурациями запуска. Поэтому мне пришлось перейти на Android Studio 3.0 Beta 6. Мой образец отлично там работает. - person Sheikh; 03.10.2017
comment
Вау, @Sheihk, это потрясающе - спасибо. Приятно слышать, что это не моя глупость вызвала проблемы. Я посмотрю, смогу ли я заставить его работать, я буду немного ограничен в версии gradle из-за проекта Cordova, но сначала, чтобы заставить его работать каким-либо образом. - person janpio; 03.10.2017
comment
Ура, ваш пример проекта сработал. К сожалению, я не могу полагаться на Studio 3, поэтому мне придется снова изучить пример Google или посмотреть, смогу ли я заставить вас работать с текущими инструментами. Шаг за шагом... - person janpio; 03.10.2017
comment
Я немного повторил ваш образец проекта: 1. Я немного упростил его, сделав BasicSampleTests просто модуль вместо (неиспользуемого) проекта: github.com/janpio/separate_test_module/tree/simplify 2. чтобы понять, как ваш проект сравнивается с Android Sample, я встроил модуль в основной проект: github.com/janpio/separate_test_module/tree/inline Сейчас он очень похож на пример, но для версии Gradle и конфигурации BuildType/Flavor. - person janpio; 03.10.2017
comment
Ух ты, кажется, я заставил его работать с теми же версиями (Gradle), что и проект android-testing-sample: github.com/janpio/separate_test_module/tree/older-gradle - person janpio; 04.10.2017
comment
И тадаа, это также работает, если тестовый модуль извлечен за пределы структуры проекта: github .com/janpio/separate_test_module/tree/ Теперь, что именно мы оба сделали неправильно раньше? Без понятия. - person janpio; 04.10.2017
comment
Отличная работа! У нас получилось, что 2.2.1 версия плагина работает. Теперь нам нужно найти версию, которая наиболее близка к последней версии 2.3.3 и которая до сих пор успешно работает. - person Sheikh; 04.10.2017
comment
@janpio, хорошо, я наконец-то понял. Тесты как независимый проект будут работать в Android Studio 3.0 (с плагином Andorid Gradle Plugin 3.0.0-betaX и оболочкой gradle 4.1-all). Тесты как отдельный модуль (ваш вариант в github.com/janpio/separate_test_module/tree /) будет работать с Android Studio 2.3.3 (с плагином Andorid Gradle Plugin 2.2.3 и оболочкой gradle 3.3-all). Таким образом, самый высокий плагин — 2.2.3 (начиная с 2.3.0+ эта функциональность не работает). Соответствует ли он вашим потребностям в вашем проекте? Я думаю, теперь, когда все ясно, мы можем закрыть ваш вопрос. - person Sheikh; 04.10.2017
comment
Вы тестировали все версии Gradle или как узнали, когда он был сломан? - person janpio; 05.10.2017
comment
Спасибо! Да, я пробовал все от 2.2.1 до текущей последней стабильной версии 2.3.3 :) я не пробовал все версии 3.0.0, потому что важно попробовать, когда она будет официально стабильной. Так что просто использовал последнюю на данный момент 3.0.0-beta6 - person Sheikh; 05.10.2017
comment
Я создал этот новый вопрос, чтобы, возможно, выяснить, что вызывает его сбой для 2.2.x: /а> - person janpio; 05.10.2017
comment
ОБРАЗЕЦ ПРОЕКТА ПУСТ. - person Xyldrun Jacob; 24.12.2019
comment
@XyldrunJacob, нет, ОБРАЗЕЦ ПРОЕКТА разделен на несколько ветвей. Но я довольно давно не обновлял этот проект, так что думаю, вы столкнетесь с ошибками сборки. - person Sheikh; 25.12.2019
comment
Я попробовал это с подходом отдельного модуля и получил ошибку INSTALL_FAILED_MISSING_SHARED_LIBRARY при установке. Кто-нибудь еще столкнулся с этим? - person Sam; 28.06.2020