代码之家  ›  专栏  ›  技术社区  ›  Eduardo León

黄瓜重复利用

  •  99
  • Eduardo León  · 技术社区  · 15 年前

    我想重复使用一些黄瓜步骤,但似乎找不到正确的方法。

    我想写一个步骤,比如:

    Given /^I login with (.*) credentials$/ |type|
      # do stuff with type being one of "invalid" or "valid"
    end
    

    但接下来还有一个步骤,比如:

    Given /^I login successfully$
      # call "Given I login with valid credentials"
    end
    

    因此,在测试用户身份验证时,我可以使用前者,但在大多数其他地方,我可以使用后者,实际上不必重新编写代码。

    是否有一种方法可以调用另一个步骤,或者我只是将逻辑放在一个辅助方法中,然后从每个任务中调用所述方法(基本上是一个方法提取重构,在阅读完我的问题后,它使我相信这实际上是最好的方法)?

    5 回复  |  直到 6 年前
        1
  •  101
  •   mhutter    9 年前

    更新 :下面描述的方法已被弃用。从另一个步骤调用步骤的建议方法如下:

    Given /^I login successfully$/
        step "I login with valid credentials" 
    end 
    

    旧的、已弃用的方法(供参考):

    您可以从以下其他步骤调用步骤:

    Given /^I login successfully$/
      Given "I login with valid credentials"
      Then "I should be logged in"
    end
    

    如果某个功能中的所有场景都需要这样(或其他步骤),您还可以使用常见的步骤为每个功能添加背景,如下所示:

    Background:
      Given I log in with valid credentials
    
    Scenario: Change my password
      Given I am on the account page
    
        2
  •  102
  •   michaeltwofish    13 年前

    请注意,在Cucumber的最新版本中,步骤内调用步骤的方法已发生更改,如果在步骤定义中出现“警告:使用”given/when/then“等错误,则使用”step“来调用其他步骤:/path/to/step\definitions/foo-steps.rb:631:in“block-in” “。见 cucumber wiki 详情。

    变化的要点是你现在应该使用 step steps 方法。

    When /^I make all my stuff shiny$/
      step "I polish my first thing"
    end
    
    When /^I make all my stuff shiny$/
      steps %Q{
        When I polish my first thing
        When I shine my second thing
      }
    end
    
        3
  •  42
  •   Andrei Botalov    7 年前

    从步骤定义调用步骤是一种糟糕的实践,并且 some disadvantages :

    1. 如果场景将失败,并且存在嵌套的步骤调用,那么您将只获得堆栈跟踪中最后调用的步骤定义。可能很难找到最后一个stepdef是从哪来的
    2. 调用stepdef有时比Ruby方法更难找到和读取
    3. Ruby方法比调用step defs中的步骤更强大

    阿斯拉克·海勒 recommends 将常用动作提取到 World 而不是重复使用步骤。它将这些操作隔离在一个地方,使代码更容易找到。您也可以将代码提取到常规的Ruby类或模块中。

    #/support/world_extensions.rb
    module KnowsUser
      def login
        visit('/login')
        fill_in('User name', with: user.name)
        fill_in('Password', with: user.password)
        click_button('Log in')
      end
    
      def user
        @user ||= User.create!(:name => 'Aslak', :password => 'xyz')
      end
    end
    World(KnowsUser)
    
    #/step_definitions/authentication_steps.rb
    When /^I login$/ do
      login
    end
    
    Given /^a logged in user$/ do
      login
    end
    

    下面是关于黄瓜邮件列表中主题的有用讨论- link

        4
  •  9
  •   Rimian    12 年前

    最好用%而不是引号来包装您的步骤。那么,您不需要转义双引号,这需要经常使用。

    Given /^I login successfully$
      step %{I login with valid credentials}
    end
    
    Given /^I login with (.*) credentials$/ |type|
      # do stuff with type being one of "invalid" or "valid"
    end
    
        5
  •  1
  •   LINGS    11 年前

    在特性文件中重用关键字,这将提供代码可重用性。

    强烈建议不要在步骤defs中调用步骤defs。

    我会这样写我的功能文件,

    Scenario Outline: To check login functionality
        Given I login with "<username>" and "<password>"
        Then I "<may or may not>" login successfully
    
    Examples:
        |username|password|may or may not|
        |paul    |123$    |may           |
        |dave    |1111    |may not       |
    

    在我的步骤定义中,(这是Java)

    @Given(I login with \"([^\"]*)\" and \"([^\"]*)\"$)
    public void I_login_with_and(String username, String password){
    
       //login with username and password
    
    }
    
    @Then(I \"([^\"]*)\" login successfully$)
    public void I_login_successully_if(String validity){
    
        if(validity.equals("may")){
            //assert for valid login
        }
        else
        if(validity.equals("may not")){
            //assert for invalid login
        }
    }
    

    这样,代码就有很多可重用性。 同样的方法,然后处理有效和无效的场景。 同时,您的特性文件对读者来说是有意义的。