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

 🔥 交流讨论:欢迎加入我们一起学习!

🔥 资源分享耗时200+小时精选的「软件测试」资料包

🔥 教程推荐:火遍全网的《软件测试》教程  

📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

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

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

数据驱动测试

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

图片.png

读取txt文件

图片.png

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包
问题一:
 

图片.png


解决方法:
进入http://mvnrepository.com/artifact/org.apache.xmlbeans/xmlbeans/2.6.0,下载jar包

问题二:
 

图片.png


解决方法:
进入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)。我们可以将关键字以“填表格”形式写入文件中,从而降低脚本的编写难度。
       正因如此,采用关键字驱动测试来编写同样的脚本需要较高的学习成本。同样,这样的框架越到后期越难维护,可靠性也会变差。所以,暂时不深入研究关键字驱动测试。

最后我邀请你进入我们的【软件测试学习交流群:785128166】, 大家可以一起探讨交流软件测试,共同学习软件测试技术、面试等软件测试方方面面,还会有免费直播课,收获更多测试技巧,我们一起进阶Python自动化测试/测试开发,走向高薪之路

作为一个软件测试的过来人,我想尽自己最大的努力,帮助每一个伙伴都能顺利找到工作。所以我整理了下面这份资源,现在免费分享给大家,有需要的小伙伴可以关注【公众号:程序员二黑】自提!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/502082.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot+vue的可盈保险合同管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

python实现常见一元随机变量的概率分布

一. 随机变量 随机变量是一个从样本空间 Ω \Omega Ω到实数空间 R R R的函数&#xff0c;比如随机变量 X X X可以表示投骰子的点数。随机变量一般可以分为两类&#xff1a; 离散型随机变量&#xff1a;随机变量的取值为有限个。连续型随机变量&#xff1a;随机变量的取值是连…

vue-router4 (六) 路由嵌套

应用场景&#xff1a; ①比如京东页面的首页、购物车、我的按钮&#xff0c;可以点击切换到对应的页面&#xff1b; ② 比如 Ant Design左侧这些按钮点击就会切到对应的页面&#xff0c;此时可以把左侧按钮放在父路由中&#xff0c;右侧的子路由 1.路由配置&#xff0c;子路由…

蓝桥杯算法题汇总

一.线性表&#xff1a;链式 例题&#xff1a;旋转链表 二.栈&#xff1a; 例题&#xff1a;行星碰撞问题 三.队列 三.数组和矩阵 例题&#xff1a;

Docsify部署IIS

什么是Docsify&#xff1f; 一个神奇的文档网站生成器。docsify 可以快速帮你生成文档网站。不同于 GitBook、Hexo 的地方是它不会生成静态的 .html 文件&#xff0c;所有转换工作都是在运行时。如果你想要开始使用它&#xff0c;只需要创建一个 index.html 就可以开始编写文档…

MYSQL--锁机制*

一.对锁机制的大概介绍: 1.大概的来说,MYSQL当中的锁实际上就是合理的管理多个服务器对于同一个共享资源的使用,是计算机协调多个进程或者是线程并发访问某一资源的机制(避免争抢资源的现象发生) 2.在数据库当中,数据是一种可以供许多的用户进行共享使用的资源,如何保证数据并发…

Python环境搭建:一站式指南

在当前AIGC技术蓬勃发展的背景下&#xff0c;Python作为人工智能领域最受青睐的编程语言之一&#xff0c;成为我们必须掌握的技能。因此&#xff0c;搭建一个适合自己的Python环境成为了每个Python开发者的首要任务。本文将为您提供一站式的Python环境搭建指南&#xff0c;帮助…

WSL2部署RV1126 SDK编译环境

1 下载RV1126 SDK 在 Firefly | 让科技更简单&#xff0c;让生活更智能 下载REPO_SDK 这里将SDK下载到了F:\SDK 2 解压SDK到WSL2 tar -xvf /mnt/f/SDK/rv1126_rv1109_linux_release_20211022.tgz 3 编译依赖安装 gcc、g版本依赖安装 sudo apt-get install lib32gcc-7-dev g-7 l…

内容检索(2024.03.01)

随着创作数量的增加&#xff0c;博客文章所涉及的内容越来越庞杂&#xff0c;为了更为方便地阅读&#xff0c;后续更新发布的文章将陆续在此汇总并附上原文链接&#xff0c;感兴趣的小伙伴们可持续关注文章发布动态&#xff01; 本期更新内容&#xff1a; 1. 电磁兼容理论与实…

【王道数据结构】【chapter8排序】【P371t5】

编写一个算法&#xff0c;在基于单链表表示的待排序关键字序列上进行简单选择排序 #include <iostream> #include <time.h> #include <stdlib.h> typedef struct node{int data;struct node *next; }node,*pnode;pnode buynode(int x) {pnode tmp(pnode) mal…

加密与安全_探索口令加密算法(PBE)

文章目录 概述疑问PBE 算法 &#xff08; Password Based Encryption&#xff09;CodePOM实现 小结 概述 加密与安全_探索对称加密算法中我们提到AES加密密钥长度是固定的128/192/256位&#xff0c;而不是我们用WinZip/WinRAR那样&#xff0c;随便输入几位都可以。 这是因为对…

Spring底层源码分析

spring依赖注入底层原理解析 spring之bean对象生命周期步骤详情 流程&#xff1a; UserService.class —>推断构造方法—>普通对象----依赖注入------>初始化&#xff08;afterPropertiesSet方法&#xff09;------>初始化后&#xff08;AOP&#xff09;------…