You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Gradle运行Cucumber测试时出现NoTestsDiscoveredException错误求助

解决Gradle运行Cucumber测试时的NoTestsDiscoveredException错误

问题现象

运行Gradle Cucumber测试时抛出异常:

org.junit.platform.suite.engine.NoTestsDiscoveredException: Suite [features.selenium.runner.RunCucumberTest] did not discover any tests

用户提供的配置与代码如下:

Gradle配置文件 (build.gradle)

plugins {
    id "io.freefair.lombok" version "6.5.0.3"
    id 'java'
    id 'application'
}

group 'org.example'
version '1.0-SNAPSHOT'
java.sourceCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_17

repositories {
    mavenCentral()
}

dependencies {

    // https://mvnrepository.com/artifact/io.appium/java-client
    implementation 'io.appium:java-client:8.5.1'

    //Http client library
    implementation 'org.apache.httpcomponents:httpclient:4.5.14'

    //Jackson utility library to parse POJO to JSON
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'

    //Selenium Framework Library
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.11.0'

    //Library for random string generation in TestEventDataInitializer.java
    implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'

    // Testing frameworks and libraries

    implementation 'org.assertj:assertj-core:3.23.1'
    testImplementation 'org.assertj:assertj-core:3.23.1'

    // Cucumber
    testImplementation(platform("org.junit:junit-bom:5.10.0"))
    testImplementation(platform("io.cucumber:cucumber-bom:7.13.0"))
    testImplementation("io.cucumber:cucumber-java")
    testImplementation("io.cucumber:cucumber-junit-platform-engine")
    testImplementation("org.junit.platform:junit-platform-suite")
    testImplementation("org.junit.jupiter:junit-jupiter")



    // Logging libraries
    testImplementation 'org.codehaus.janino:janino:3.1.9'
    implementation 'org.codehaus.janino:janino:3.1.9'

    testImplementation 'ch.qos.logback:logback-classic:1.4.5'
    implementation 'ch.qos.logback:logback-classic:1.4.5'

    testImplementation 'ch.qos.logback:logback-core:1.4.5'
    implementation 'ch.qos.logback:logback-core:1.4.5'

    // General purpose libraries
    implementation 'io.vavr:vavr:1.0.0-alpha-4'

    //CSV files handler
    implementation 'com.opencsv:opencsv:5.7.1'

    // https://mvnrepository.com/artifact/io.qameta.allure/allure-junit5
    testImplementation 'io.qameta.allure:allure-junit5:2.23.0'

    //RestAssured libs

    // https://mvnrepository.com/artifact/org.hamcrest/hamcrest
    testImplementation 'org.hamcrest:hamcrest:2.2'

    // https://mvnrepository.com/artifact/io.rest-assured/rest-assured
    testImplementation 'io.rest-assured:rest-assured:5.3.1'


}
wrapper {
    gradleVersion = "8.0"
}
test {
    reports {
        junitXml.destination = file("$buildDir/junitreports")
    }
    systemProperties = System.properties

    useJUnitPlatform { config ->
        def device = System.getProperty('device', '').toLowerCase()
        def scope = System.getProperty('scope', '').toLowerCase()

        def handleE2ETestsForDevice = { deviceType ->
            switch (deviceType) {
                case 'android':
                    config.excludeTags 'Windows'
                    config.includeTags 'Android'
                    break
                case 'windows':
                    config.excludeTags 'Android'
                    config.includeTags 'Windows'
                    break
                default:
                    println "Warning: Unknown device '${deviceType}' for E2E tests. Running all E2E tests."
                    break
            }
        }
        switch (scope) {
            case 'e2e':
                handleE2ETestsForDevice(device)
                break
            case 'api':
                config.includeTags 'API'
                break
            default:
                println "Warning: Unknown scope '${scope}'. Running all tests."
                break
        }
    }
}

Cucumber运行类 (RunCucumberTest.java)

package features.selenium.runner;


import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;

import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;

@Suite
@IncludeEngines("cucumber")
@SelectClasspathResource("features")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "features.selenium.stepdefinition")
public class RunCucumberTest {
}

步骤定义类 (SimpleTest.java)

package features.selenium.stepdefinition;

import static org.assertj.core.api.Assertions.assertThat;

import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class SimpleTest {

  @When("Test")
  public void passOn() {
    assertThat("test").isEqualTo("test");
    System.out.println("TEST");
  }

  @Then("First simple test with Cucumber")
  public void passMe() {
    assertThat("test").isEqualTo("test");
    System.out.println("TEST");
  }
}

解决方案

1. 确保Feature文件路径与内容匹配

  • 将.feature文件放置在src/test/resources/features目录下,与@SelectClasspathResource("features")配置对应。
  • Feature文件的语句必须和步骤定义的注解文本完全一致,示例内容:
    Feature: Basic Cucumber Test
      Scenario: Execute simple steps
        When Test
        Then First simple test with Cucumber
    

2. 修复Gradle测试任务的标签过滤逻辑

当前配置中,未指定scope或device时,默认分支没有明确允许无标签的测试,导致Cucumber测试被过滤。修改test任务的逻辑:

  • 在handleE2ETestsForDevice的default分支添加config.includeTags '':
    default:
        println "Warning: Unknown device '${deviceType}' for E2E tests. Running all E2E tests."
        config.includeTags '' // 允许无标签测试
        break
    
  • 在scope的default分支添加config.includeTags '':
    default:
        println "Warning: Unknown scope '${scope}'. Running all tests."
        config.includeTags '' // 允许无标签测试
        break
    

3. 确认测试类位置

确保RunCucumberTest类位于src/test/java目录下,Gradle默认只编译该目录下的类到测试类路径,若放在src/main/java会无法被识别。

4. 清理依赖缓存并重新构建

执行以下命令清理缓存、重新同步依赖并构建:

./gradlew clean build --refresh-dependencies

内容的提问来源于stack exchange,提问作者Pawel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:37:33