建立数据驱动,关键字驱动和混合Selenium框架这些你了解吗

news2024/11/16 19:49:14

一、什么是Selenium框架?

Selenium框架是一种代码结构,用于简化代码维护和提高代码可读性。框架涉及将整个代码分成较小的代码段,以测试特定的功能。

该代码的结构使得“数据集”与实际的“测试用例”分开,后者将测试Web应用程序的功能。它也可以通过以下方式构造:从外部应用程序(例如.csv)调用(调用)需要执行的测试用例。

有许多框架,但是3个常用的Selenium框架是:

  • 数据驱动框架
  • 关键字驱动框架
  • 混合框架

在华为工作了10年的大佬出的Web自动化测试教程,华为现用技术教程!_哔哩哔哩_bilibili在华为工作了10年的大佬出的Web自动化测试教程,华为现用技术教程!共计16条视频,包括:1. 【web自动化】主流Web自动化测试技术对比、2. 【web自动化】Selenium自动化测试环境一键搭建、3. 【web自动化】Selenium八大定位策略详解等,UP主更多精彩视频,请关注UP账号。https://www.bilibili.com/video/BV1sM4y1d7tq/?spm_id_from=333.337.search-card.all.click

二、为什么我们需要一个Selenium框架?

如果没有合适的框架,将只有一个测试用例,其中包含了整个测试功能。可怕的是,这个单一的测试用例最多可以上升一百万行代码。因此,显而易见,如此庞大的测试案例将很难阅读。即使您以后想要修改任何功能,修改代码也将很困难。

由于框架的实施,将产生较小但多个代码段,因此有许多好处。

三、Selenium 框架的好处

  • 增加代码重用
  • 改进的代码可读性
  • 更高的便携性
  • 精简脚本 保养

既然您已经了解了框架的基础知识,那么让我详细解释每个框架。

四、数据驱动框架

Selenium中的数据驱动框架是一种将“数据集”与实际“测试用例”(代码)分离的技术。该框架完全取决于输入的测试数据。测试数据来自外部源,例如excel文件,.CSV文件或任何数据库。

由于测试用例与数据集是分开的,因此我们可以轻松修改特定功能的测试用例,而无需对代码进行大量更改。例如,如果您想修改用于登录功能的代码,则可以只进行修改,而不必同时修改同一代码中的任何其他相关部分。

除此之外,您还可以轻松控制需要测试的数据量。您可以通过向excel文件(或其他来源)添加更多用户名和密码字段来轻松增加测试参数的数量。

例如,如果我必须检查登录到网页,那么我可以将用户名和密码凭据集保留在excel文件中,并将凭据传递给代码以在单独的Java类文件中在浏览器上执行自动化。

五、将Apache POI与Selenium WebDriver一起使用

WebDriver不直接支持读取excel文件。因此,我们使用Apache POI 读取/写入任何Microsoft Office文档。您可以从此处下载Apache POI(JAR文件集)。根据您的要求下载zip文件或tar文件,并将它们与Selenium JAR集一起放置。

TestNG数据提供程序将处理主要代码和数据集之间的协调,TestNG数据提供程序 是一个库它是Apache POI JAR文件的一部分。出于演示目的,我创建了一个名为“ LoginCredentials”的Excel文件,其中的用户名和密码已存储在不同的列中。

查看下面的代码以了解测试用例。它是用于测试航班预订应用程序登录功能的简单代码。

package DataDriven;
 
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
 
public class DDTExcel
{
 ChromeDriver driver;
  
 @Test(dataProvider="testdata")
 public void DemoProject(String username, String password) throws InterruptedException
{
 System.setProperty("webdriver.chrome.driver", "C:UsersVardhanDownloadschromedriver.exe");
 driver = new ChromeDriver();
  
 driver.get("http://newtours.demoaut.com/");
  
 driver.findElement(By.name("userName")).sendKeys(username);
 driver.findElement(By.name("password")).sendKeys(password);
 driver.findElement(By.name("login")).click();
  
 Thread.sleep(5000);
  
 Assert.assertTrue(driver.getTitle().matches("Find a Flight: Mercury Tours:"), "Invalid credentials");
 System.out.println("Login successful");
 }
  
