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代码中,解释方法也同样对应的引入参数,如:
运行runner类,测试通过,到此为止我们就实现了用参数化/数据驱动的形式来实现cucumber测试。