目录
Selenium-Web自动化测试(Java )
序幕
自动化测试
自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。通常,在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的规程一步步执行测试,得到实际结果与期望结果的比较。在此过程中,为了节省人力、时间或硬件资源,提高测试效率,便引入了自动化测试的概念。
Selenium
Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。这个工具的主要功能包括:测试与浏览器的兼容性——测试你的应用程序看是否能够很好得工作在不同浏览器和操作系统之上。测试系统功能——创建回归测试检验软件功能和用户需求。支持自动录制动作和自动生成
.Net、Java、Perl等不同语言的测试脚本。
TestNG
- TestNg是什么?
TestNG是Java中的一个测试框架, 类似于JUnit 和NUnit, 功能都差不多, 只是功能更加强大,使用也更方便。详细使用说明参考官方链接:TestNG - Welcome - testng用来干什么?
即可以用来做单元测试,也可以用来做集成测试。 - 特点
注解;
TestNG使用Java和面向对象的功能;
支持综合类测试(例如,默认情况下,没有必要创建一个新的测试每个测试方法的类的实例)
独立的编译时间测试代码运行时配置/数据信息;
灵活的运行时配置;
主要介绍“测试组”。当编译测试,只要问TestNG运行所有的“前端”的测试,或“快”,“慢”,“数据库”等
支持依赖测试方法,并行测试,负载测试,局部故障;
灵活的插件API;
支持多线程测试;
TestNG 常用注解
@Before, @BeforeClass, @BeforeEach 和 @BeforeAll之间的不同
-
@BeforeClass
在当前类的所有测试方法之前执行。
注解在静态方法上。
此方法可以包含一些初始化代码。 -
@AfterClass
在当前类中的所有测试方法之后执行。
注解在静态方法上。
此方法可以包含一些清理代码。 -
@Before
在每个测试方法之前执行。
注解在非静态方法上。
可以重新初始化测试方法所需要使用的类的某些属性。 -
@After
在每个测试方法之后执行。
注解在非静态方法上。
可以回滚测试方法引起的数据库修改。
搭建测试环境
步骤
- 创建maven项目
- 导入maven坐标
org.seleniumhq.selenium
org.testng - 设置浏览器驱动
当前浏览器版本号所对应驱动 - webDriver Get要打开的网址
实例
打开百度网页
package com.abtester;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
public class TestCase {
public WebDriver webDriver ;
@Test
public void openBaiduA(){
Path P1 = Paths.get("src","Drivers","chromedriver.exe");
System.setProperty("webdriver.chrome.driver",P1.toAbsolutePath().toString());
webDriver = new ChromeDriver();
webDriver.get("https://www.csdn.net/");
}
}
元素定位
属性定位
根据id、name、class等HTML标签内属性进行定位。
- webDriver.findElement(By.id(“kw”))
- webDriver.findElement(By.name(“kw”)).sendKeys(“金木”);
- findElement(By.className(“kw”)).sendKeys(“金木”)
实例
@Test
public void OpenBaidu(){
//使用浏览器驱动进行打开指定网页的操作
webDriver.get("https://www.baidu.com/"); //"https://www.csdn.net/"
//匹配到搜索框,并输入文本
webDriver.findElement(By.id("kw")).sendKeys("金木");
//匹配到“百度一下”按钮,并点击
webDriver.findElement(By.id("su")).click();
//等待三秒
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//使用name匹配到图片分类选项,并点击
webDriver.findElement(By.className("s-tab-pic")).click();
}
xpath定位
XPath是一种用于在XML和HTML文档中定位元素的语言。
xpath定位举例 //*[@class="pull-rs" and @title="黑化"]
//使用两个斜杠,表示从任意位置开始匹配
* 表示匹配所有的标签,可以换成a表示只匹配a标签,
[]表示他的属性
@表示访问某个属性
and表示且要满足后面的要求
text()=""表示匹配标签的中间文本 例://a[@id="uploadImg" and text()="本地上传"]
实例
//使用xpath匹配到“黑化”,并点击
webDriver.findElement(By.xpath("//p[@class=\"pull-rs-p\" and text()=\"黑化\"]")).click();
css定位
标签类型[属性="属性值"]>二级标签[属性="属性值"]
ul[class="new-type-filter-con"]>li[par="hd"]
ul 表示只匹配该类型的标签
[] 里写标签里的属性及其值
‘>’表示相对元素定位,例ul是li的父级(ul的class的属性具有唯一性,li的par属性单独匹配有很多)
注意:css定位没有文本值选项
实例
//使用css定位元素"高清",并点击 注意定位到元素的唯一性,不然报元素无法定位的错误。
webDriver.findElement(By.cssSelector("div[title=\"食尸鬼\"]")).click();
webDriver.findElement(By.cssSelector("ul[class=\"new-type-filter-con\"]>li[par=\"hd\"]")).click();
Actions
- 是什么?
Actions,用于模拟复杂用户手势的面向用户的API。使用此类而不是直接使用键盘或鼠标。 - 用来干什么?
Actions对象可模拟鼠标的操作以及页面的拖拽。通过往Action对象的事件列表里添加事件,然后通过perform()执行事件列表。完成模拟操作。
鼠标滑动
- moveToElement() 将鼠标移动到元素的中间。
- click() 点击事件
- perform() 一种无需先调用 build() 即可执行操作的便捷方法。
实例
@Test
public void MoveQianQian(){
webDriver.get("https://www.baidu.com/");
// 模拟鼠标移动
WebElement element = webDriver.findElement(By.linkText("更多"));
Actions actions = new Actions(webDriver);
actions.moveToElement(element).perform();
}
鼠标右击、悬停
- 将鼠标移动至元素右击,并停顿三秒
actions.moveToElement(elementBDDT).contextClick().pause(3000).perform(); - 在当前鼠标位置单击不释放
actions.clickAndHold(); - 拖拽地图,xOffset水平偏移(负值向左移动鼠标),yOffset垂直偏移(负值向上移动鼠标)
actions.moveByOffset(400,400); - 在当前鼠标位置释放按下的鼠标左键
actions.release(); - 鼠标双击
actions.doubleClick(login).perform();
实例
@Test
public void MoveBDmap() throws InterruptedException {
//打开百度地图页面
webDriver.get("https://map.baidu.com/");
Thread.sleep(2000);
//关闭登陆界面
Actions actions = new Actions(webDriver);
WebElement element01 = webDriver.findElement(By.id("TANGRAM__PSP_37__closeBtn"));
actions.moveToElement(element01).click().perform();
//关闭百度页面弹窗广告
webDriver.findElement(By.className("close-btn-indexpage")).click();
//搜索框输入“”
// webDriver.findElement(By.id("sole-input")).sendKeys("武汉市");
// //点击搜索
// webDriver.findElement(By.id("search-button")).click();
// Thread.sleep(3000);
//匹配百度地图,并右击,且停顿三秒
WebElement elementBDDT = webDriver.findElement(By.id("mask"));
actions.moveToElement(elementBDDT).contextClick().pause(3000).perform();
//点击“以此为起点”选项
actions.moveToElement(webDriver.findElement(By.id("cmitem_start"))).click();
//在当前鼠标位置单击不释放
actions.clickAndHold();
//拖拽地图,xOffset水平偏移(负值向左移动鼠标),yOffset垂直偏移(负值向上移动鼠标)
actions.moveByOffset(400,400);
//在当前鼠标位置释放按下的鼠标左键
actions.release();
//停顿三秒
actions.pause(3000);
//右键,并点击以“此为终点”
actions.contextClick().click(webDriver.findElement(By.id("cmitem_end")));
//原神启动!(不是) ACTIONS任务链条启动
actions.perform();
}
Other
浏览器窗口切换
- 获取当前窗口炳 String winD = webDriver.getWindowHandle();
- 获取浏览器所有窗口炳 Set sinDs = webDriver.getWindowHandles();
- 切换指定窗口炳 webDriver.switchTo().window(winD);
@Test
public void windowSwitching() throws InterruptedException {
//打开百度学术页面 窗口切换实例
webDriver.get("https://xueshu.baidu.com/");
//获取当前浏览器窗口
String winD = webDriver.getWindowHandle();
//定位弹窗按钮,并点击
webDriver.findElement(By.xpath("//span[text()=\"我知道了\"]")).click();
//点击导航栏“文库”
webDriver.findElement(By.linkText("文库")).click();
//获取所有浏览器窗口
Set<String> sinDs = webDriver.getWindowHandles();
//浏览器窗口切换
for (String i:sinDs){
if (i!=winD){
webDriver.switchTo().window(winD);
}
}
}
frame窗口切换
- 匹配iframe窗口
WebElement ifStr= webDriver.findElement(By.id(“iframeLoginIfm”)); - 切换至iframe窗口
webDriver.switchTo().frame(ifStr); - 此时就可以匹配到iframe窗口中的元素并使用了
实例
@Test
public void iframe(){
//使用浏览器驱动打开安居客首页
webDriver.get("https://beijing.anjuke.com/");
//点击首页的登陆超链接
webDriver.findElement(By.className("user-login")).click();
//找到iframe登陆窗口
WebElement ifStr= webDriver.findElement(By.id("iframeLoginIfm"));
//切换至iframe窗口
webDriver.switchTo().frame(ifStr);
//在iframe窗口元素中查找class名为“ipt”的元素,并写入值
webDriver.findElement(By.className("ipt")).sendKeys("217896323");
}
元素隐式等待
- 是什么是隐式等待?
给整个页面中的元素设置一个等待时间,任一个元素没有被找到时都等待它一段时间,是全局的元素等待时间。 - 弊端
当测试用例较多,且有部分测试用例本就找不到(可能是更改了链接地址、文案),这时就会因为等待这些用例元素而浪费较多的时间。 - 作用
设置最长的等待时间,若在指定时间内找到元素可提前结束等待,若超过了指定时间便不再等待。 - webDriver.manage().timeouts().implicitlyWait(20,TimeUnit.SECONDS);
实例
@Test
public void TimeOut(){
//打开指定网页
webDriver.get("https://www.juhe.cn/");
//全局元素等待时间
webDriver.manage().timeouts().implicitlyWait(20,TimeUnit.SECONDS);
//定位iframe框架窗口
WebElement iframeStr = webDriver.findElement(By.id("layui-layer-iframe2"));
//切换至iframe窗口
webDriver.switchTo().frame(iframeStr);
//在iframe窗口定位指定元素,并输入值
webDriver.findElement(By.id("mobilephone")).sendKeys("8318273128973");
}
元素显示等待
- 什么是元素显示等待?
是针对某一个元素设置的最长等待时间,不会影响到其他元素。
实例
@Test
public void activeTimeOut(){
//打开指定网页
webDriver.get("https://www.juhe.cn/");
WebDriverWait wait = new WebDriverWait(webDriver, Duration.ofSeconds(10));
// 设置指定元素等待时间
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("layui-layer-iframe2")));
//切换至iframe窗口
webDriver.switchTo().frame(element);
//在iframe框架内定位输入框,并输入值
webDriver.findElement(By.id("mobilephone")).sendKeys("0999999999999999998");
}
参考视频: bilibili
Git地址:FangYiZe的小破库
IDEA快捷键
Ctrl+P:查看方法参数
Ctrl+Q:查看类、方法、属性注释
ALT + 7 查看当前类的成员关系
Ctrl + H 查看所选类的继承关系
(需要注意的是,上述的7必须是字母区域上面的数字键盘,不能使用右侧的数字键盘。)
结稿时间:2023.08.09。
值得明确的是这里所涉及的Selenium-Web自动化测试的知识点并不全面。其他视频。
常见报错
1 指定元素是被嵌入进frame元素中,无法被找到。
2 网络波动、或页面加载较慢,元素没有立即加载出来,导致没有被匹配到。
关于此文章,所有测试代码:
package com.abtester;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class TestCase {
public WebDriver webDriver ;
@BeforeClass
public void setChoreDrive(){
//设置浏览器驱动
Path P1 = Paths.get("src","Drivers","chromedriver.exe");
System.setProperty("webdriver.chrome.driver",P1.toAbsolutePath().toString());
webDriver = new ChromeDriver();
// webDriver.manage().window().maximize();
}
@Test
public void OpenBaidu() throws InterruptedException {
//使用浏览器驱动进行打开指定网页的操作
webDriver.get("https://www.baidu.com/"); //"https://www.csdn.net/"
//匹配到搜索框,并输入文本
webDriver.findElement(By.id("kw")).sendKeys("金木");
//匹配到“百度一下”按钮,并点击
webDriver.findElement(By.id("su")).click();
//等待1秒
Thread.sleep(1000);
//使用name匹配到图片分类选项,并点击
webDriver.findElement(By.className("s-tab-pic")).click();
//等待2秒
// Thread.sleep(2000);
//使用xpath匹配到“黑化”,并点击
webDriver.findElement(By.xpath("//p[@class=\"pull-rs-p\" and text()=\"黑化\"]")).click();
Thread.sleep(1000);
//使用css定位元素"高清",并点击
// webDriver.findElement(By.cssSelector("div[title=\"食尸鬼\"]")).click();
webDriver.findElement(By.cssSelector("ul[class=\"new-type-filter-con\"]>li[par=\"hd\"]")).click();
//模拟鼠标滑动到"贴吧",并点击
Actions actions = new Actions(webDriver);
WebElement element01 = webDriver.findElement(By.xpath("//a[@name=\"tieba_6\"]"));
actions.moveToElement(element01).click().perform();
//模拟移动鼠标到“会员”,并点击隐藏列表选项"Y币商城"
WebElement elementHuiYuan= webDriver.findElement(By.xpath("//a[@class=\"u_member_wrap\"]"));
actions.moveToElement(elementHuiYuan).perform();
WebElement elementYBI = webDriver.findElement(By.xpath("//a[@class=\"dropdown-tbmall\"]"));
actions.moveToElement(elementYBI).click().perform();
}
@Test
public void MoveQianQian(){
webDriver.get("https://www.baidu.com/");
// 模拟鼠标移动到“更多”
WebElement element = webDriver.findElement(By.linkText("更多"));
Actions actions = new Actions(webDriver);
actions.moveToElement(element).perform();
}
@Test
public void MoveBDmap() throws InterruptedException {
//打开百度地图页面
webDriver.get("https://map.baidu.com/");
Thread.sleep(2000);
//关闭登陆界面
Actions actions = new Actions(webDriver);
WebElement element01 = webDriver.findElement(By.id("TANGRAM__PSP_37__closeBtn"));
actions.moveToElement(element01).click().perform();
//关闭百度页面弹窗广告
webDriver.findElement(By.className("close-btn-indexpage")).click();
//搜索框输入“”
// webDriver.findElement(By.id("sole-input")).sendKeys("武汉市");
// //点击搜索
// webDriver.findElement(By.id("search-button")).click();
// Thread.sleep(3000);
//匹配百度地图,并右击,且停顿三秒
WebElement elementBDDT = webDriver.findElement(By.id("mask"));
actions.moveToElement(elementBDDT).contextClick().pause(3000).perform();
//点击“以此为起点”选项
actions.moveToElement(webDriver.findElement(By.id("cmitem_start"))).click();
//在当前鼠标位置单击不释放
actions.clickAndHold();
//拖拽地图,xOffset水平偏移(负值向左移动鼠标),yOffset垂直偏移(负值向上移动鼠标)
actions.moveByOffset(400,400);
//在当前鼠标位置释放按下的鼠标左键
actions.release();
//停顿三秒
actions.pause(3000);
//右键,并点击以“此为终点”
actions.contextClick().click(webDriver.findElement(By.id("cmitem_end")));
//原神启动!(不是) ACTIONS任务链条启动
actions.perform();
}
@Test
public void windowSwitching() throws InterruptedException {
//打开百度学术页面 窗口切换实例
webDriver.get("https://xueshu.baidu.com/");
//获取当前浏览器窗口
String winD = webDriver.getWindowHandle();
//定位弹窗按钮,并点击
webDriver.findElement(By.xpath("//span[text()=\"我知道了\"]")).click();
//点击导航栏“文库”
webDriver.findElement(By.linkText("文库")).click();
//获取所有浏览器窗口
Set<String> sinDs = webDriver.getWindowHandles();
//浏览器窗口切换
for (String i:sinDs){
if (i!=winD){
webDriver.switchTo().window(winD);
}
}
}
/**
* iframe 窗口切换
* webDriver.switchTo().frame(ifStr);
* webDriver.findElement(By.className("ipt")).sendKeys("217896323");
*/
@Test
public void iframe(){
//使用浏览器驱动打开安居客首页
webDriver.get("https://beijing.anjuke.com/");
//点击首页的登陆超链接
webDriver.findElement(By.className("user-login")).click();
//找到iframe登陆窗口
WebElement ifStr= webDriver.findElement(By.id("iframeLoginIfm"));
//切换至iframe窗口
webDriver.switchTo().frame(ifStr);
//在iframe窗口元素中查找class名为“ipt”的元素,并写入值
webDriver.findElement(By.className("ipt")).sendKeys("217896323");
}
/**
* 隐式等待
* webDriver.manage().timeouts().implicitlyWait(20,TimeUnit.SECONDS);
* @throws InterruptedException
*/
@Test
public void TimeOut(){
//打开指定网页
webDriver.get("https://www.juhe.cn/");
//全局元素等待时间
webDriver.manage().timeouts().implicitlyWait(20,TimeUnit.SECONDS);
//定位iframe框架窗口
WebElement iframeStr = webDriver.findElement(By.id("layui-layer-iframe2"));
//切换至iframe窗口
webDriver.switchTo().frame(iframeStr);
//在iframe窗口定位指定元素,并输入值
webDriver.findElement(By.id("mobilephone")).sendKeys("8318273128973");
}
/**
* 显式等待
* @throws InterruptedException
*/
@Test
public void activeTimeOut(){
//打开指定网页
webDriver.get("https://www.juhe.cn/");
WebDriverWait wait = new WebDriverWait(webDriver,20);
// 设置指定元素等待时间
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("layui-layer-iframe2")));
//切换至iframe窗口
webDriver.switchTo().frame(element);
//在iframe框架内定位输入框,并输入值
webDriver.findElement(By.id("mobilephone")).sendKeys("0999999999999999998");
}
@AfterClass
public void ChoreQuit() throws InterruptedException {
Thread.sleep(2000);
webDriver.quit();
}
}