代码之家  ›  专栏  ›  技术社区  ›  user1559625

如何生成catch组(+?)在cucumber java中按预期工作?

  •  0
  • user1559625  · 技术社区  · 7 年前

    当我为特征文件编写黄瓜爪哇步骤时,我观察到以下内容:

    功能文件:

    Then I get result one <result1> and result two <result2> from microservice
    

    Java步骤(步进定义)

    @Then("^I get result one(.+?) and result two(.+?)$")  //step function 1
    public void i_get_result_one_and_result_two(String result1, String result2)
            throws Throwable {}
    
    @Then("^I get result one(.+?) and result two(.+?) from microservice$")  //step function 2
    public void i_get_result_one_and_result_two_from_ms(String result1, String result2)
            throws Throwable {}
    

    不知何故,特征文件总是映射到步骤函数1,而不是步骤函数2

    捕获组的定义(+?)据我所知,匹配任何一个或多个对象(我假设只匹配特征文件中的变量)。我不明白为什么它与步骤函数2不匹配。

    有人能解释一下为什么会发生这种情况,以及如何解决这个问题吗?

    多谢。

    2 回复  |  直到 7 年前
        1
  •  1
  •   KyleFairns    7 年前

    问题的解释

    因为您在这里使用regex来匹配您的步骤,所以应该注意 .+ 匹配尽可能多的字符(最少匹配1个字符)。

    这本身就意味着你的步骤:

    ^I get result one (.+?) and result two (.+?)$
    

    matching everything 从最后一个抓捕组开始。

    回答

    如果要使捕获组只与引号中的内容匹配,则应改为使用:

    ^I get result one '([^']+?)' and result two '([^']+?)'$
    

    在这里, [^']+ 表示尽可能多次匹配任何不是单引号/撇号的字符(至少匹配1个字符)

    (也可以使用双引号代替单引号)

        2
  •  0
  •   SubOptimal    7 年前

    你说得对 (.+?) 匹配一组任意字符,发生一次或多次(使用 reluctant quantifier )此组以字符串的结尾(字符串的 $ 部分的 (.+?)$ )

    模式 ^I get result one(.+?) and result two(.+?)$ 匹配两个字符串。我把括号放在匹配的部分周围。

    ^I get result one( <result1>) and result two( <result2> from microservice)$
    ^I get result one( <result1>) and result two( <result2>)$
    

    您可以改写步骤,使模式与两个句子都不匹配,也可以在步骤中包围变量字段,例如用一个引号 (必须是匹配值中永远不会出现的字符) ,分别修改模式。

    可能看起来像

    // steps
    Then I get result one '<result1>' and result two '<result2>' from microservice
    Then I get result one '<result1>' and result two '<result2>'
    
    // glue code
    @Then("^I get result one '(.+?)' and result two '(.+?)' from microservice$")
    @Then("^I get result one '(.+?)' and result two '(.+?)'$")
    

    编辑 这里有一些更详细的解释如何匹配工作。

    最初的模式 (+?) ([^']+?) 解释。这个 ? 限定符意味着搜索将从左到右吃掉字符(请参阅不情愿限定符的链接)。

    ^我得到结果一'(.+?)'结果二“(.+?)”$

    ^ --- begin of the line
    I get result one ' --- a fixed sequence
    (.+?) --- any character, one or more times (group 1)
    ' and result two ' --- a fixed sequence
    (.+?) --- any character, one or more times (group 2)
    ' --- a fixed sequence
    $ --- end of the line
    

    group 1 group 2 可以包含任何字符,包括 ' .

    ^我得到结果一'([^']+?)'结果二'([^']+?)'$

    ^ --- begin of the line
    I get result one ' --- a fixed sequence
    ([^']+?) --- any character, except the single quote, one or more times (group 1)
    ' and result two ' --- a fixed sequence
    ([^']+?) --- any character, except the single quote, one or more times (group 2)
    ' --- a fixed sequence
    $ --- end of the line
    

    很快 第1组 第2组 会包含一个 这条线不再匹配了。
    例如 I get result one '<O'Reilly>' and result two '<result2>'
    因为 第1组 将是 <O 然后模式期望固定的序列 ' and result two ' 不匹配的 'Reilly>' ... .

    一些演示片段

    Pattern pattern = Pattern.compile("^I get result one '(.+?)' and result two '(.+?)'$");
    Matcher matcher = pattern.matcher("I get result one '<result1>' and result two '<result>'");
    while (matcher.find()) {
        for (int i = 0; i <= matcher.groupCount(); i++) {
            System.out.printf("group: %d  subsequence: %s%n", i, matcher.group(i));
        }
    }
    

    输出

    group: 0  subsequence: I get result one '<result1>' and result two '<result2>'
    group: 1  subsequence: <result1>
    group: 2  subsequence: <result2>
    

    group 0 被整个表达式捕获

    Pattern pattern = Pattern.compile("^I get result one '(.+?)' and result two '(.+?)'$");
    Matcher matcher = pattern.matcher("I get result one '<O'Reilly>' and result two '<result2>'");
    

    输出

    group: 0  subsequence: I get result one '<O'Reilly>' and result two '<result2>'
    group: 1  subsequence: <O'Reilly>
    group: 2  subsequence: <result2>
    

    第1组 也匹配 因为 (+?) 它嵌入在固定序列的前后之间。

    现在排除周围字符的模式。

    Pattern pattern = Pattern.compile("^I get result one '([^']+?)' and result two '([^']+?)'$");
    Matcher matcher = pattern.matcher("I get result one '<result1>' and result two '<result2>'");
    

    输出

    组:0子序列:我得到结果1“<result1>”和结果2“<result2>”
    组:1子序列:<result1>
    组:2子序列:<result2>
    

    模式没有区别 (+?) 作为应该由 第1组 第2组 不包含 .

    Pattern pattern = Pattern.compile("^I get result one '([^']+?)' and result two '([^']+?)'$");
    Matcher matcher = pattern.matcher("I get result one '<O'Reilly>' and result two '<result2>'");
    

    没有输出,因为模式与行不匹配(请参阅上面的说明)。这也意味着黄瓜将无法找到相关的胶水方法。

    假设步骤在特征文件中定义为

    Then I get result one '<O'Reilly>' and result two '<result2>'
    

    粘合方法用

    @Then("^I get result one '([^']+?)' and result two '([^']+?)'$")
    

    运行cucumber将引发以下异常

    cucumber.runtime.junit.UndefinedThrowable: The step "I get result one '<O'Reilly>' and result two '<result2>'" is undefined