我有一个在标准单元测试期间执行时可以正常工作的代码,但是在将其编译到jar中并添加为其他项目的依赖项时却无法工作。
找到根本原因并解决它不是问题,但是我开始思考如何在将其部署到任何地方之前测试一下刚制作的jar工件,以确保它可以用于最终用户和其他项目。我已经在这个主题上搜索了几个小时,但是甚至没有找到与之接近的东西。
也许我是完全错误的,并且试图实现一些怪异的东西,但是我无法找到另一种方法来验证已编译的软件包,并确信它会为其他人使用。
有关该项目的一些详细信息-简单的Java库,只有很少的类,使用Gradle 5.5作为构建系统,使用travis-ci作为CI / CD工具,用于测试我使用的是TestNG,但如果使用它,我可以轻松切换到JUnit将是必需的。
如果您对代码感到好奇,当将其编译到程序包中时该代码不起作用,这里是简化版本:
public String readResourceByURI() throws IOException, URISyntaxException
{
new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemClassLoader().getResource("resource.txt").toURI())));
}
如果打包到jar文件中,则此函数将引发java.nio.file.FileSystemNotFoundException。但是正如我说的,问题不在于代码...
理想情况下,我想创建一个生成管道,该管道将生成jar工件,然后将对其进行测试,如果测试成功,这些jar将自动部署到存储库(maven和/或bintray)。
目前,所有测试都在创建jar之前执行,因此有可能由于打包而无法在jar包中编译代码。
因此,为了简化我的问题,我正在寻找一种Gradle配置,该配置可以对新制作的jar文件执行单元测试。
答案 0 :(得分:0)
在Gradle中,您可以尝试执行一些脚本任务,这些脚本任务从jar中运行代码。或复杂但简单的POC均可。 在主gradle项目中,创建子项目“ child”。 在settings.gradle中添加有关它的信息:
include 'child'
在build.gradle中添加以下内容:
task externalTest {
copy {
from 'src/test'
into './child/src/test'
}
}
externalTest.dependsOn(':child:build')
jar.doLast {
externalTest
}
然后在child / settings.gradle的依赖项中添加父级jar:
compile files('../build/libs/parent.jar')
现在在构建的主项目中,子项目将在jar创建之后构建。
答案 1 :(得分:0)
我认为没有一种好的方法可以在单元测试中检测到此类问题。这是一种通常在集成测试中发现的问题。
如果您的工件/交付物是一个库,那么集成测试通常没有多大意义。但是,您可以花一些时间来创建一个使用您的库的示例或测试应用程序,然后您可以为其编写集成测试。
您需要问问自己,是否存在足够的此类潜在错误以保证做到这一点:
也许实用的答案是认识到您不能(或负担不起)测试所有内容。
已经说过,一种可能的方法可能是选择一个独立的测试运行器(打包为非GUI Java应用程序)。然后,让Gradle以脚本任务的形式运行测试运行程序,并为您的库提供JAR,并在类路径上进行单元测试。
答案 2 :(得分:0)
这就是我想出的:
test {
// Add dependency on jar task, since it will be main target for testing
dependsOn jar
// Rearrange test classpath, add compiled JAR instead of main classes
classpath = project.sourceSets.test.output + configurations.testRuntimeClasspath + files(jar.archiveFile)
useTestNG()
}
在这里,我通过将文件夹与测试类,运行时依赖项和已编译的JAR文件结合起来,来更改测试任务的默认类路径。不确定这样做是否正确...