自动化测试模型可以看作自动化测试框架与工具设计的思想。随着自动化测试技术的发展,演化为以下几种模型:

  • 线性测试
  • 模块化驱动侧式
  • 数据驱动测试
  • 关键字驱动测试

数据驱动测试

前一篇所讲的模块化驱动测试能够很好的解决脚本重复的问题,但是在针对同一个功能进行不同数据的测试,从而检测测试结果的变化时仍然需要重复地编写测试脚本。于是,数据驱动测试的概念就为解决这类问题而被提出。
我们可以通过读取定义的数组、字典,或者是外部文件(excel、csv、txt、xml等),都可以看作是数据驱动,从而实现数据与脚本的分离,进一步增强脚本的复用性。

读取txt文件

Java

(ノへ ̄、)这段代码存在一个问题,txt文件中有四组数据,但运行时只执行了三组数据(运行时忽略了一条密码为空的数据)。

data.javapackage PublicMethods;import java.io.*;
import java.util.*;public class data {//读取txt文件public static Map txtData(String fileName) throws IOException {Map<String, String> map = new HashMap<String , String>(); //存放多个键值对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.javapackage 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<String> 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.javapackage 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 stubWebDriver 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();}
}

Python

data.pyclass data():# 读取txt文件def txtData(self, fileName):file = open(fileName, 'r')lines = file.readlines()file.close()return lines

share.pyfrom time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ECclass 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.pyfrom public import share,datadriver = 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()

Ruby

读取csv文件

该方法同样适用于读取txt文件

Java

data.javapackage PublicMethods;import java.io.*;
import java.util.*;public class data {//读取csv文件public static ArrayList<String[]> csvData(String fileName){ArrayList<String[]> list = new ArrayList<String[]>();  //创建保存数据集合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<list.size();i++){data[i]=list.get(i);}return list;}
}

share.javapackage 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<String[]> list) throws InterruptedException {for(int i=0;i<list.size();i++) {Thread.sleep(2000);driver.findElement(By.xpath("//*[@id='username']")).sendKeys(list.get(i)[1]);driver.findElement(By.xpath("//*[@id='password']")).sendKeys(list.get(i)[2]);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.javapackage 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 stubWebDriver 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<String[]> list = csvData(filename);UserLogin(driver, list);driver.quit();}
}

Python

data.pyimport csvclass data():# 读取CSV文件def csvData(self, fileName):lines = csv.reader(open(fileName, 'r'))return lines

share.pyfrom time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ECclass 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.pyfrom public import share,datadriver = 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.javapackage 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); //加载workbookXSSFSheet sheet = wb.getSheetAt(0);  //加载sheetreturn sheet;}
}

share.javapackage 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<sheet.getLastRowNum();i++) {Thread.sleep(2000);driver.findElement(By.xpath("//*[@id='username']")).sendKeys(sheet.getRow(i).getCell(1).getStringCellValue().toString().trim());driver.findElement(By.xpath("//*[@id='password']")).sendKeys(sheet.getRow(i).getCell(2).getStringCellValue().toString().trim());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.javapackage 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 stubWebDriver 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.pyimport xlrdclass 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.pyfrom time import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ECclass 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.nrowsfor 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.pyfrom public import share,datadriver = 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)。我们可以将关键字以“填表格”形式写入文件中,从而降低脚本的编写难度。
       正因如此,采用关键字驱动测试来编写同样的脚本需要较高的学习成本。同样,这样的框架越到后期越难维护,可靠性也会变差。所以,暂时不深入研究关键字驱动测试。

转载于:https://www.cnblogs.com/CSgarcia/p/9548334.html