 @AfterMethod
 void ProgramTermination()
{
 driver.quit();
 }
 
@DataProvider(name="testdata")
 public Object[][] TestDataFeed()
 {
  
 ReadExcelFile config = new ReadExcelFile("C:UsersVardhanworkspaceSeleniumLoginCredentials.xlsx");
  
 int rows = config.getRowCount(0);
  
 Object[][] credentials = new Object[rows][2];
 
for(int i=0;i<rows;i++)
 {
 credentials[i][0] = config.getData(0, i, 0);
 credentials[i][1] = config.getData(0, i, 1);
 }
  
 return credentials;
 }
}

 如果从上面注意到,我们有一个名为“ TestDataFeed()”的方法。在这种方法中,我创建了另一个名为“ ReadExcelFile”的类的对象实例。在实例化该对象时,我已经提供了包含数据的excel文件的路径。我进一步定义了一个for循环,以从excel工作簿中检索文本。

但是,为了从给定的工作表编号,列编号和行编号读取数据,将对“ ReadExcelFile”类进行调用。我的“ ReadExcelFile”的代码如下。

package DataDriven;
 
import java.io.File;
import java.io.FileInputStream;
 
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
public class ReadExcelFile
{
 XSSFWorkbook wb;
 XSSFSheet sheet;
  
 public ReadExcelFile(String excelPath)
{
 try
 {
 File src = new File(excelPath);
 FileInputStream fis = new FileInputStream(src);
 wb = new XSSFWorkbook(fis);
 }
  
 catch(Exception e)
 {
 System.out.println(e.getMessage());
 }
 }
  
 public String getData(int sheetnumber, int row, int column)
{
 sheet = wb.getSheetAt(sheetnumber);
 String data = sheet.getRow(row).getCell(column).getStringCellValue();
 return data;
 }
  
 public int getRowCount(int sheetIndex)
{
 int row = wb.getSheetAt(sheetIndex).getLastRowNum();
 row = row + 1;
 return row;
 }
}

 首先请注意我导入的库。我已经导入了Apache POI XSSF库,该库用于读取数据或将数据写入excel文件。在这里,我创建了一个构造函数(相同方法的对象)以传递值:工作表编号,行编号和列编号。

六、关键字驱动框架

关键字驱动框架是一种技术,其中要执行的所有操作和指令均与实际测试用例分开编写。它与Data Driven框架的相似之处在于,要执行的操作再次存储在Excel表格之类的外部文件中。

我正在谈论的操作不过是需要作为测试用例的一部分执行的方法。关键字驱动框架的好处是您可以轻松控制要测试的功能。您可以在excel文件中指定测试应用程序功能的方法。因此,将仅测试excel中指定的那些方法名称。

例如,对于登录Web应用程序,我们可以在主测试用例中编写多种方法,其中每个测试用例都将测试某些功能。为了实例化浏览器驱动程序,可能有一种方法,找到用户名和密码字段,可能有方法,为了导航到网页,可能有另一种方法,等等。

 看一下下面的代码,以了解框架的外观。如果您不理解,下面的代码中注释掉的行将作为解释。

package KeywordDriven;
 
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.Test;
 
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
 
public class Actions 
{
 public static WebDriver driver;
  
 public static void openBrowser()
{ 
 System.setProperty("webdriver.chrome.driver", "C:UsersVardhanDownloadschromedriver.exe");
 driver=new ChromeDriver();
 }
  
 public static void navigate()
{ 
 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
 driver.get("http://newtours.demoaut.com");
 }
  
 public static void input_Username()
{
 driver.findElement(By.name("userName")).sendKeys("mercury"); 
 }
  
 public static void input_Password()
{
 driver.findElement(By.name("password")).sendKeys("mercury");
 }
  
 public static void click_Login()
{
 driver.findElement(By.name("login")).click();
 }
 
@Test
 public static void verify_login()
{
 String pageTitle = driver.getTitle();
 Assert.assertEquals(pageTitle, "Find a Flight: Mercury Tours:");
 }
 
 public static void closeBrowser()
{
 driver.quit();
 }
}

如您所见,需要测试的不同功能存在于等待调用的单独方法中。现在,基于excel文件中方法名称的存在,将从另一个类中调用这些方法。同样,为了读取excel文件并发送回结果,我编写了另一个Class。它们都显示在下面。

调用方法的类文件就是这个。

package KeywordDriven;
 
