Как иметь два набора тестов в платформе JUnit в Gradle


Я использую платформу JUnit 5 через Gradle.

В моем текущем файле сборки есть пункт конфигурации

junitPlatform {
    platformVersion '1.0.0-M5'
    logManager 'java.util.logging.LogManager'
    enableStandardTestTask true

    filters {
        tags {
            exclude 'integration-test'
        }
        packages {
            include 'com.scherule.calendaring'
        }
    }
}

Это прекрасно работает. Но мне также нужно запустить интеграционные тесты, которые требуют, чтобы приложение было построено, докеризовано и запущено в фоновом режиме. Поэтому у меня должна быть вторая конфигурация, подобная этой, которая будет запущена только тогда... как этого добиться? Обычно я бы расширил тестовую задачу, создав задачу IntegrationTest, но она не подходит для платформы JUnit, где нет простой задачи ходовые испытания...

Я знаю, что мог бы сделать sth вот так

task integrationTests(dependsOn: "startMyAppContainer") {
    doLast {
        def request = LauncherDiscoveryRequestBuilder.request()
                .selectors(selectPackage("com.scherule.calendaring"))
                .filters(includeClassNamePatterns(".*IntegrationTest"))
                .build()

        def launcher = LauncherFactory.create()

        def listener = new SummaryGeneratingListener()
        launcher.registerTestExecutionListeners(listener)
        launcher.execute(request)
    }

    finalizedBy(stopMyAppContainer)
}
Но есть ли более простой способ? Более последовательный.
1 4

1 ответ:

Это еще не полностью поддерживается в Gradle с плагином JUnit5 (хотя он становится все ближе). Есть несколько обходных путей. Это тот, который я использую: он немного многословен, но он делает то же самое, что и тест maven против verify.

Различают классы тестов (unit) и интеграционных тестов.

Основные и тестовые исходные наборы Грэдла хороши сами по себе. Добавьте новый набор источников integrationTest, который описывает только ваши интеграционные тесты. Вы можете использовать имена файлов, но это может означать, что вам придется настроить набор тестовых источников, чтобы пропустить файлы, которые он в данный момент включает (в вашем примере вы хотите удалить ".* IntegrationTest " из набора тестовых источников и оставить его только в наборе integrationTest sourceSet). Поэтому я предпочитаю использовать имя корневого каталога, отличное от имени тестового набора исходных текстов.
sourceSets {
  integrationTest {
    java {
      compileClasspath += main.output + test.output
      runtimeClasspath += main.output + test.output
      srcDir file('src/integrationTest/java')
    }
    resources.srcDir file('src/integrationTest/resources')
  }
}

Так как у нас есть плагин java, это очень красиво создает функции integrationTestCompile и integrationTestRuntime для использования с dependencies блок:

dependencies {
    // .. other stuff snipped out ..
    testCompile "org.assertj:assertj-core:${assertjVersion}"

    integrationTestCompile("org.springframework.boot:spring-boot-starter-test") {
        exclude module: 'junit:junit'
    }
}

Здорово!

Добавьте интеграционное тестирование в правильное место в процессе сборки

Как вы уже отмечали, для запуска интеграционных тестов необходимо иметь задание. Вы можете использовать лаунчер, как в вашем примере; я просто делегирую его существующему консольному раннеру, чтобы воспользоваться простыми опциями командной строки.

def integrationTest = task('integrationTest',
                           type: JavaExec,
                           group: 'Verification') {
    description = 'Runs integration tests.'
    dependsOn testClasses
    shouldRunAfter test
    classpath = sourceSets.integrationTest.runtimeClasspath

    main = 'org.junit.platform.console.ConsoleLauncher'
    args = ['--scan-class-path',
            sourceSets.integrationTest.output.classesDir.absolutePath,
            '--reports-dir', "${buildDir}/test-results/junit-integrationTest"]
}

Это определение задачи включает в себя dependsOn и shouldRunAfter, чтобы убедиться, что при выполнении интеграционных тестов, модульные тесты выполняются первыми. Чтобы обеспечить выполнение интеграционных тестов при ./gradlew check, необходимо обновить задачу проверки:

check {
  dependsOn integrationTest
}

Теперь вы используете ./gradlew test like ./mvnw test, и ./gradlew check like ./mvnw verify.