空手道测试不一致地通过或失败

时间:2020-06-02 20:52:04

标签: java integration-testing karate

我将Karate与Gradle结合使用,并具有8个功能文件,这些文件测试了我的Spring Boot API的读取/获取功能。

我看到这些测试以某种相当随机的方式失败了。 失败与授权有关,但是我看不到任何错误。

这是一个例子,

这失败了

Feature: Get Objectives

  Background:
    * url baseUrl
    * def objectiveEndpoint = '/objectives'
    * header Authorization = token

  Scenario: Get an Objective that exists

    Given path objectiveEndpoint + '/37376564-3139-6232-2d66-6631392d3466'
    When method GET
    Then status 200
    And match response contains { objectiveId: '37376564-3139-6232-2d66-6631392d3466' }

这成功了

Feature: Get Assessments

  Background:
    * url baseUrl
    * def assessmentEndpoint = '/assessments'
    * header Authorization = token

  Scenario: Get an assessment that exists

    Given path assessmentEndpoint + '/2900b695-d344-4bec-b25d-524f6b22a93a'
    When method GET
    Then status 200
    And match response contains { odiAssessmentId: '2900b695-d344-4bec-b25d-524f6b22a93a' }

客观测试由于401并显示以下消息而失败:

com.intuit.karate.exception.KarateException: objectives-read.feature:12 - status code was: 401, expected: 200, response time: 74, url: http://localhost:8080/objectives/37376564-3139-6232-2d66-6631392d3466, response: {"path":"/objectives/37376564-3139-6232-2d66-6631392d3466","error":"Unauthorized","message":"Unauthorized","timestamp":"2020-06-02T08:04:57.231+0000","status":401}

评估考试通过。

我通过运行授权功能来获得令牌,并将结果存储到令牌变量中。

身份验证功能为:

Feature: Log In

  Background:
    * url 'https://$URL/oauth/token'
    * def localSecret = secret
    * def localClientId = clientId

  Scenario: Get token
    Given url 'https://$URL/oauth/token'
    And form field grant_type = 'client_credentials'
    And form field client_id = localClientId
    And form field client_secret = localSecret
    And form field audience = 'http://localhost:8080'
    When method post
    Then status 200
    And match response contains { access_token: '#string' }
    And def access_token = $.access_token

然后我将令牌添加到config中,并将其传递给每个测试,如下所示:

var result = karate.callSingle('classpath:login.feature', config);
    config.token = 'Bearer ' + result.access_token;

我已经确认以上两个功能中使用的令牌有效。我已经用失败测试的输出中打印的令牌手动测试了我的API,并且当我在Postman中重新创建它们时,上述两个测试都可以正常工作。这对我的API来说似乎不是问题,因为如果我重新运行测试套件,则失败的测试会有所不同,并且在我的CI上,这些测试会生成绿色版本。

像这样分别运行测试套件时,我都遇到了这个问题:

@Karate.Test
    Karate testAssessments() {
        return Karate.run().relativeTo(AssessmentsRunner.class);
    }

,当我像这样并行运行所有测试时:

public class SpecTestParallel {
    public static void generateReport(String karateOutputPath) {
        Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[]{"json"}, true);
        List<String> jsonPaths = new ArrayList(jsonFiles.size());
        jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
        Configuration config = new Configuration(new File("target"), "Test API");
        ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
        reportBuilder.generateReports();
    }

    @Test
    void testParallel() {
        Results results = Runner.path("classpath:specTests").tags("~@ignore").parallel(5);
        generateReport(results.getReportDir());
        assertEquals(0, results.getFailCount(), results.getErrorMessages());
    }
}

有人以前有过类似的问题吗?

1 个答案:

答案 0 :(得分:1)

事实证明,这是IntelliJ中的意外行为。

因此,空手道似乎有重试政策。如果测试失败,它将重试几次。

当我使用IntelliJ中的测试运行器功能运行测试时,每次测试失败时,IntelliJ都会将其记录在测试运行器窗口中,以进行失败的测试,但空手道会继续运行,重试并通过测试。我现在可以在报告中看到这一点,但是IntelliJ测试运行程序没有更新。

这会导致令人困惑的情况,即测试通过但似乎在本地失败,但是测试通过了CI。

以下是本地测试的示例:

local-tests

并在CI中传递相同的提交:

ci-tests

我真的不确定这里有什么解决方法(如果有的话)。如果IntelliJ意识到了这种行为,那将是很好的选择,或者空手道只能在处理完所有重试后才报告测试结果-现在看起来像空手道一样在第一次测试运行后就报告了。

这真是令人困惑的几天。