public class DriverScript
{
 public static void main(String[] args) throws Exception 
 {
 //用Excel文件的名称声明Excel文件的路径
 String sPath = "C:UsersVardhanworkspaceSelenium Frameworks DemodataEngine.xlsx"; 
 
//在这里,我们传递Excel路径和SheetName作为参数来连接Excel文件
 ReadExcelData.setExcelFile(sPath, "Sheet1");
 
 //硬编码值目前用于Excel行和列
//硬编码值目前用于Excel行和列
//在后面的章节中,我们将用varibales/替换这些硬编码值,这是逐行读取列3(Action关键字)的值的循环
 for (int iRow=1;iRow<=7;iRow++)
 {
 String sActions = ReadExcelData.getCellData(iRow, 1); 
 
 //将Excel单元格的值与“Actions”类中的所有关键字进行比较
 if(sActions.equals("openBrowser"))
 { 
//如果excel单元格值为“openBrowser”,则执行此操作
//此处调用Action关键字以执行操作
 Actions.openBrowser();
 }
 else if(sActions.equals("navigate"))
 {
 Actions.navigate();
 }
 else if(sActions.equals("input_Username"))
 {
 Actions.input_Username();
 }
 else if(sActions.equals("input_Password"))
 {
 Actions.input_Password();
 }
 else if(sActions.equals("click_Login"))
 {
 Actions.click_Login();
 } 
 else if(sActions.equals("verify_Login"))
 {
 Actions.verify_login();
 } 
 else if(sActions.equals("closeBrowser"))
 {
 Actions.closeBrowser();
 } 
 }
 }
}

 读取Excel值的类文件是这个。

package KeywordDriven;
 
import java.io.FileInputStream;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
 
public class ReadExcelData
{
 private static XSSFSheet ExcelWSheet;
 private static XSSFWorkbook ExcelWBook;
 private static XSSFCell Cell; 
//此方法用于设置文件路径并打开Excel文件
//将Excel Path和SheetName作为参数传递给此方法
 public static void setExcelFile(String Path,String SheetName) throws Exception 
{
 FileInputStream ExcelFile = new FileInputStream(Path);
 ExcelWBook = new XSSFWorkbook(ExcelFile);
 ExcelWSheet = ExcelWBook.getSheet(SheetName);
 }
  
 //此方法是从Excel单元格中读取测试数据
//在这里,我们将参数/参数作为Row Num和Col Num传递
 public static String getCellData(int RowNum, int ColNum) throws Exception
{
 Cell = ExcelWSheet.getRow(RowNum).getCell(ColNum);
 String CellData = Cell.getStringCellValue();
 return CellData;
 }
}

 

七、混合框架

混合框架是一种技术,在这种技术中,我们可以充分利用数据驱动和关键字驱动的

Selenium 框架。使用此文章中上面显示的示例,我们可以通过将要执行的方法存储在excel文件中(关键字驱动方法)并将这些方法名称传递给Java Reflection Class(数据驱动方法)来构建混合框架,而不是创建 If /DriverScript类中的/ Else循环。

在下面的代码片段中查看修改后的“ DriverScript”类。 在这里,不是使用多个If / Else循环,而是使用数据驱动的方法从excel文件中读取方法名称。

package HybridFramework;
 
import java.lang.reflect.Method;
 
public class DriverScriptJava
{
 //这是一个类对象,声明为“public static”
 //以便它可以在main[]方法的范围之外使用
 public static Actions actionKeywords;
  
 public static String sActions;
 
 //这是反射类对象,声明为“public static”
 //以便它可以在main[]方法的范围之外使用
 public static Method method[];
  
 public static void main(String[] args) throws Exception 
{
 //用Excel文件的名称声明Excel文件的路径
 String sPath = "C:UsersVardhanworkspaceSelenium Frameworks DemodataEngine.xlsx";
 
//在这里,我们传递Excel路径和SheetName来连接Excel文件
//此方法是以前创建的
 ReadExcelData.setExcelFile(sPath, "Sheet1");
 
//硬编码值目前用于Excel行和列
//稍后,我们将更有效地使用这些硬编码值
//这是逐行读取列(Action关键字)值的循环
//这意味着这个循环将执行测试步骤表中为测试用例提到的所有步骤
 for (int iRow=1;iRow<=7;iRow++)
 {
 sActions = ReadExcelData.getCellData(iRow, 1);
//将创建一个名为“execute_Actions”的新独立方法
//你可以在下面的测试中找到这个方法
//所以这条语句除了调用那段代码来执行
 execute_Actions(); 
 }
 }
 
//此方法包含执行某些操作的代码
//因为它是完全不同的逻辑集,只围绕动作运行,所以将它与主驱动程序脚本分开是有意义的
//这是执行测试步骤(操作)
private static void execute_Actions() throws Exception 
{
//在这里,我们将实例化类“Actions”的新对象
 actionKeywords = new Actions();
 
//这将在其中加载类“Actions”的所有方法。
//它就像一系列的方法,用这里的断点做手表
 method = actionKeywords.getClass().getMethods();
 
 //这是一个循环,将为Action关键字类中的操作数运行
//方法变量包含所有方法和方法.长度返回方法总数
 for(int i = 0;i<method.length;i++)
 {
//现在将方法名与从excel接收的ActionKeyword值进行比较
  if(method[i].getName().equals(sActions))
 { //如果找到匹配,它将执行matched方法
  method[i].invoke(actionKeywords);
   //一旦执行了任何方法,这个break语句将把流带出for循环
  break;
 }
 }
 }
}

