Selenium WebDriver 数据驱动测试框架,以QQ邮箱添加联系人为示例,测试框架结构如下图:

ObjectMap.java

/**
* 使用配置文件存储测试页面上的定位和定位表达式,做到定位数据和程序的分离
*/
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.openqa.selenium.By; public class ObjectMap { Properties properties; public ObjectMap(String propFile) {
properties = new Properties();
try {
FileInputStream in = new FileInputStream(propFile);
properties.load(in);
in.close();
} catch (IOException e) {
System.out.println("读取对象文件出错");
e.printStackTrace();
}
} public By getLocator(String ElementNameInpopFile) throws Exception {
// 根据变量ElementNameInpopFile,从属性配置文件中读取对应的配置对象
String locator = properties.getProperty(ElementNameInpopFile); // 将配置对象中的定位类型存储到locatorType变量,将定位表达式的值存储到locatorValue变量中
String locatorType = locator.split(":")[0];
String locatorValue = locator.split(":")[1]; // 在Eclipse中的配置文件均默认为ISO-8859-1编码存储,使用getBytes方法可以将字符串编码转换为UTF-8编码,以此来解决在配置文件读取中文乱码的问题
locatorValue = new String(locatorValue.getBytes("ISO-8859-1"), "UTF-8");
// 输出locatorType变量值和locatorValue变量值,验证是否赋值正确
System.out.println("获取的定位类型:" + locatorType + "\t 获取的定位表达式:" + locatorValue); // 根据locatorType的变量值内容判断返回何种定位方式的By对象
if (locatorType.toLowerCase().equals("id")) {
return By.id(locatorValue);
} else if (locatorType.toLowerCase().equals("name")) {
return By.name(locatorValue);
} else if ((locatorType.toLowerCase().equals("classname")) || (locatorType.toLowerCase().equals("class"))) {
return By.className(locatorValue);
} else if ((locatorType.toLowerCase().equals("tagname")) || (locatorType.toLowerCase().equals("tag"))) {
return By.className(locatorValue);
} else if ((locatorType.toLowerCase().equals("linktext")) || (locatorType.toLowerCase().equals("link"))) {
return By.linkText(locatorValue);
} else if (locatorType.toLowerCase().equals("partiallinktext")) {
return By.partialLinkText(locatorValue);
} else if ((locatorType.toLowerCase().equals("cssselector")) || (locatorType.toLowerCase().equals("css"))) {
return By.cssSelector(locatorValue);
} else if (locatorType.toLowerCase().equals("xpath")) {
return By.xpath(locatorValue);
} else {
throw new Exception("输入的 locator type 未在程序中被定义:" + locatorType);
}
}
}

Constant.java

public class Constant {

    //测试网址常量
public static final String URL = "http://mail.qq.com"; //测试数据EXCEL路径
public static final String TestDataExcelFilePath = "f:\\QQ邮箱的测试数据.xlsx"; //EXCEL测试数据sheet名称
public static final String TestDataExcelFileSheet = "新建联系人测试用例";
}

ExcelUntil.java

