自动化测试模型可以看作自动化测试框架与工具设计的思想。随着自动化测试技术的发展,演化为以下几种模型:
前一篇所讲的模块化驱动测试能够很好的解决脚本重复的问题,但是在针对同一个功能进行不同数据的测试,从而检测测试结果的变化时仍然需要重复地编写测试脚本。于是,数据驱动测试的概念就为解决这类问题而被提出。
我们可以通过读取定义的数组、字典,或者是外部文件(excel、csv、txt、xml等),都可以看作是数据驱动,从而实现数据与脚本的分离,进一步增强脚本的复用性。
(ノへ ̄、)这段代码存在一个问题,txt文件中有四组数据,但运行时只执行了三组数据(运行时忽略了一条密码为空的数据)。
data.java
package PublicMethods;
import java.io.*;
import java.util.*;
public class data {
//读取txt文件
public static Map txtData(String fileName) throws IOException
{
Map map = new HashMap(); //存放多个键值对
String[] arryTemp = null;
String username = null;
String password = null;
String s = null;
File file = new File(fileName);
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
while((s = br.readLine()) != null)
{
arryTemp = s.split(","); //将一行数据存入数组
username = arryTemp[0]; //获取账户
password = arryTemp[1]; //获取密码
map.put(username, password); //存储一组账号密码
}
return map;
}
}
share.java
package PublicMethods;
import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.WebDriver;
import java.util.Map;
import java.util.Set;
import org.openqa.selenium.firefox.FirefoxDriver;
public class share {
private static WebDriver driver;
public static WebDriver OpenDriver(String url)
{
driver = new FirefoxDriver();
driver.get(url);
return driver;
}
public static void UserLogin(WebDriver driver, Map map) throws InterruptedException
{
Set keyset = map.keySet(); //获取Map的值
for(String count : keyset) {
Thread.sleep(2000);
driver.findElement(By.xpath("//*[@id='username']")).sendKeys(count);
System.out.println(count);
driver.findElement(By.xpath("//*[@id='password']")).sendKeys(map.get(count).toString());
Thread.sleep(2000);
driver.findElement(By.xpath("//*[@id='login_button']")).click();
Thread.sleep(2000);
try
{
driver.switchTo().alert().accept();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[@id='username']")).clear();
driver.findElement(By.xpath("//*[@id='password']")).clear();
}catch(NoAlertPresentException NofindAlert)
{
UserLogout(driver);
}
}
}
public static void UserLogout(WebDriver driver) throws InterruptedException
{
driver.findElement(By.xpath("//*[@id='logout_button']")).click();
Thread.sleep(2000);
}
}
LoginTest.java
package Test;
import java.io.IOException;
import java.util.*;
import PublicMethods.*;
import org.openqa.selenium.WebDriver;
public class LoginTest {
public static void main(String[] args) throws InterruptedException, IOException {
// TODO Auto-generated method stub
WebDriver driver = PublicMethods.share.OpenDriver("file:///D:/%E7%99%BB%E5%BD%95.html");
String filename = "D:\\app_tool\\eclipse-workspace\\AutoTest\\TestData\\user_info.txt";
Map map = txtData(filename);
UserLogin(driver, map);
driver.quit();
}
}
data.py
class data():
# 读取txt文件
def txtData(self, fileName):
file = open(fileName, 'r')
lines = file.readlines()
file.close()
return lines
share.py
from time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
class share():
# 启动浏览器
def open_driver(self, url):
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get(url)
return driver
# 登录账号检测
def user_login(self, driver, lines):
for line in lines:
sleep(2)
driver.find_element(By.XPATH, "//*[@id='username']").send_keys(line.split(',')[0])
driver.find_element(By.XPATH, "//*[@id='password']").send_keys(line.split(',')[1])
sleep(2)
driver.find_element(By.XPATH, "//*[@id='login_button']").click()
sleep(2)
result =EC.alert_is_present()(driver)
# 判断是否有弹窗
if result:
result.accept()
driver.find_element(By.XPATH, "//*[@id='username']").clear()
driver.find_element(By.XPATH, "//*[@id='password']").clear()
# 退出账号
def user_logout(self, driver):
driver.find_element(By.XPATH, "//*[@id='logout_button']").click()
sleep(2)
LoginTest.py
from public import share,data
driver = share.share().open_driver('file:///D:/%E7%99%BB%E5%BD%95.html')
filename = 'user_info.txt'
lines = data.data().txtData(filename)
share.share().user_login(driver, lines)
share.share().user_logout(driver)
driver.quit()
读取csv文件
该方法同样适用于读取txt文件
Java
data.java
package PublicMethods;
import java.io.*;
import java.util.*;
public class data {
//读取csv文件
public static ArrayList csvData(String fileName)
{
ArrayList list = new ArrayList(); //创建保存数据集合
CsvReader cReader = null;
try{
cReader = new CsvReader(fileName);
//是否跳过表头
cReader.readHeaders();
while(cReader.readRecord())
{
list.add(cReader.getValues());
}
}catch(Exception e) {
e.printStackTrace();
}
finally
{
cReader.close();
}
//如果使用testng的DataProvider,可以返回一个二维数组
Object data[][] = new Object[list.size()][];
for(int i=0;i
share.java
package PublicMethods;
import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.WebDriver;
import java.util.ArrayList;
import org.openqa.selenium.firefox.FirefoxDriver;
public class share {
private static WebDriver driver;
public static WebDriver OpenDriver(String url)
{
driver = new FirefoxDriver();
driver.get(url);
return driver;
}
public static void UserLogin(WebDriver driver, ArrayList list) throws InterruptedException
{
for(int i=0;i
LoginTest.java
package Test;
import java.io.IOException;
import java.util.*;
import PublicMethods.*;
import org.openqa.selenium.WebDriver;
public class LoginTest {
public static void main(String[] args) throws InterruptedException, IOException {
// TODO Auto-generated method stub
WebDriver driver = PublicMethods.share.OpenDriver("file:///D:/%E7%99%BB%E5%BD%95.html");
String filename = "D:\\app_tool\\eclipse-workspace\\AutoTest\\TestData\\user_info.csv";
ArrayList list = csvData(filename);
UserLogin(driver, list);
driver.quit();
}
}
data.py
import csv
class data():
# 读取CSV文件
def csvData(self, fileName):
lines = csv.reader(open(fileName, 'r'))
return lines
share.py
from time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
class share():
# 启动浏览器
def open_driver(self, url):
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get(url)
return driver
# 登录账号检测
def user_login(self, driver, lines):
for line in lines:
sleep(2)
driver.find_element(By.XPATH, "//*[@id='username']").send_keys(line[0])
driver.find_element(By.XPATH, "//*[@id='password']").send_keys(line[1])
sleep(2)
driver.find_element(By.XPATH, "//*[@id='login_button']").click()
sleep(2)
result =EC.alert_is_present()(driver)
# 判断是否有弹窗
if result:
result.accept()
driver.find_element(By.XPATH, "//*[@id='username']").clear()
driver.find_element(By.XPATH, "//*[@id='password']").clear()
# 退出账号
def user_logout(self, driver):
driver.find_element(By.XPATH, "//*[@id='logout_button']").click()
sleep(2)
LoginTest.py
from public import share,data
driver = share.share().open_driver('file:///D:/%E7%99%BB%E5%BD%95.html')
filename = 'user_info.csv'
lines = data.data().csvData(filename)
share.share().user_login(driver, lines)
share.share().user_logout(driver)
driver.quit()
Ruby
读取excel文件
Excel文件数据必须时文本格式
Java
进入http://poi.apache.org/download.html下载POI的Jar包
问题一:
解决方法:
进入http://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans/2.6.0,下载jar包
问题二:
解决方法:
进入http://mvnrepository.com/artifact/org.apache.commons/commons-collections4/4.1,下载jar包
问题三:
在遇到Excel单元值为空时sheet.getRow(i).getCell(j).getStringCellValue()会报错
解决方法:
在Excel中把空值改为空格,然后在代码中获取该值后去空格。
data.java
package PublicMethods;
import java.io.*;
import java.util.*;
public class data {
//读取Excel文件
public static XSSFSheet excelData(String fileName) throws IOException
{
File file = new File(fileName);
FileInputStream is = new FileInputStream(file);
XSSFWorkbook wb = new XSSFWorkbook(is); //加载workbook
XSSFSheet sheet = wb.getSheetAt(0); //加载sheet
return sheet;
}
}
share.java
package PublicMethods;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class share {
private static WebDriver driver;
public static WebDriver OpenDriver(String url)
{
driver = new FirefoxDriver();
driver.get(url);
return driver;
}
public static void UserLogin(WebDriver driver, XSSFSheet sheet) throws InterruptedException
{
for(int i=0;i
LoginTest.java
package Test;
import java.io.IOException;
import PublicMethods.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.openqa.selenium.WebDriver;
public class LoginTest {
public static void main(String[] args) throws InterruptedException, IOException {
// TODO Auto-generated method stub
WebDriver driver = PublicMethods.share.OpenDriver("file:///D:/%E7%99%BB%E5%BD%95.html");
String filename = "D:\\app_tool\\eclipse-workspace\\AutoTest\\TestData\\user_info.xlsx";
XSSFSheet sheet = excelData(filename);
UserLogin(driver, sheet);
driver.quit();
}
}
Python
data.py
import xlrd
class data():
# 读取excel文件
def execelData(self, fileName, sheetName):
data = xlrd.open_workbook(fileName)
# 通过索引顺序获取
# table = data.sheets()[0]
# table = data.sheet_by_index(0)
table = data.sheet_by_name(sheetName)
# 获取一行或一列的值,参数是第几行
# table.row_values(0) 获取第一行的值
# table.col_values(0) 获取第一列的值
return table
share.py
from time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
class share():
# 启动浏览器
def open_driver(self, url):
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get(url)
return driver
# 登录账号检测
def user_login(self, driver, table):
rows = table.nrows
for i in range(rows):
sleep(2)
driver.find_element(By.XPATH, "//*[@id='username']").send_keys(table.cell(i, 1).value)
driver.find_element(By.XPATH, "//*[@id='password']").send_keys(table.cell(i, 2).value)
sleep(2)
driver.find_element(By.XPATH, "//*[@id='login_button']").click()
sleep(2)
result =EC.alert_is_present()(driver)
# 判断是否有弹窗
if result:
result.accept()
driver.find_element(By.XPATH, "//*[@id='username']").clear()
driver.find_element(By.XPATH, "//*[@id='password']").clear()
# 退出账号
def user_logout(self, driver):
driver.find_element(By.XPATH, "//*[@id='logout_button']").click()
sleep(2)
LoginTest.py
from public import share,data
driver = share.share().open_driver('file:///D:/%E7%99%BB%E5%BD%95.html')
filename = 'TestData/user_info.xlsx'
sheetname = 'test'
table = data.data().execelData(filename, sheetname)
share.share().user_login(driver, table)
share.share().user_logout(driver)
driver.quit()
Ruby
浅谈关键字驱动测试
在数据驱动的基础上,我们把“数据”转化为“关键字”后,通过关键字的改变从而引起测试结果的变化。
为何我要在这里说明是“浅谈”呢?在关键字驱动测试中,我们可以将测试的对象、满足条件、传输值、断言等,甚至是所需要读取的外部文件以及外部类库,所有的相关条件存储在文件中(典型的关键字驱动工具:UFT)。我们可以将关键字以“填表格”形式写入文件中,从而降低脚本的编写难度。
正因如此,采用关键字驱动测试来编写同样的脚本需要较高的学习成本。同样,这样的框架越到后期越难维护,可靠性也会变差。所以,暂时不深入研究关键字驱动测试。
最后:下方这份完整的【自动化测试】视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取 【保证100%免费】