我希望这个文章对您有用,并让您清楚地了解什么是Selenium框架,它如何有益以及如何使用这3个Selenium框架构建代码结构。请继续关注本系列中的更多文章。 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【PyTorch】第八节:数据的预处理

作者&#x1f575;️‍♂️&#xff1a;让机器理解语言か 专栏&#x1f387;&#xff1a;PyTorch 描述&#x1f3a8;&#xff1a;PyTorch 是一个基于 Torch 的 Python 开源机器学习库。 寄语&#x1f493;&#xff1a;&#x1f43e;没有白走的路&#xff0c;每一步都算数&#…

【NVIDIA GPU 入门】综述

系列文章目录 文章目录系列文章目录前言一、概述二、GPU架构基础2.1 GPU概述2.2 GPU的架构2.3 自主查询GPU相关信息三、CUDA编程概念3.1 CUDA线程模型3.1 线程层次结构1.引入库2.读入数据总结参考文献前言 GPU作为机器学习的基础运算设备&#xff0c;基本上是无人不知无人不晓。…

【bsauce读论文】PSPRAY-基于时序侧信道的Linux内核堆利用技术

会议&#xff1a;USENIX Security’23 作者&#xff1a;来自 Seoul National University 的 Yoochan Lee、Byoungyoung Lee 等人。 主要内容&#xff1a;由于Linux内核的堆分配器SLUB开启的freelist随机化保护&#xff0c;所以堆相关的内核漏洞利用成功率较低&#xff08;平均…

BEV(一)---lift splat shoot

1. 算法原理 1.1 2D坐标与3D坐标的关系 如图&#xff0c;已知世界坐标系上的某点P&#xff08;Xc&#xff0c; Yc&#xff0c; Zc&#xff09;经过相机的内参矩阵可以获得唯一的图像坐标p&#xff08;x&#xff0c; y&#xff09;&#xff0c;但是反过来已知图像上某点p&…

软考初级程序员--学习

1、十进制 转 二进制 1.1、整数十进制87 转换为 二进制为 1010111 1.2 、小数十进制0.125 转为 二进制 为 0.001 使用乘2取整法&#xff0c;一直乘到没有小数 2、二进制 转 十进制 2.1、二进制1010111 转换为 十进制 2.2、 二进制小数0.001 转 十进制 3、循环队列 计算长度通用…

周赛341(模拟、双指针、树上DP)

