【问题标题】:Windows, Gradle and Cucumber combination throws an IOException upon generating reportsWindows、Gradle 和 Cucumber 组合在生成报告时抛出 IOException
【发布时间】:2019-08-01 16:55:49
【问题描述】:

我正在开发一个结合使用 Windows、Java、Groovy、Gradle 和 Cucumber 的项目。这种组合给我的 Windows 机器带来了一些我的 *NIX 同事没有遇到的问题。在运行 gradle build 时,gradle 想要输出一些报告。这些报告的位置和文件名显然是由 Cucumber 测试的定义或输出决定的。不幸的是,使用的名称不能用作文件名,所以我得到每个测试报告的 IOException。

对于 Cucumber 测试,我们使用以下结构:

  Scenario Outline: Receive and parse ReturnItem from Service
    Given The message from service return item outlined in <messagePath>
    When We process the message
    Then XXX posted a message to YYY on topic <topic> with event <eventType>
    And payload matches <resultPath>

 | messagePath               | topic      | eventType  | resultPath                 |
 | /test/testxml.xml         | test_topic | EVENT_TYPE | /result/result.json        |

运行后,我收到以下异常:

Caused by: org.gradle.api.UncheckedIOException: Could not write to file 'C:\xxx\project\build\reports\tests\test\packages\| \test\testxml.xml | test_topic | EVENT_TYPE | \result\result.html'.
        at org.gradle.internal.IoActions$TextFileWriterIoAction.execute(IoActions.java:151)
        at org.gradle.internal.IoActions$TextFileWriterIoAction.execute(IoActions.java:127)
        at org.gradle.internal.IoActions.writeTextFile(IoActions.java:45)
        at org.gradle.reporting.HtmlReportRenderer$DefaultHtmlReportContext.renderHtmlPage(HtmlReportRenderer.java:118)
        at org.gradle.api.internal.tasks.testing.report.DefaultTestReport$HtmlReportFileGenerator.run(DefaultTestReport.java:147)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.access$900(DefaultBuildOperationExecutor.java:48)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor$ParentPreservingQueueWorker.execute(DefaultBuildOperationExecutor.java:342)
        at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.runOperation(DefaultBuildOperationQueue.java:230)
        at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.access$600(DefaultBuildOperationQueue.java:172)
        at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable$1.call(DefaultBuildOperationQueue.java:209)
        at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable$1.call(DefaultBuildOperationQueue.java:203)
        at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:154)
        at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.runBatch(DefaultBuildOperationQueue.java:203)
        at org.gradle.internal.operations.DefaultBuildOperationQueue$WorkerRunnable.run(DefaultBuildOperationQueue.java:177)
        ... 3 more
Caused by: java.io.IOException: Unable to create directory 'C:\xxx\project\project-test\build\reports\tests\test\packages\| \test\testxml.xml | test_topic | EVENT_TYPE | \result'
        at org.gradle.internal.IoActions$TextFileWriterIoAction.execute(IoActions.java:141)
        ... 19 more

有人知道如何解决这个问题吗?我能想出的唯一“解决方案”是禁用报告,这可行,但更多的是一种解决方法而不是解决方案。为了禁用,我在 gradle.build 中使用了以下配置:

    apply plugin: 'java'
    apply plugin: 'groovy'

    test {
        reports {
            junitXml.enabled = false
            html.enabled = false
        }
    }

(灵感来自:How to make Gradle build produce HTML test report instead of XML default?

【问题讨论】:

    标签: java windows gradle groovy cucumber


    【解决方案1】:

    根据提供的信息,它似乎正在尝试创建一个名为:

    'C:\xxx\project\project-test\build\reports\tests\test\packages\| \test\testxml.xml | test_topic | EVENT_TYPE | \result'

    你能展示一下传入messagePath的代码吗?我怀疑您正在传递整行数据而不仅仅是messagePath(我会大胆猜测您正在对数组执行 .toString() 而不是传入数组的第一个元素)

    【讨论】:

    • 感谢您的建议,我在原帖中添加了代码。它不会将整行发布到 Cucumber 功能,只有 messagePath。我怀疑 Gradle 会提取整行,并尝试使用它来生成测试报告。
    • 可能是您正在遭受的痛苦:github.com/cucumber/cucumber-jvm/issues/468。你用的是什么版本的黄瓜/gradle?
    • 您的评论使我对 github 问题跟踪器进行了更多调查并进一步搜索。这最终使我找到了我在下面发布的解决方案。感谢您的时间和关注!
    【解决方案2】:

    我终于找到了罪魁祸首。显然,这些文件名对应于 JUnit 用于生成 Cucumber 测试报告的默认行为。在 *NIX 上,这不会带来任何问题。然而,在 Windows 上,由于Examples 中的管道,这将导致异常。 IOException 显然有些特别,因为我在互联网上发现的大多数例外都是FileNotFoundExceptions。这就解释了为什么我花了这么长时间才找到答案,我专注于异常。

    这里的解决方案是在运行 Cucumber 测试时使用以下JUnitOption 作为@CucumberOptions 注释:--filename-compatible-names

    Java 和 Spring 的代码示例如下所示:

    @RunWith(Cucumber.class)
    @CucumberOptions(junit = {"--filename-compatible-names"})
    public class CucumberRunner {
    }
    

    如果这些与操作系统相关的非破坏性选项是默认选项而不是可选选项,那就太好了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-22
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2023-02-09
      • 2019-05-15
      • 2017-11-15
      • 2023-01-31
      相关资源
      最近更新 更多