如何使用Gradle

时间:2019-07-03 10:28:06

标签: java testing gradle travis-ci

我有一个在标准单元测试期间执行时可以正常工作的代码,但是在将其编译到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文件执行单元测试。

3 个答案:

答案 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)

我认为没有一种好的方法可以在单元测试中检测到此类问题。这是一种通常在集成测试中发现的问题。

如果您的工件/交付物是一个库,那么集成测试通常没有多大意义。但是,您可以花一些时间来创建一个使用您的库的示例或测试应用程序,然后您可以为其编写集成测试。

您需要问问自己,是否存在足够的此类潜在错误以保证做到这一点:

  • 我不认为您会很快再次犯这个特殊错误。
  • 这种性质的其他问题可能包括您的库中关于OS平台或Java版本的假设……只能通过在不同平台上运行应用程序才能真正进行测试。

也许实用的答案是认识到您不能(或负担不起)测试所有内容。


已经说过,一种可能的方法可能是选择一个独立的测试运行器(打包为非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文件结合起来,来更改测试任务的默认类路径。不确定这样做是否正确...