package until;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelUntil { private static XSSFSheet excelWSheet;
private static XSSFWorkbook excelWBook;
private static XSSFCell cell;
private static XSSFRow row; //指定要操作的excel文件的路径及sheet名称
public static void setExcelFile(String path,String sheetName) throws Exception{ FileInputStream excelFile;
try {
excelFile = new FileInputStream(path);
excelWBook = new XSSFWorkbook(excelFile);
excelWSheet = excelWBook.getSheet(sheetName);
} catch (Exception e) {
e.printStackTrace();
}
} //读取excel文件指定单元格数据(此方法只针对.xlsx后辍的Excel文件)
public static String getCellData(int rowNum,int colNum) throws Exception{
try {
//获取指定单元格对象
cell = excelWSheet.getRow(rowNum).getCell(colNum);
//获取单元格的内容
//如果为字符串类型,使用getStringCellValue()方法获取单元格内容,如果为数字类型,则用getNumericCellValue()获取单元格内容
String cellData = cell.getStringCellValue();
return cellData;
} catch (Exception e) {
return "";
}
} //在EXCEL的执行单元格中写入数据(此方法只针对.xlsx后辍的Excel文件) rowNum 行号,colNum 列号
public static void setCellData(int rowNum,int colNum,String Result) throws Exception{
try {
//获取行对象
row = excelWSheet.getRow(rowNum);
//如果单元格为空,则返回null
cell = row.getCell(colNum);
if(cell == null){
cell=row.createCell(colNum);
cell.setCellValue(Result);
}else{
cell.setCellValue(Result);
}
FileOutputStream out = new FileOutputStream(Constant.TestDataExcelFilePath);
//将内容写入excel中
excelWBook.write(out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
} //从EXCEL文件中获取测试数据
public static Object[][] getTestData(String excelFilePath,String sheetName) throws IOException{
//声明一个file文件对象
File file = new File(excelFilePath);
//创建一个输入流
FileInputStream in = new FileInputStream(file);
//声明workbook对象
Workbook workbook = null;
//判断文件扩展名
String fileExtensionName = excelFilePath.substring(excelFilePath.indexOf("."));
if(fileExtensionName.equals(".xlsx")){
workbook = new XSSFWorkbook(in);
}else {
workbook = new HSSFWorkbook(in);
} //获取sheet对象
Sheet sheet = workbook.getSheet(sheetName);
//获取sheet中数据的行数,行号从0始
int rowCount = sheet.getLastRowNum()-sheet.getFirstRowNum(); List<Object[]> records = new ArrayList<Object[]>();
//读取数据(省略第一行表头)
for(int i=1; i<rowCount+1; i++){
//获取行对象
Row row = sheet.getRow(i);
System.out.println(">>>>>>>>>>> "+ row.getLastCellNum());
//声明一个数组存每行的测试数据,excel最后两列不需传值
String[] fields = new String[row.getLastCellNum()-2];
//excel倒数第二列为Y,表示数据行要被测试脚本执行,否则不执行
if(row.getCell(row.getLastCellNum()-2).getStringCellValue().equals("Y")){
for(int j=0; j<row.getLastCellNum()-2; j++){
//判断单元格数据是数字还是字符
//fields[j] = row.getCell(j).getCellTypeEnum() == CellType.STRING ? row.getCell(j).getStringCellValue() : ""+row.getCell(j).getNumericCellValue();
fields[j] = row.getCell(j).getCellType() == CellType.STRING ? row.getCell(j).getStringCellValue() : ""+row.getCell(j).getNumericCellValue();
}
records.add(fields);
}
}
//将list转为Object二维数据
Object[][] results = new Object[records.size()][];
//设置二维数据每行的值,每行是一个object对象
for(int i=0; i<records.size(); i++){
results[i]=records.get(i);
}
return results;
} public static int getLastColumnNum(){
//返回数据文件最后一列的列号,如果有12列则返回11
return excelWSheet.getRow(0).getLastCellNum()-1;
}
}

Log.java

package until;

import org.apache.log4j.Logger;

public class Log {

    // 初始化Log4j日志
private static Logger Log = Logger.getLogger(Log.class.getName()); // 打印测试用例开头的日志
public static void startTestCase(String sTestCaseName) {
Log.info("------------------ " + sTestCaseName + " " +"开始执行 ------------------");
} //打印测试用例结束的日志
public static void endTestCase(String sTestCaseName) {
Log.info("------------------ " + sTestCaseName + " " +"测试执行结束 ---------------"); } public static void info(String message) {
Log.info(message);
} public static void warn(String message) {
Log.warn(message);
} public static void error(String message) {
Log.error(message);
} public static void fatal(String message) {
Log.fatal(message);
} public static void debug(String message) {
Log.debug(message);
} }

LoginPage.java

package pageobject;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import until.ObjectMap; public class LoginPage { private WebElement element = null;
//指定页面元素定位表达式配置文件的绝对路径
private ObjectMap objectMap = new ObjectMap("F:\\workspace\\TestNGProj\\ObjectMap.properties");
private WebDriver driver; public LoginPage(WebDriver driver){
this.driver = driver;
} //返回登录页面中的用户名输入框页面元素对象
public WebElement username() throws Exception{
element =driver.findElement(objectMap.getLocator("QQ.Email.username"));
return element;
} //返回登录页面中的密码输入框页面元素对象
public WebElement password() throws Exception {
element = driver.findElement(objectMap.getLocator("QQ.Email.password"));
return element;
} //返回登录页面中的登录按钮页面元素对象
public WebElement login_button() throws Exception {
element = driver.findElement(objectMap.getLocator("QQ.Email.login_button"));
return element;
}
}

HomePage.java

package pageobject;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import until.ObjectMap; public class HomePage { private WebElement element = null;
private ObjectMap objectMap = new ObjectMap("F:\\workspace\\TestNGProj\\ObjectMap.properties");
private WebDriver driver; public HomePage(WebDriver driver){
this.driver = driver;
} //获取登录后主页的“通讯录”链接
public WebElement addressLink() throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.homepage.address_book"));
return element;
}
}

AddressBookPage.java

package pageobject;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement; import until.ObjectMap; public class AddressBookPage { private WebElement element = null;
private ObjectMap objectMap = new ObjectMap("F:\\workspace\\TestNGProj\\ObjectMap.properties");
private WebDriver driver; public AddressBookPage(WebDriver driver){
this.driver = driver;
} //获取新建联系人按钮
public WebElement addContactButton() throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_button"));
return element;
} //新建联系人页面姓名输入框
public WebElement addContactName()throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_Contact"));
return element;
} //新建联系人页面邮件输入框
public WebElement addContactEmail() throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_email"));
return element;
} //新建联系人页面电话输入框
public WebElement addContactTell() throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_tell"));
return element;
} //新建联系人页面国家输入框
public WebElement addContactCounty() throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_country"));
return element;
} //新建联系人页面省份输入框
public WebElement addContactProvince() throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_province"));
return element;
} //新建联系人页面城市输入框
public WebElement addContactCity() throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.add_city"));
return element;
} //新建联系人页面保存按钮
public WebElement addContactSaveButton() throws Exception{
element = driver.findElement(objectMap.getLocator("QQEmail.addressBook.save_button"));
return element;
}
}