【Web自动化测试——代码篇十二】自动化测试模型——数据驱动测试和关键字驱动测试...相关推荐

  1. Android自动化测试-Appium篇(二)

    Android自动化测试-Appium篇(二) 基于Appium的Android自动化测试环境部署 1. 安装Appium Desktop: a.访问Appium官网:http://appium.io ...

  2. Web基础配置篇(二): Maven配置及使用

    Web基础配置篇(二): Maven配置及使用 一.概述 Maven是一个软件开发管理工具,主要管理工作是:依赖管理,项目一键构建. 以前用过ant,很不方便,maven比较简单易用. 然后后面又来了 ...

  3. 实现医生工作站的病程模板功能的代码(十二)

    实现医生工作站的病程模板功能的代码(十二) 3.2.8病程模板 3.2.8.1病程模板主界面 病程模板是记录每种病的历程,是供医生做参考的.医生可以通过记录病程从而熟悉每个病人的病和预测病的发展,从而 ...

  4. 【云原生微服务>SCG网关篇十二】Spring Cloud Gateway集成Sentinel API实现多种限流方式

    文章目录 一.前言 二.Gateway集成Sentinel API 0.集成Sentinel的核心概念 1)GatewayFlowRule 和 ApiDefinition 2)GatewayFlowR ...

  5. Web Hacking 101 中文版 十二、开放重定向漏洞

    十二.开放重定向漏洞 作者:Peter Yaworski 译者:飞龙 协议:CC BY-NC-SA 4.0 描述 根据 OWASP,开放重定向出现在应用接受参数并将用户重定向到该参数值,并且没有对该值 ...

  6. 高级之路篇十二:全面解析web安全及防御方法

    web安全常见的8大板块: 老生常谈的XSS跨站脚本攻击 警惕iframe带来的风险 别被点击劫持了 错误的内容推断 防火防盗防猪队友:不安全的第三方依赖包 用了HTTPS也可能掉坑里 本地存储数据泄 ...

  7. java提高篇(十二)-----代码块

    在编程过程中我们可能会遇到如下这种形式的程序: public class Test {{ } } 这种形式的程序段我们将其称之为代码块,所谓代码块就是用大括号({})将多行代码封装在一起,形成一个独立 ...

  8. 〖Python WEB 自动化测试实战篇⑮〗 实战 - 自动化测试的持续集成

    订阅 Python全栈白宝书-零基础入门篇 可报销!白嫖入口-请点击我.推荐他人订阅,可获取扣除平台费用后的35%收益,文末名片加V! 说明:该文属于 Python全栈白宝书专栏,免费阶段订阅数量43 ...

  9. 自动化测试中级篇——LazyAndroid UI自动化测试框架使用指南

    原文地址https://blog.csdn.net/iamhuanggua/article/details/53104345 简介 一直以来,安卓UI自动化测试都存在以下两个障碍,一是测试工具Moke ...

最新文章

  1. 【单片机】以输出方波为例的 定时器使用
  2. 文章17周项目2--通过基准线结合(三个数字排序(指针参数))
  3. VC 6.0中添加库文件和头文件
  4. wandb: 深度学习轻量级可视化工具入门教程
  5. 进制问题:m进制转n进制,m进制转十进制,十进制转n进制
  6. 关于async与await的FAQ 转
  7. 《大型门户网站是这样炼成的!(Struts 2+Spring 2+Hibernate 3) 》
  8. NoSql数据库:Cassandra,Mongo,Redis数据库比较
  9. java句柄数过高怎么解决_主播个人及企业利润高,个税或企业所得税怎么解决...
  10. RGB转灰度图的几种算法
  11. R语言学习笔记(五)假设检验及其R实现
  12. 如何用更短时间写出高质量的博客文章经验分享
  13. Activity的Launch mode详解,A B C D的singleTask模式
  14. 用JS开发跨平台桌面应用,从原理到实践
  15. chrome控制台使用jquery
  16. Netty原理:Channel
  17. JavaScript 详解(表单验证,JSON,JS事件,JS函数)
  18. Python机器学习:值得反复练习的8个项目
  19. JAVAEE工程师入门技术之第1课day01_Java基础语法HelloWorld
  20. 蓝牙4.0BLE 手机控制 cc2540 CC2541 的串口透传功能已实现

热门文章

  1. 理解SQLNET.AUTHENTICATION_SERVICES参数|转|
  2. Windows CE授权费用
  3. ASP.NET 常用验证
  4. linux python pip卸载,Python pip的安装及卸载
  5. 转载:【opencv入门教程之三】:图片的载入|显示|输出
  6. 计算机怎样调整工作表位置,图表布局中调整图表大小和位置及跨工作表移动——想象力电脑应用...
  7. python 中文识别 不用tesseract_Python——验证码识别 Pillow + tesseract-ocr
  8. Echarts动态加载地图数据(Dynamic load Echarts map data)
  9. Endnote X9安装教程
  10. 刷magisk模块后不能开机_联想启天商用电脑刷BIOS或维修换主板后 开机叫两声处理办法...