Gradle测试套件用于相同测试源集的不同过滤器

jjhzyzn0  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(81)

我尝试使用jvm-test-suite为我的Kotlin和spring-boot项目设置一个gradle integrationTest测试套件。我希望所有测试套件都只有一个源代码集(即src/test),每个套件都将过滤它实际运行的测试。
这是我的尝试:

@Suppress("UnstableApiUsage")
testing {
  suites {
    configureEach {
      if (this is JvmTestSuite) {
        useJUnitJupiter()
        dependencies {
          implementation("org.springframework.boot:spring-boot-starter-test")
          implementation("io.projectreactor:reactor-test")
          implementation("org.springframework.security:spring-security-test")
          implementation("io.mockk:mockk:1.13.5")
          implementation("com.ninja-squad:springmockk:4.0.0")
          implementation("org.testcontainers:junit-jupiter")
          implementation("org.testcontainers:r2dbc")
          implementation("org.testcontainers:postgresql")
        }
        targets {
          all {
            testTask.configure {
              /* See https://mockk.io/doc/md/jdk16-access-exceptions.html
                 "Note: this includes creating @SpyKBean on spring data repository instances,
                 because they are instances of java.lang.reflect.Proxy in fact."
                 "Add JVM argument --add-opens java.base/full.package.name=ALL-UNNAMED for each
                 package you need to mock. Package name should be fully qualified." */
              jvmArgs = listOf("--add-opens=java.base/java.lang.reflect=ALL-UNNAMED")
            }
          }
        }
      }
    }
    val test by getting(JvmTestSuite::class) {
      useJUnitJupiter()

      targets {
        all {
          testTask.configure {
            minHeapSize = "512m"
            maxHeapSize = "2048m"
            finalizedBy(tasks.jacocoTestReport)
            filter {
              excludeTestsMatching("*Integration*Test")
              excludeTestsMatching("*.integration.*")
              excludeTestsMatching("*Repository*Test")
              excludeTestsMatching("*Controller*Test")
            }
          }
        }
      }
    }

    register<JvmTestSuite>("integrationTest") {
      useJUnitJupiter()
      sources {
        java {
          setSrcDirs(test.sources.java.srcDirs)
        }
        kotlin {
          setSrcDirs(test.sources.kotlin.srcDirs)
        }
        resources {
          setSrcDirs(test.sources.resources.srcDirs)
        }
        compileClasspath += test.sources.compileClasspath + project.sourceSets["main"].compileClasspath
        runtimeClasspath += test.sources.runtimeClasspath + project.sourceSets["main"].runtimeClasspath
      }
      dependencies {
        implementation(project)
      }

      targets {
        all {
          testTask.configure {
            shouldRunAfter(test)
            filter {
              includeTestsMatching("*IntegrationTest")
            }
          }
        }
      }
    }
  }
}

但是当运行./gradlew testIntegration时,我得到了一个编译错误,抱怨internal类的使用:

e: file:///some/path/src/test/kotlin/my/company/somepackage/SomeTest.kt:145:62 Cannot access 'SomeClassB': it is internal in 'SomeClassA'

这就是我的类定义的相似之处

@Component
class SomeClassA(
 val transactionManager: ReactiveTransactionManager,
) {
  internal data class SomeClassB(
    val foo: Int,
  )
 // ...
}

我目前仍在使用gradle 7.4.2,./gradlew test做我想做的事情(运行所有测试,但排除的测试)。

kse8i1jr

kse8i1jr1#

this answer中,我想到了将以下内容添加到sources配置中,使其工作:

val compilations = project
      .extensions
      .getByType(KotlinJvmProjectExtension::class.java).target.compilations
    compilations.getByName(sources.name)
      .associateWith(compilations.getByName(SourceSet.MAIN_SOURCE_SET_NAME))

所以完整的配置看起来像:

register<JvmTestSuite>("integrationTest") {
  useJUnitJupiter()
  sources {
    java {
      setSrcDirs(test.sources.java.srcDirs)
    }
    kotlin {
      setSrcDirs(test.sources.kotlin.srcDirs)
    }
    resources {
      setSrcDirs(test.sources.resources.srcDirs)
    }
    compileClasspath += test.sources.compileClasspath + project.sourceSets["main"].compileClasspath
    runtimeClasspath += test.sources.runtimeClasspath + project.sourceSets["main"].runtimeClasspath

    // make internal classes available to tests
    val compilations = project
      .extensions
      .getByType(KotlinJvmProjectExtension::class.java).target.compilations
    compilations.getByName(sources.name)
      .associateWith(compilations.getByName(SourceSet.MAIN_SOURCE_SET_NAME))
  }
  dependencies {
    implementation(project)
  }

  targets {
    all {
      testTask.configure {
        filter {
          includeTestsMatching("*IntegrationTest")
        }
      }
    }
  }
}

相关问题