LoginAction.java

package appmodules;

import org.openqa.selenium.WebDriver;
import org.testng.annotations.Test;
import pageobject.LoginPage;
import until.Log; /**
* 登录方法的封装,方便其他测试脚本的调用
*
*/
public class LoginAction { public static void execute(WebDriver driver,String userName,String passWord) throws Exception{
Log.info("访问网址:http://mail.qq.com");
driver.get("http://mail.qq.com");
driver.switchTo().frame("login_frame");
LoginPage loginPage = new LoginPage(driver);
loginPage.username().clear();
Log.info("在QQ邮箱登录页面的用户名输入框中输入 "+userName);
loginPage.username().sendKeys(userName);
Log.info("在QQ邮箱登录页面的密码输入框中输入 "+passWord);
loginPage.password().sendKeys(passWord);
Log.info("单击登录页面的登录按钮");
loginPage.login_button().click();
//Thread.sleep(5000);
}
}

AddContactAction.java

package appmodules;

import org.openqa.selenium.WebDriver;
import pageobject.AddressBookPage;
import pageobject.HomePage;
import until.Log; public class AddContactAction { public static void execute(
WebDriver driver,
String userName,
String passWord,
String contactName,
String contactEmail,
String contactCountry,
String contactProvince,
String contactCity) throws Exception{
//调用登录方法
Log.info("调用LoginAction类的execute方法");
LoginAction.execute(driver, userName, passWord);
Thread.sleep(3000); HomePage homePage = new HomePage(driver);
Log.info("登录后,单击通讯录链接");
homePage.addressLink().click();
driver.switchTo().frame("mainFrame"); AddressBookPage addressBookPage = new AddressBookPage(driver);
Log.info("休眠3秒,等待打开通讯录页面");
Thread.sleep(3000); Log.info("在通讯录页面,单击'新增联系人'按钮");
addressBookPage.addContactButton().click(); Log.info("在联系人姓名输入框中,输入: "+contactName);
addressBookPage.addContactName().sendKeys(contactName);
Log.info("在联系人邮箱输入框中,输入: "+contactEmail);
addressBookPage.addContactEmail().sendKeys(contactEmail);
//addressBookPage.addContactTell().sendKeys(contactTell);
Log.info("在联系人国家输入框中,输入: "+contactCountry);
addressBookPage.addContactCounty().sendKeys(contactCountry);
Log.info("在联系人省份输入框中,输入: "+contactProvince);
addressBookPage.addContactProvince().sendKeys(contactProvince);
Log.info("在联系人城市输入框中,输入: "+contactCity);
addressBookPage.addContactCity().sendKeys(contactCity);
Log.info("单击确定按钮");
addressBookPage.addContactSaveButton().click();
Log.info("休眠5秒,等待保存联系人后返回通讯录的主页面");
Thread.sleep(5000);
}
}

