行为驱动:Cucumber + Selenium + Java (四) - 实现测试用例的参数化

在上一篇中,我们介绍了 Selenium + Cucumber + Java 框架下的使用 Tags 对测试用例分组的实现方法,这一篇我们用数据表格来实现测试用例参数化。

4.1 什么是用例参数化

  实际测试中,我们可能经常会去测试几个类似的场景,或者一些大同小异的测试点。

  比如说,测试用户登录的过程中,为了满足测试的完整性,我们会要通过等价类划分等基本方法,去测试登录系统对于有效类--正确的用户名密码;和无效类--错误的用户名密码等场景。

  这一些场景的前序步骤都很类似,如果我们对于每一个这样的用例都从头到尾按照我们之前的例子那样,从 gherkin 的用例编写,到 Java 代码的解释这么写下来,代码量会很多而且没有必要。

  所以我们就要想,对于这样的测试,我们能不能将他们集合在一起,用参数化或者数据驱动的方式去实现?

4.2 Cucumber 的数据驱动

  我们直接去我们的代码里新建一个 test.feature 特性文件,如果 eclipse 的 cucumber 插件正确安装的话,那么不但这个文件会有独特的外观,你还会发现文件中自带了对于 gherkin 用例的一个模板:

#Author: your.email@your.domain.com
#Keywords Summary :
#Feature: List of scenarios.
#Scenario: Business rule through list of steps with arguments.
#Given: Some precondition step
#When: Some key actions
#Then: To observe outcomes or validation
#And,But: To enumerate more Given,When,Then steps
#Scenario Outline: List of steps for data-driven as an Examples and <placeholder>
#Examples: Container for s table
#Background: List of steps run before each of the scenarios
#""" (Doc Strings)
#| (Data Tables)
#@ (Tags/Labels):To group Scenarios
#<> (placeholder)
#""
## (Comments)
#Sample Feature Definition Template
@tag
Feature: Title of your feature
  I want to use this template for my feature file

  @tag1
  Scenario: Title of your scenario
    Given I want to write a step with precondition
    And some other precondition
    When I complete action
    And some other action
    And yet another action
    Then I validate the outcomes
    And check more outcomes

  @tag2
  Scenario Outline: Title of your scenario outline
    Given I want to write a step with <name>
    When I check for the <value> in step
    Then I verify the <status> in step

    Examples: 
      | name  | value | status  |
      | name1 |     5 | success |
      | name2 |     7 | Fail    |

 

  我们可以看到,@tag2 这个标签标记的测试用例用了一种我们之前没有用过的格式来组织用例,并且下面还有一个 Examples 表格。这就是 cucumber 自带的数据驱动表格。

  下面我们就用这种形式来实现数据驱动和参数化。

4.3 编写参数化的 feature 特性文件

  我们来实现之前提到的登录测试。

  先在 features 文件夹底下新建一个名为 testLogin.feature 的特性文件。文件中写入如下 gherkin 代码:

@tag
Feature: Test login feature of lemfix
  I want to use this case to test login functionality

  @tag1
  Scenario Outline: Test login feature of lemfix
    Given I navigated to lemfix site
    When I input “<username>” and “<password>” to login
    Then I verify login “<result>”

    Examples: 
      | username        | password  | result  |
      | vincent20181030 | password1 | success |
      | vincent20000000 | password1 | fail    |

  这里我们在一个用例里,用数据表格的方式,分别想去测试用户登录成功/失败的案例。数据表格的第一行是存在的用户名和密码,预计登录成功;而第二行的用户是不存在,预计登录失败。

4.4 将 feature 进行步骤定义

  在 stepDefinitions 文件夹下新建 TestLogin.java,写入如下代码:

package stepDefinitions;

import static org.testng.Assert.assertTrue;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;

import cucumber.api.PendingException;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class TestLemfix {
    WebDriver driver;
    
    
    @Given("^I navigated to lemfix site$")
    public void i_navigated_to_lemfix_site() throws Throwable {
        driver = new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.manage().window().maximize();
        
        driver.get("http://fm.lemfix.com");
    }

    @When("^I input \"([^\"]*)\" and \"([^\"]*)\" to login$")
    public void i_input_vincent_and_password_to_login(String us_name, String us_psswd) throws Throwable {
        WebElement loginTop;
        WebElement username;
        WebElement password;
        WebElement loginBTN;
        
        loginTop = driver.findElement(By.xpath("html/body/div[1]/div/div[3]/ul/li[2]/a"));
        loginTop.click();
        
        username = driver.findElement(By.id("user_login"));
        password = driver.findElement(By.id("user_password"));
        loginBTN = driver.findElement(By.xpath(".//*[@id='new_user']/div[4]/input"));
        
        username.sendKeys(us_name);
        password.sendKeys(us_psswd);
        loginBTN.click();
        
        Thread.sleep(1000);
    }

    @Then("^I verify login \"([^\"]*)\"")
    public void i_verify_login_result(String rs) throws Throwable {
        String title = driver.getTitle();
        String result;
        if(title.contains("登录")){
            result = "fail";
        }else if(title.equals("Lemfix")){
            result = "success";
        }else{
            result = null;
        }
        System.out.println(title);
        System.out.println("result=" + result);
        Assert.assertTrue(result.equals(rs));
        
        Thread.sleep(1000);
        driver.quit();
    }
}

  注意在 Java 代码中,解释方法也同样对应的引入参数,如:

image.png

  运行 runner 类,测试通过,到此为止我们就实现了用参数化/数据驱动的形式来实现 cucumber 测试。

回帖
请输入回帖内容 ...