代码之家  ›  专栏  ›  技术社区  ›  Brian Postow

编写通过额外信息的黄瓜测试

  •  0
  • Brian Postow  · 技术社区  · 7 年前

    我有一个ruby on rails程序,在cucumber中进行了特性测试。

    我刚刚实现了一个功能,管理员可以为客户端用户创建一个新密码。现在,在“编辑客户端”页面上,有一个额外的按钮允许管理员设置密码。现在,我只需要做个黄瓜测试。

    我试图将此测试建立在正常的客户机更改密码测试和管理员更改用户信息测试的基础上。我有的是:

    Feature: Analyst changes client's password
      As an Analyst
      I want to change client's password
      So that I can reset the client's account
    
      Background:
        Given the following client accounts
          | email             | password |
          | user1@someorg.com | password |
        And I am logged in as an admin
    
      @javascript
      Scenario: Update a Client user
        Given I navigate to the Clients Management Page
        When I edit the Client User "user1@someorg.com"
        And I click on "button"
        Then I should be on the Clients Password Page
    
      @javascript
      Scenario: Can change password if confirmation matches
        Given I navigate to the Clients Password Page
        And I enter "Password1" as the password
        And I enter "Password1" as the password confirmation
        And I submit the form
        Then I should be taken to the Client Landing Page
        And The client's password should be "Password1"
    

    在这些步骤中,我有:

    Given /^I navigate to the Clients Password Page$/ do
      client_management_index_page = ClientsPasswordPage.new Capybara.current_session
      client_management_index_page.visit
    end
    
    Then /^I should be on the Clients Password Page$/ do
      client_password_page = ClientsPasswordPage.new Capybara.current_session
      expect(client_password_page).to be_current_page
    end
    

    以及客户页面:

    class ClientsPasswordPage
      include PageMixin
      include Rails.application.routes.url_helpers
    
      def initialize session
        initialize_page session, edit_admin_client_password_path
      end
    end
    

    除了edit_admin_client_password_path对正在编辑的用户采用:id。我不知道如何把这些信息输入其中。

    如果重要的话,我会用设备来做保安…

    2 回复  |  直到 7 年前
        1
  •  1
  •   Thomas Walpole    7 年前

    有几种方法可以做到这一点。最简单的方法是认识到在测试期间您只创建了一个客户机,所以

    Client.first # whatever class represents clients
    

    永远是那个客户。显然,如果您有创建一个以上客户机的测试,那么这是行不通的,因此您可以在cucumber步骤中创建实例变量,这些变量设置在世界上,然后可以从其他步骤访问并传递给页面对象

    When I edit the Client User "user1@someorg.com"
      @current_client = Client.find_by(email: "user1@someorg.com") # obviously would actually be a parameter to the step
      ...
    end
    
    Then /^I should be on the Clients Password Page$/ do
      client_password_page = ClientsPasswordPage.new Capybara.current_session, @current_client
      expect(client_password_page).to be_current_page
    end
    

    当然如果没有页面对象的开销

    Then /^I should be on the Clients Password Page$/ do
      expect(page).to have_current_path(edit_admin_client_password_path(@current_client))
    end
    
        2
  •  0
  •   diabolist    7 年前

    为了简化这个场景,您可以做很多事情。如果您有更简单的场景,使用更简单的步骤定义,那么将更容易解决实现问题,例如如何在一个步骤中让客户机在第二个步骤中可用。

    简化场景的主要方法是在场景中完全不包含任何解释如何实现功能的内容。如果你把所有的点击按钮、填写字段和访问页面都从你的场景中去掉,你就可以专注于业务问题。

    那怎么样

    Background
      Given there is a client
      And I am logged in as an admin
    
    Scenario: Change clients password
      When I change the clients password
      Then the client should have a new password
    

    注: 这立即引发了一个问题:“客户端如何发现新密码?”,这就是好的简单场景的作用,它们会让你提出有价值的问题。回答这个问题可能超出了范围。

    现在让我们看看实现。

    Given 'there is a client' do
      @client = create_new_client
    end
    
    When 'I change the clients password' do
      visit admin_change_password_path(@client)
      change_client_password(client: @client)
    end
    

    这也许足以让你走上正确的道路。除此之外

    Given 'I am logged in as an admin' do
      @i = create_admin_user
      login_as(user: @i)
    end
    

    会有帮助的。

    我们在这里所做的是

    1. 将how压入堆栈中,以便现在您正确执行此操作的代码不在您的场景和步骤定义中
    2. 使用变量在行的步骤之间进行通信 @client = create_new_client 创建在所有步骤定义中都可用的全局(实际上是cucumber::world的全局)变量

    您可以通过向cucumber world添加模块并在其中定义方法来创建helper方法。请注意,这些方法是全局的,因此您必须仔细考虑名称(这些方法是全局的原因非常充分)。所以

    module UserStepHelper
      def create_new_client
        ...
      end
    
      def create_admin_user
        ...
      end
    
      def change_client_password(client: )
        ...
      end
    end
    World UserStepHelper
    

    将创建可在任何步骤定义中使用的帮助器方法。

    您可以看到这种方法的一个示例 here .我在2013年cukeup演讲时用过的一个项目。也许你可以用这个作为你的教程例子。