文章目录周赛341[6376. 一最多的行](https://leetcode.cn/problems/row-with-maximum-ones/)暴力模拟[6350. 找出可整除性得分最大的整数](https://leetcode.cn/problems/find-the-maximum-divisibility-score/)暴力模拟[6375. 构造有效字符串的最少插入数](https://leetcode.c…

JVM系统优化实践(15):GC可视化工具实践

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 线上系统的JVM监测要么使用jstat、jmap、jhat等工具查看JVM状态&#xff0c;或者使用监控系统&#xff0c;如Zabbix、Prometheus、Open-FaIcon、Ganglia等。作为…

pyg的NeighborLoader和LinkNeighborLoader

NeighborLoader 1 数据格式要求 需要传入加载的属性值&#xff1a; class NeighborLoader(data: Union[Data, HeteroData, Tuple[FeatureStore, GraphStore]], num_neighbors: Union[List[int], Dict[Tuple[str, str, str], List[int]]], input_nodes: Union[Tensor, None…

进程调度的基本过程

进程调度的基本过程&#x1f50e; 进程是什么&#x1f50e; 进程管理&#x1f50e; 进程中结构体的属性进程标识符(PID)内存指针文件描述符表结构体中与进程调度相关的属性进程的状态进程的优先级进程的上下文进程的记账信息&#x1f50e; 总结&#x1f50e; 结尾&#x1f50e;…

(第十四届蓝桥真题) 整数删除(线段树+二分)

样例输入&#xff1a; 5 3 1 4 2 8 7 样例输出&#xff1a; 17 分析&#xff1a;这道题我想的比较复杂&#xff0c;不过复杂度还是够用的&#xff0c;我是用线段树二分来做的。 我们用线段树维护所有位置的最小值&#xff0c;那么我们每次删除一个数之前先求一遍最小值&a…

停车场管理系统文件录入(C++版)

❤️作者主页&#xff1a;微凉秋意 ✅作者简介&#xff1a;后端领域优质创作者&#x1f3c6;&#xff0c;CSDN内容合伙人&#x1f3c6;&#xff0c;阿里云专家博主&#x1f3c6; 文章目录一、案例需求描述1.1、汽车信息模块1.2、普通用户模块1.3、管理员用户模块二、案例分析三…

mysql:使用终端操作数据库

登录进入终端&#xff1a; mysql -u root -p 展示数据库 SHOW DATABASES; 创建数据库&#xff1a; CREATE DATABASE IF NOT EXISTS RUNOOB_TEST DEFAULT CHARSET utf8 COLLATE utf8_general_ci; 1. 如果数据库不存在则创建&#xff0c;存在则不创建。 2. 创建RUNOOB_TEST数据库…

ElasticSearch安装、启动、操作及概念简介

ElasticSearch快速入门 文件链接&#xff1a;https://pan.baidu.com/s/15kJtcHY-RAY3wzpJZIn4-w?pwd0k5a 提取码&#xff1a;0k5a 有些软件对于安装路径有一定的要求&#xff0c;例如&#xff1a;路径中不能有空格&#xff0c;不能有中文&#xff0c;不能有特殊符号&#xf…

JUC并发编程之ReentrantLock

1. 非公平锁实现原理 加锁解锁流程 构造器默认实现的是非公平锁 public ReentrantLock() {sync new NonfairSync();}NonfairSync 继承 Sync&#xff0c; Sync 继承 AbstractQueuedSynchronizer 没有竞争时 第一个竞争出现时 Thread-1 执行了 CAS 尝试将state 由 0 改为 1&…

Stable Diffusion免费(三个月)通过阿里云轻松部署服务

温馨提示&#xff1a;划重点&#xff0c;活动入口在这里喔&#xff0c;不要迷路了。 其实我就在AIGC_有没有一种可能&#xff0c;其实你早就在AIGC了&#xff1f;阿里云邀请你&#xff0c;体验一把AIGC级的毕加索、达芬奇、梵高等大师作画的快感。阿里云将提供免费云产品资源&…

如何使用evosuite为指定被测方法生成测试用例

目录 省流版本 准备工作 环境 evosuite获取 检验环境 参数解释 怎样表示被测方法 怎样指向被测类 其他参数 参考 省流版本 java -jar .\target\depd\evosuite-1.1.0.jar -generateTests -Dtarget_method"isLenient()Z" -class com.google.gson.stream.…

Midjourney教程(二)——Prompt基本结构

Midjourney教程——Prompt基本结构 Basic Prompt 基础版本的prompt仅仅包含图片的描述&#xff0c;能够满足普通的需求&#xff0c;如下图所示 Advanced Prompt 高级版本的prompt主要包含三个部分&#xff0c;如下图所示 Image Prompts(可选) prompt第一部分是Image&#x…

TCP/IP协议详解

一.引言TCP/IP 是 TCP 和 IP 两种协议群的统称&#xff0c;具体来说&#xff0c;IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议二.计算机网络体系结构分层计算机网络体系结构分层计算机网络体系结构分层不难看出&#xff0c;TCP/IP 与 OSI 在分层模块…

【C语言】迷宫问题

【C语言】迷宫问题一. 题目描述二. 思想2.1 算法---回溯算法2.2 思路分析图解三. 代码实现3.1 二维数组的实现3.2 上下左右四个方向的判断3.4 用栈记录坐标的实现3.5 完整代码四. 总结一. 题目描述 牛客网链接&#xff1a;https://www.nowcoder.com/questionTerminal/cf2490605…

STM32看门狗

目录 独立看门狗 IWDG 什么是看门狗&#xff1f; 独立看门狗本质 独立看门狗框图 独立看门狗时钟 分频系数算法&#xff1a; ​编辑 重装载寄存器 键寄存器 溢出时间计算公式 独立看门狗实验 需求&#xff1a; 硬件接线&#xff1a; 溢出时间计算&#xff1…