在上一篇中,我们介绍了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代码中,解释方法也同样对应的引入参数,如:

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

  下一篇我们改用maven对cucumber环境进行配置并实现测试报告输出。

行为驱动:Cucumber + Selenium + Java(四) - 实现测试用例的参数化的更多相关文章

  1. 行为驱动:Cucumber + Selenium + Java(一) - 环境搭建

    1.1 什么是行为驱动测试 说起行为驱动,相信很多人听说过. 行为驱动开发-BDD(Behavior Driven Development)是一个诞生于2003年的软件开发理念.其关键思想在于通过与利 ...

  2. 行为驱动:Cucumber + Selenium + Java(二) - 第一个测试

    在上一篇中,我们搭建好了Selenium + Cucumber + Java的自动化测试环境,这一篇我们就赶紧开始编写我们的第一个BDD测试用例. 2.1 创建features 我们在新建的java项 ...

  3. 行为驱动:Cucumber + Selenium + Java(一) - Cucumber简单操作实例

    场景(Scenarios) 场景是Cucumber结构的核心之一.每个场景都以关键字“Scenario:”(或本地化一)开头,后面是可选的场景标题.每个Feature可以有一个或多个场景,每个场景由一 ...

  4. 行为驱动:Cucumber + Selenium + Java(五) - 使用maven来实现cucumber测试和报告

    在上一篇中,我们介绍了Selenium + Cucumber + Java框架下的测试用例参数化/数据驱动,这一篇我们来使用maven去搭建cucumber框架以及实现测试报告. 5.1 为什么要用m ...

  5. 行为驱动:Cucumber + Selenium + Java(三) - 使用标签实现测试分组

    在上一篇中,我们写出了Selenium + Cucumber + Java环境下的第一个BDD自动化测试用例,这一篇我们说说怎么用标签对用例进行分组. 3.1 Cucumber标签 实际工作中,我们的 ...

  6. 行为驱动:Cucumber + Selenium + Java(二) - extentreports 测试报告+jenkins持续集成

    1.extentreports 测试报告 pom文件 <dependency> <groupId>com.vimalselvam</groupId> <art ...

  7. Selenium+Java(四)Selenium Xpath元素定位

    前言 关于Selenium元素定位,这是最后一篇博客. Xpath定位可以实现的功能 Selenium+Java(三)Selenium元素定位中讲的定位方式也可以实现,具体要用那种定位方式要根据自己的 ...

  8. Selenium Java环境配置

    Selenium Java环境配置 上次配置的是C#的环境,今天主要来配置一下Java环境. 首先,对于java环境配置最基础的JDK和JRE 先前我做过配置,这里就不重述了,网上的教程超级多.在基础 ...

  9. 利用Selenium+java实现淘宝自动结算购物车商品(附源代码)

    转载请声明原文地址! 本次的主题是利用selenium+java实现结算购买购物车中的商品. 话不多说,本次首先要注意的是谷歌浏览器的版本,浏览器使用的驱动版本,selenium的jar包版本.   ...

随机推荐

  1. 第n次搭建 SSM 框架

    什么说第 N 次搭建SSM框架呢? 刚学习java的时候,搭建 SSM 框架想做一个个人项目之类的,后来没搭起来,也就拖延了,进入公司之后,接触的第一个项目就是SSM的,模仿了一下,也能搭个简简单单的 ...

  2. Numpy 基础运算2

    # -*- encoding:utf-8 -*- # Copyright (c) 2015 Shiye Inc. # All rights reserved. # # Author: ldq < ...

  3. JS 存储

    1. 描述cookie ,sessionStorage 和 localStorage 的区别? cookie : 本身用于客户端和服务器端通信, 但是有本身存储的功能,就被‘借用’ 使用documen ...

  4. python操作git

    GitPython 是一个用于操作 Git 版本库的 python 包,它提供了一系列的对象模型(库 - Repo.树 - Tree.提交 - Commit等),用于操作版本库中的相应对象. 模块安装 ...

  5. redux 与 react-redux

    Redux 一.Redux 三大原则: 1.一个应用永远只有一个数据源(整个应用状态都保存在一个对象中,Redux提供的工具函数combineReducers可以解决庞大的数据对象的问题) 2.状态是 ...

  6. Round #2

    题源:来自hzwer整理的题 2014-5-10 NOIP模拟赛 by coolyangzc Problem 1 机器人(robot.cpp/c/pas) [题目描述] 早苗入手了最新的Gundam模 ...

  7. Flutter 编写内联文本

    使用Text.rich或者RichText ListView( children: <Widget>[ Text.rich( TextSpan( text: 'Text: ', child ...

  8. Js 运行机制和Event Loop

    一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Java ...

  9. Java script 逻辑运算符

    a && b : 将a, b转换为Boolean类型, 再执行逻辑与, true返回b, false返回a 1.只要“&&”前面是false,无论“&& ...

  10. js深度复制三种方法

    1.用递归的方式进行深度复制 2.用JSON.stringify加上JSON.parse()进行深度复制 3.用jquery中自带的方法$.extend()进行深度复制 具体实现代码可百度自行查询