TestQQEmailAddContact.java

package testscript;

import java.io.IOException;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import appmodules.AddContactAction;
import until.Constant;
import until.ExcelUntil;
import until.Log; public class TestQQEmailAddContact { public WebDriver driver;
//调用Constant类中的常量url
private String url = Constant.URL; @DataProvider(name="testData")
public static Object[][] data() throws IOException{
//调用ExcelUntil工具类中getTestData()方法获取测试数据
return ExcelUntil.getTestData(Constant.TestDataExcelFilePath, Constant.TestDataExcelFileSheet);
} //使用名称为testData的dataProvider作为测试方法的测试数据集
//测试方法一共有12个参数,分别对应Excel数据文件中的1~12列
@Test(dataProvider="testData")
public void testAddressBook(
String caseRowNumber,
String testCaseName,
String userName,
String passWord,
String contactName,
String contactEmail,
String contactTell,
String contactCountry,
String contactProvince,
String contactCity,
String assertContactName,
String assertContactEmail
) throws Exception{
Log.startTestCase(testCaseName);
driver.get(url); Log.info("调用AddContactAction类的execute方法");
try {
AddContactAction.execute(driver, userName, passWord, contactName, contactEmail, contactCountry, contactProvince, contactCity);
} catch (AssertionError error) {
Log.info("添加联系人失败");
//设置Excel中测试数据行的执行结果为“测试执行失败”
ExcelUntil.setCellData(Integer.parseInt(caseRowNumber.split("[.]")[0]), ExcelUntil.getLastColumnNum(), "测试执行失败");
Assert.fail("执行AddContactAction类的execute方法失败");
}
Log.info("调用AddContactAction类的execute方法后,休眠3秒钟");
Thread.sleep(3000); Log.info("断言通讯录页面是否包含联系人姓名关键字");
try {
Assert.assertTrue(driver.getPageSource().contains(assertContactName));
} catch (AssertionError error) {
Log.info("断言通讯录页面是否包含联系人姓名的关键字失败");
ExcelUntil.setCellData(Integer.parseInt(caseRowNumber.split("[.]")[0]), ExcelUntil.getLastColumnNum(), "测试执行失败");
Assert.fail("断言通讯录页面是否包含联系人姓名的关键字失败");
} Log.info("断言通讯录页面是否包含联系人邮箱关键字");
try {
Assert.assertTrue(driver.getPageSource().contains(assertContactEmail));
} catch (AssertionError error) {
Log.info("断言通讯录页面是否包含联系人邮箱的关键字失败");
ExcelUntil.setCellData(Integer.parseInt(caseRowNumber.split("[.]")[0]), ExcelUntil.getLastColumnNum(), "测试执行失败");
Assert.fail("断言通讯录页面是否包含联系人邮箱的关键字失败");
} Log.info("新建联系人全部断言成功,在Excel的测试数据文件的'测试执行结果'中写入'测试执行成功'");
//断言全部成功,在Excel的测试数据文件的“测试执行结果”中写入“测试执行成功”
ExcelUntil.setCellData(Integer.parseInt(caseRowNumber.split("[.]")[0]), ExcelUntil.getLastColumnNum(), "测试执行成功");
Log.info("测试结果成功写入excel数据文件中的测试执行结果列");
Log.endTestCase(testCaseName); } @BeforeMethod
public void beforeMethod(){
System.setProperty("webdriver.chrome.driver", "e:\\chromedriver.exe");
driver = new ChromeDriver();
} @AfterMethod
public void afterMethod(){
driver.quit();
} @BeforeClass
public void BeforeClass() throws Exception{
ExcelUntil.setExcelFile(Constant.TestDataExcelFilePath,Constant.TestDataExcelFileSheet);
}
}

ObjectMap.properties

QQ邮箱的测试数据.xlsx

