软件测试——自动化测试常用函数(超详细)
本节重点
元素定位
操作测试对象
窗⼝
等待
导航
弹窗
⽂件上传
浏览器参数
一:元素的定位
web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素,然后才能对元素进⾏具体的操作。
常⻅的元素定位⽅式⾮常多,如id,classname,tagname,xpath,cssSelector
常⽤的主要由cssSelector和xpath
要定位页面的元素,需要借助页面开发者工具,打开工具的方法有很多:
1)页面鼠标右键”检查“
2)快捷键 :ctrl+shift+i 点击Elements 或者f12
元素定位器,点击,然后就可以在前端页面寻找源码元素
1.1 cssSelector
选择器的功能:选中⻚⾯中指定的标签元素
选择器的种类分为基础选择器和复合选择器,常⻅的元素定位⽅式可以通过id选择器和⼦类选择器来进⾏定位
步骤:
1:定位元素位置,然后右键
我复制出来给大家展示一下:#chat-textarea
然后我们验证一下:
按ctrl+f出现一个搜索框,把我们刚才复制的粘贴搜索,这样我们就一一对应了(搜索框是这个流程,百度按钮也一样)
接下来我们在java代码中是怎么样写的:
直接加上#就可以
//使用css选择器也可以定位到输入框 driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("迪丽热巴"); //4、找到"百度一下"按钮并点击 driver.findElement(By.cssSelector("#chat-submit-button")).click();
1.2 xpath
XML路径语⾔,不仅可以在XML⽂件中查找信息,还可以在HTML中选取节点(就是可以定位节点元素)
流程和cssselector基本一样
步骤
还是先找元素
然后复制:// * [@id="chat-textarea"]
验证就不用了
直接展示java代码
driver.findElement(By.xpath("//*[@id=\"chat-textarea\"]")).sendKeys("迪丽热巴"); //4、找到"百度一下"按钮并点击 driver.findElement(By.xpath("//*[@id=\"chat-submit-button\"]")).click();
1.2.1 获取HTML⻚⾯所有的节点
// *
比如:我们查找百度里面的所有div标签
足足有251个
1.2.2 获取HTML⻚⾯指定的节点
//[指定节点]
//ul :获取HTML⻚⾯所有的ul节点
//input:获取HTML⻚⾯所有的input节点
1.2.3 获取⼀个节点中的直接⼦节点(就是查找他的孩子,下一层)
/
//span/input
比如:
1.2.4 获取⼀个节点的⽗节点
..
//input/.. 获取input节点的⽗节点
先搜索中韩元首会谈有哪些亮点,然后找到它的父节点就是黄色背景的
1.2.5 实现节点属性的匹配
[@...]
//* [@id='kw'] 匹配HTML⻚⾯中id属性为kw的节点
1.2.6 使⽤指定索引的⽅式获取对应的节点内容
注意:xpath的索引是从1开始的。
百度⾸⻚通过://div/ul/li[3] 定位到第三个百度热搜标签
但是当存在动态元素的时候,仅仅通过页面复制xpth或者selector会导致代码报错(NosuchElementException)
面试题:页面不存在这样的元素可能出现的原因
1)元素赋值错误
2)方法使用错误(select-》xpath)
3)动态元素
二: 操作测试对象
获取到了⻚⾯的元素之后,接下来就是要对元素进⾏操作了。常⻅的操作有点击、提交、输⼊、清除、获取⽂本。
2.1 点击/提交对象
页面上绝大数多数都可以点击(特殊元素不可以:页面隐藏)
如果查找一个没有显示的就会出现:elemenNOTInteractableException(元素不可交互)
有这个元素,但是不可交互。
click()
//找到百度⼀下按钮并点击
driver.findElement(By.cssSelector("#chat-submit-button")).click();
2.2 模拟按键输⼊
sendKeys("")driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("输⼊⽂字");
2.3 清除⽂本内容
输⼊⽂本后⼜想换⼀个新的关键词,这⾥就需要⽤到 clear()
driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("我爱游戏");
driver.findElement(By.cssSelector("#chat-textarea")).clear();
driver.findElement(By.cssSelector("#chat-textarea")).sendKeys("我爱学习");
如果不加clear,搜索框就会出现追加,使用clear就会清除前一个元素数据,然后执行下一句语句。
2.4 获取⽂本信息
需要设置返回值。
如果判断获取到的元素对应的⽂本是否符合预期呢?获取元素对应的⽂本并打印⼀下~~
获取⽂本信息: getText()
String bdtext = driver.findElement(By.xpath("//* [@id="title-
content"]/span[1]")).getText();
System.out.println("打印的内容是:"+bdtext);
问题:是否可以通过 getText() 获取到“百度⼀下按钮”上的⽂字“百度⼀下”呢?尝试⼀下
注意:⽂本和属性值不要混淆了。获取属性值需要使⽤⽅法 getAttribute("属性名称") ;
2.5 获取当前⻚⾯标题
getTitle()
2.6 获取当前⻚⾯URL
getCurrentUrl()
运行:
大家有没有看到,我们打印的前后title和url是一样的。
为什么呢?
一步步解释:
我们先看看前面的代码,我们的driver的作用域是在百度一下的中国界面,我们跳转之后,页面虽然变化了,但是driver没有变,我们验证一下:
这个元素的css是百度一下的搜索框,就只是查找一下 ,没有进行任何操作,但是证明我们的当前的driver在百度一下这个页面。
但是我们试一下在跳转后的页面,查找元素:
运行:
没有元素
最后说明什么,证明我们的driver还作用在第一个页面,没有跳转到第二个页面
因为每个标签页都有自己的句柄“身份证号码”
接下来我们就来解决它进入学习窗口;
三:窗⼝
打开⼀个新的⻚⾯之后获取到的title和URL仍然还是前⼀个⻚⾯的?
3.1 切换窗⼝
1)获取当前⻚⾯句柄:
(获取driver作用在哪个句柄上)
driver.getWindowHandle();
2)获取所有⻚⾯句柄:
driver.getWindowHandles()
3)切换当前句柄为最新⻚⾯//获取当前窗口句柄 String currentHandle = driver.getWindowHandle(); //获取所有窗口句柄 Set<String> allHandles = driver.getWindowHandles(); //切换到新窗口 //遍历所有窗口句柄 for(String handle : allHandles) { //判断窗口是否为当前窗口,是则跳过,不是则执行判断条件里面的语句 if (!handle.equals(currentHandle)) { //切换到新窗口 driver.switchTo().window(handle); break; } }注意:执⾏了driver.close()之前需要切换到未被关闭的窗⼝
运行:
这种情况就是针对,我们打开新的标签页,url发生改变的情况下,我们需要作用到这个页面,我们就需要切换句柄。
3.2 窗⼝设置⼤⼩
1)窗⼝的⼤⼩设置
//窗⼝最⼤化
driver.manage().window().maximize();
//窗⼝最⼩化
driver.manage().window().minimize();
//全屏窗⼝
driver.manage().window().fullscreen();
//⼿动设置窗⼝⼤⼩
driver.manage().window().setSize(new Dimension(1024, 768));
public void test01() throws InterruptedException { //驱动程序管理的自动化 WebDriverManager.chromedriver().setup(); ChromeOptions options = new ChromeOptions(); //允许访问所有链接 options.addArguments("--remote-allow-origins=*"); //1、打开浏览器 WebDriver driver = new ChromeDriver(options); driver.manage().window().maximize(); Thread.sleep(3000); driver.manage().window().minimize(); Thread.sleep(3000); driver.manage().window().fullscreen(); Thread.sleep(3000); driver.manage().window().setSize(new Dimension(100, 100)); Thread.sleep(3000); driver.close(); } }
3.3 屏幕截图
我们的⾃动化脚本⼀般部署在机器上⾃动的去运⾏,如果出现了报错,我们是不知道的,可以通过抓拍来记录当时的错误场景
屏幕截图⽅法需要额外导⼊包:
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency> ``` ``` File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(file,new File(filename));可以指定目录:
也可以不用指定,直接定义到我们的项目中
有一个小问题今后我们需要对很多场景进行屏幕截图,如果写死了图片名称,导致新是生成的屏幕截图我呢见会覆盖历史的图片文件,如果想把所有的文件都会留存下来,方便后续进行问题的排查,该如何解决这个问题?
更改图片名称,保证每一次保存的图片名称都是唯一的
测试目录显示
3.4 关闭窗⼝
driver.close();(关闭标签页)
注意:窗⼝关闭后driver要重新定义
driver.quit()//关闭驱动,关闭整个浏览器(常使用)
若存在多个标签页,通过close关闭一个标签页后,还需要对其他页面进行操作的话,此时需要将driver切换到其他标签页,否则driver还作用在已关闭的标签页上(driver失效的)selenium 专门用于做web自动化的工具
junit:单元测试框架
四:等待
通常代码执⾏的速度⽐⻚⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可以使⽤selenium中提供的三种等待⽅法:
4.1 强制等待
Thread.sleep()
单位是毫秒
优点:使⽤简单,调试的时候⽐较有效
缺点:影响运⾏效率,浪费⼤量的时间
强制等待一般仅用在调试阶段
4.2 隐式等待
隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执⾏,直到超时没找到元素才会报错。
implicitlyWait() 参数:Duration类中提供的毫秒、秒、分钟等⽅法//隐式等待1000毫秒driver.manage().timeouts().implicitlyWait(Duration.ofMillis(1000));//隐式等待5秒driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
隐式等待作⽤域是整个脚本的所有元素。即只要driver对象没有被释放掉(driver.quit()),隐式等待就⼀直⽣效。
优点:智能等待,作⽤于全局(只需要一次,作用整个脚本的所有元素)
4.3 显⽰等待
显⽰等待也是⼀种智能等待,在指定超时时间范围内只要满⾜操作的条件就会继续执⾏后续代码
new WebDriverWait(driver, Duration.ofSeconds(3)).until($express)$press:涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类
返回值:boolean
ExpectedConditions预定义⽅法的⼀些⽰例:
elementToBeClickable(By locator) ‒ ⽤于检查元素的期望是可⻅的并已启⽤,以便您
可以单击它。
•
textToBe(Bylocator,String str) - 检查元素。
•
presenceOfElementLocated(Bylocator) ‒ 检查⻚⾯的 DOM 上是否存在元素。
•
urlToBe(java.lang.String url) ‒ 检查当前⻚⾯的 URL 是⼀个特定的 URL。WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(10));boolean ispass = wait.until(ExpectedConditions.textToBe(By.cssSelector("#s-topleft > a:nth-child(1)"), "新闻"));if(ispass){System.out.println("测试通过");}else {System.out.println("测试失败");}
优点:显⽰等待是智能等待,可以⾃定义显⽰等待的条件,操作灵活
缺点:写法复杂隐式等待和显⽰等待⼀起使⽤效果如何呢?
//隐式等待设置为5s,显⽰等待设置为10s,那么结果会是5+10=15s吗?SimpleDateFormat sim =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sim.format(System.currentTimeMillis()));driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));driver.findElement(By.cssSelector("#hotsearch-content-wrapper > li:nthchild(1) > a > span.title-content"));WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(10));try{ wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content")));}catch (Exception e){System.out.println("nosuelement!");}System.out.println(sim.format(System.currentTimeMillis()));结果:重试多次,最终打印的等待时间有10s、11s....
结论:不要混合隐式和显式等待,可能会导致不可预测的等待时间。
隐式等待和显示等待不建议使用,可能会出现意想不到的结果:
注意不是说隐式等待,和显示等待不能在一个代码文件中,而是隐式等待和显示等待同一个元素上
五:浏览器导航
常⻅操作:
1)打开⽹站
// 更⻓的⽅法
driver.navigate().to("https://selenium.dev");
// 简洁的⽅法
driver.get("https://selenium.dev");
2)浏览器的后退、前进、刷新
driver.navigate().back();//后退
driver.navigate().forward();//前进
driver.navigate().refresh();//刷新public void test03() throws InterruptedException, IOException { //驱动程序管理的自动化 WebDriverManager.chromedriver().setup(); ChromeOptions options = new ChromeOptions(); //允许访问所有链接 options.addArguments("--remote-allow-origins=*"); //1、打开浏览器 WebDriver driver = new ChromeDriver(options); driver.navigate().to("https://tool.lu/"); driver.findElement(By.cssSelector("#nav > div > div > ul > li:nth-child(6) > a")).click(); Thread.sleep(3000); driver.navigate().back();//返回上一页 后退 Thread.sleep(3000); driver.navigate().forward();//前进 Thread.sleep(3000); driver.navigate().refresh();//刷新页面(最后到达软件页面) Thread.sleep(3000); driver.quit();先点击软件-回到首页-软件-刷新
六:弹窗(蒙层)
6.1 警告弹窗+确认弹窗+提示弹窗
弹窗的特点:无法对弹窗进行元素定位
弹窗的操作有哪些:
1切换弹窗
2点击确认按钮
3点击取消按钮
4输入文本信息
5获取弹窗上的提示文本
弹窗是在⻚⾯是找不到任何元素的,这种情况怎么处理?使⽤selenium提供的Alert接口
我们先看看
先看看警告弹窗:
直接到提示弹窗:
开启关闭很快但是代码就是这个样子,总结就是找出弹窗,点击确定或者取消。以及输入文本,打印文本.
七:⽂件上传
点击⽂件上传的场景下会弹窗系统窗⼝,进⾏⽂件的选择。
selenium⽆法识别⾮web的控件,上传⽂件窗⼝为系统⾃带,⽆法识别窗⼝元素
但是可以使⽤sendkeys来上传指定路径的⽂件,达到的效果是⼀样的
找一个演示效果
八:浏览器参数设置
1)设置无头模式
1)设置无头模式
不添加该配置的时候,默认浏览器为“有头模式”,即可以在页面看到自动化执行的过程
程序都执行了,但是界面不会展示执行过程
2)设置浏览器加载策略
我们在后面做自动化可能会遇到这样的场景,自动化打开页面加载的速度非常非常满
driver.get();//get方法默认等待页面所有的资源下载并加载完成,才会继续往下执行。
options.setPageLoadStrategy(PageLoadStrategy.NONE);

