Selenium WebDriver 数据驱动测试框架的更多相关文章

  1. Selenium关键字驱动测试框架Demo(Java版)

    Selenium关键字驱动测试框架Demo(Java版)http://www.docin.com/p-803493675.html

  2. Selenium & Webdriver 远程测试和多线程并发测试

    Selenium & Webdriver 远程测试和多线程并发测试 Selenium Webdriver自动化测试,初学者可以使用selenium ide录制脚本,然后生成java程序导入ec ...

  3. Selenium页面工厂+数据驱动测试框架

    工程的目录结构: pom.xml文件: <?xml version="1.0" encoding="UTF-8"?><project xmln ...

  4. Selenium WebDriver + python 自动化测试框架

    目标 组内任何人都可以进行自动化测试用例的编写 完全分离测试用例和自动化测试代码,就像写手工测试用例一下,编写excel格式的测试用例,包括步骤.检查点,然后执行自动化工程,即可执行功能自动化测试用例 ...

  5. Python Selenium 之数据驱动测试

    数据驱动模式的测试好处相比普通模式的测试就显而易见了吧!使用数据驱动的模式,可以根据业务分解测试数据,只需定义变量,使用外部或者自定义的数据使其参数化,从而避免了使用之前测试脚本中固定的数据.可以将测 ...

  6. <day002>Selenium基本操作+unittest测试框架

    任务1:Selenium基本操作 from selenium import webdriver # 通用选择 from selenium.webdriver.common.by import By # ...

  7. Python Selenium 之数据驱动测试的实现

    数据驱动模式的测试好处相比普通模式的测试就显而易见了吧!使用数据驱动的模式,可以根据业务分解测试数据,只需定义变量,使用外部或者自定义的数据使其参数化,从而避免了使用之前测试脚本中固定的数据.可以将测 ...

  8. Python&Selenium 关键字驱动测试框架之数据文件解析

    摘要:在关键字驱动测试框架中,除了PO模式以及一些常规Action的封装外,一个很重要的内容就是读写EXCEL,在团队中如何让不会写代码的人也可以进行自动化测试? 我们可以将自动化测试用例按一定的规格 ...

  9. Selenium(Python)页面对象+数据驱动测试框架

    整个工程的目录结构: 常用方法类: class SeleniumMethod(object): # 封装Selenium常用方法 def __init__(self, driver): self.dr ...

随机推荐

  1. git(github)配置密钥/私钥/SSH公钥)

    1.桌面右键 Git Bash Here 打开git命令行 2.ssh-keygen -t rsa -C "xxxxx@qq.com"(你的注册邮箱)enter 3.cd ~/.s ...

  2. [七月挑选]使用idea创建spring boot 项目

    title: 使用idea创建spring boot 项目 参考lindaZ的IntelliJ IDEA 创建spring boot 的Hello World 项目 1.Open IDEA,choos ...

  3. SpringBoot 单元测试忽略@component注解

    springboot框架在单元测试时可能需要忽略某些带有@component的实例 例如以下代码: @Component public class MyCommandLineRunner implem ...

  4. MOVE - 重定位一个游标

    SYNOPSIS MOVE [ direction { FROM | IN } ] cursorname DESCRIPTION 描述 MOVE 在不检索数据的情况下重新定位一个游标. MOVE AL ...

  5. fpga新建nios

    [FPGA]基于Qsys的第一个Nios II系统设计 (2013-12-12 21:50:08) 转载▼ 标签: fpga niosii qsys helloword quartusii 分类: 嵌 ...

  6. 012-linux系统管理——进程管理与工作管理

    linux系统管理——进程管理 top 命令是使用 top - :: up :, user, load average: 0.06, 0.60, 0.48 #五分钟钱,十分钟前,十五分钟前负载的值根据 ...

  7. PAT Advanced 1035 Password (20 分)

    To prepare for PAT, the judge sometimes has to generate random passwords for the users. The problem ...

  8. Linux 安装FTP服务

    Linux 安装FTP服务,简单入门 环境: 虚拟机:Oracle VM VirtualBox. 系统:CentOS 7. (1)判断是否安装了ftp: rpm -qa | grep vsftpd 或 ...

  9. man(2) V

    vfork(2) #include <sys/types.h> #include <unistd.h> pid_t vfork(void); 功能:创建子进程并阻塞父进 --- ...

  10. mysql5.7.26-忘记密码(CentOS为例)

    编辑 my.cnf [mysqld]下插入 skip-grant-tables [root@VM_0_7_centos mysql]# vim /etc/my.cnf # For advice on ...