0


Selenium

⾃动化

⾃动化测试

  • ⾃动的代替⼈的⾏为完成操作
  • ⾃动化在⽣活中处处可⻅

制造业自动化:
- 机器人装配线:在汽车制造中,机器人可以自动组装汽车的各个部件。
- 自动化焊接:在金属加工中,自动化焊接机器人可以精确地焊接金属部件。

家庭自动化:
- 智能恒温器:可以根据居住者的习惯自动调节室内温度。
- 智能照明系统:可以根据时间或光线强度自动开关灯。

办公自动化:
- 电子邮件过滤:自动将电子邮件分类到不同的文件夹或标记为垃圾邮件。
- 文档审批流程:自动化的工作流程可以加快文档审批过程。

金融服务自动化:
- 自动取款机(ATM):允许用户无需银行职员即可进行现金提取和存款。
- 算法交易:在金融市场中,算法可以自动执行交易指令。

农业自动化:
- 自动驾驶拖拉机:可以在没有驾驶员的情况下耕种和收割作物。
- 无人机监测:使用无人机来监测作物的生长状况和健康。

物流自动化:
- 自动化仓库:使用机器人和自动化系统来存储、检索和运输货物。
- 自动化包裹分拣系统:在快递中心,自动化系统可以快速准确地将包裹分拣到正确的目的地。

医疗自动化:
- 实验室自动化:自动化设备可以进行样本分析和测试。
- 药物分配系统:在医院中,自动化系统可以管理药物的存储和分发。

客户服务自动化:
- 聊天机器人:在线客服可以通过聊天机器人自动回答常见问题。
- 自动语音响应系统:电话系统中的IVR(Interactive Voice Response)可以自动处理客户的查询。

内容创作自动化:
- 文章生成器:可以自动生成新闻报道或博客文章的初稿。
- 图像和视频编辑:软件可以自动调整图像和视频的色彩、对比度等。

网络安全自动化:
- 入侵检测系统:可以自动监测和响应网络安全威胁。
- 漏洞扫描:自动化工具可以扫描系统以识别潜在的安全漏洞。

回归测试

  • 软件有多个版本需要进⾏功能的整体回归
  • 为了避免新增功能影响到历史的功能需要进⾏功能的回归

常⻅⾯试题

⾃动化测试能够取代⼈⼯测试吗?

⾃动化测试不⼀定⽐⼈⼯测试更能保障系统的可靠性,⾃动化测试是测试⼈员⼿⼯编写,后续如果有 功能的变更⾃动化也需要进⾏不定期的维护和更新


⾃动化测试可以⼤幅度降低⼯作量?

错误 坑!!“⼀定程度上”和“⼤幅度”的表达⽅式也需要注意 tips:测试笔试中的选择题尽量不要选择说的太死或者太绝对的选项~~~~

⾃动化分类

  • 讲⾃动化分类的⽬的是避免同学们将⾃动化混淆,同时避免讲不同的⾃动化如何实施造成的课时 压⼒
  • 很多同学经常听到⾃动化这个词,但是很容易误以为⾃动化就是⼀个东西,⾃动化是个统称,同 学们可以理解为我们常说的吃⽠这样的表达⽅式和⾃动化是⼀样的,吃⽠可以是吃西⽠,吃哈密 ⽠,吃⾹⽠,⾃动化也包含多种,如接⼝⾃动化,web⾃动化,移动端⾃动化等等...
  • 主要介绍各测试分类为什么需要实施⾃动化,⽬的和意义

接⼝⾃动化

什么是接⼝⾃动化测试?


为什么要做?解决了什么问题,⽬的是什么

UI⾃动化

UI测试也称为界⾯测试,常⻅的UI⾃动化测试包含web⾃动化测试、移动端⾃动化测试等等。

移动端⾃动化测试

移动端⾃动化测试 什么是移动端⾃动化测试?


为什么要做?解决了什么问题,⽬的是什么

移动端,顾名思义,就是部署在⼿机上的应⽤程序。移动端⾃动化测试主要测试程序部署在⼿机上能 否按照预期的结果的进⾏操作。

  • 移动端测试通常不是将程序部署在移动端上进⾏测试,⽽是需要安装模拟器,在电脑上编写⾃动化测 试脚本代码对模拟器上的软件进⾏操作
  • 移动端测试难度相对较⼤,移动端测试的稳定性要⽐接⼝⾃动化测试和web⾃动化测试的稳定性要差 很多,原因主要是移动端测试收到的环境影响⽐较多,诸如什么呢????

Web⾃动化测试

  • 什么是web⾃动化测试?
  • 为什么要做?解决了什么问题,⽬的是什么
  • 如何进⾏百度搜索?
  • 通常来说我们⼿动进⾏百度搜索的步骤如下,web⾃动化能够代替我们⾃动的执⾏

模拟⼈在浏览器上的操作⾏为,⾃动的打开浏览器,访问百度⾸⻚,并进⾏⼀系列的搜索和验证等⾏为。

⾃动化测试⾦字塔

理想的⾃动化测试⾦字塔表达了⾃动化测试的理想情况,利⽤较少的时间和精⼒在单元测试上就能够 发现更多有效的问题

然后实际上在企业中,⾃动化往往是“冰淇淋蛋筒反模式”

⾃动化需要⼤量的初始投资,找到“突破点”,与⼿动测试相⽐,我们开始看到它对⻓期成本产⽣的 积极影响,也能够清楚,这两种测试活动都是完全兼容,产⽣短期和⻓期利益。

web⾃动化测试

驱动

上⾯给⼤家已经介绍过,web系统的测试前提是需要打开浏览器,通过访问web服务器来对服务器界 ⾯进⾏⼀系列的操作。对于⼿⼯测试来说,这⼀系列的操作都需要测试⼈员⼿动的,⼀步⼀步的来执 ⾏测试。那么对于⾃动化程序来说,程序如何才能打开浏览器并执⾏我们预期的操作流程呢?
驱动⼀词应⽤⼴泛,同学们都不会陌⽣


⻋有了驱动才能够让⻋跑起来。

计算机有了驱动程序就可以与设备(耳机,摄像头,麦克风,键盘,显示器等等设备)进行通信

程序想要打开web浏览器就需要安装web驱动(即WebDriver),WebDriver 以本地化⽅式驱动浏览 器

安装驱动管理

驱动管理

WebDriverManager是⼀个开源Java库,以完全⾃动化的⽅式对Selenium WebDriver所需的驱动程 序(如chromedriver、geckodriver、msedgedriver等)进⾏管理(即下载、设置和维护),⾃版 本5起,WebDriverManager还提供了其他相关功能,如发现本地系统中安装的浏览器的能⼒,构建 WebDriver对象(如ChromeDriver、FirefoxDriver、EdgeDriver等)

<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>5.8.0</version>
</dependency>

Selenium

  • 万事俱备,只⽋东⻛
  • 接下来就是使⽤selenium来编写web⾃动化测试脚本
  • selenium是⼀个web⾃动化测试⼯具,selenium中提供了丰富的⽅法供给使⽤者进⾏web⾃动化测 试
  • ⼀个简单的web⾃动化⽰例

安装selenium库

<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.21.0</version>
</dependency>

使⽤selenium编写代码

public class FirstTest {
    //测试百度搜索关键词;迪丽热巴
    void test01() throws InterruptedException {
        //1. 打开浏览器 使用驱动来打开
        WebDriverManager.chromedriver().setup();
        //增加浏览器配置:创建驱动对象要强制指定允许访问所有的链接
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");

        WebDriver driver = new ChromeDriver(options);
        Thread.sleep(3000);

        //2. 输入完整的网址:https://www.baidu.com
        driver.get("https://www.baidu.com");
        Thread.sleep(3000);

        //3. 找到输入框,并输入关键词:迪丽热巴
        driver.findElement(By.cssSelector("#kw")).sendKeys("迪丽热巴");
        Thread.sleep(3000);

        //4. 找到百度一下按钮,并点击
        driver.findElement(By.cssSelector("#su")).click();
        Thread.sleep(3000);

        //5. 关闭浏览器
        driver.quit();
    }
}

selenium+驱动+浏览器的⼯作原理

实现web⾃动化测试需要浏览器、浏览器驱动、selenium⾃动化脚本。这三者是如何交互最终实现 web的⾃动化测试?

  • 通过selenium编写的⾃动化脚本代码中在ChromeDriverService中创建⼀个服务
  • 通过创建好的服务打开webdriver,安装在本地的驱动服务IP为localhost,PORT为 ChromeDriverService中创建的端⼝号,该服务地址为selenium向webdriver发送请求的服务地 址
  • 向浏览器驱动程序发送HTTP请求,浏览器驱动程序解析请求,打开浏览器,并获得sessionid,如 果再次对浏览器操作需携带此id
  • 打开浏览器后,所有的selenium的操作(访问地址,查找元素等)均通过创建好的服务链接到 webdriver,然后使⽤execute发送请求
  • 驱动收到请求并对请求进⾏解析,转成浏览器能够解析的脚本并发送给浏览器,浏览器通过请求的 内容执⾏对应动作
  • 浏览器再把执⾏的动作结果通过浏览器驱动程序返回给测试脚本

驱动需要接收、解析请求,发送请求给浏览器,那么驱动到底是什么样的⻆⾊呢?

验证⽅式:

执⾏selenium编写的⾃动化脚本代码中,可以在终端看到创建的驱动服务地址。

⾃动化测试常⽤函数

元素的定位

web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素,然后才能对元素进⾏具体的操作

常⻅的元素定位⽅式⾮常多,如id,classname,tagname,xpath,cssSelector

常⽤的主要由cssSelector和xpath

cssSelector

选择器的功能:选中⻚⾯中指定的标签元素

选择器的种类分为基础选择器和复合选择器,常⻅的元素定位⽅式可以通过id选择器和⼦类选择器来 进⾏定位。

  1. 定位百度⾸⻚的“百度热搜”元素,可以使⽤通过id选择器和⼦类选择器进⾏定位:#s-hotsearchwrapper > div
  2. “搜索输⼊框元素”:#kw “
  3. 百度⼀下按钮”:#su

xpath

XML路径语⾔,不仅可以在XML⽂件中查找信息,还可以在HTML中选取节点

xpath使⽤路径表达式来选择xml⽂档中的节点

xpath语法中:

  • 获取HTML⻚⾯所有的节点
//*
  • 获取HTML⻚⾯指定的节点
//[指定节点]
//ul :获取HTML⻚⾯所有的ul节点
//input:获取HTML⻚⾯所有的input节点
  • 获取⼀个节点中的直接⼦节点
//span/input
  • 获取⼀个节点的⽗节点
..
//input/.. 获取input节点的⽗节点
  • 实现节点属性的匹配
[@...]
//*[@id='kw'] 匹配HTML⻚⾯中id属性为kw的节点
  • 使⽤指定索引的⽅式获取对应的节点内容
  • 注意:xpath的索引是从1开始的。
百度⾸⻚通过://div/ul/li[3] 定位到第三个百度热搜标签
更便捷的⽣成selector/xpath的⽅式:右键选择复制"Copy selector/xpath"

注意:元素的定位⽅法必须唯⼀

  • 案例:如果想要匹配到百度⾸⻚指定的新闻⽂本或者节点集,直接使⽤ #hotsearch-contentwrapper > li 能够满⾜吗?
  • 问题:既然可以⼿动复制 selector/xpath的⽅式 ,为什么还有了解语法?
  • ⼿动复制的selector/xpath表达式并不⼀定满⾜上⾯的唯⼀性的要求,有时候也需要⼿动的进⾏修改表 达式
  • 案例:百度⾸⻚(需要登陆百度账号)右侧的热搜,复制li标签下的a标签,复制好的的selector为: #title-content ,xpath为: //*[@id="title-content"] ,可以⼿动操作⼀下, ⼿动复制的表达式是否唯⼀呢?

操作测试对象

获取到了⻚⾯的元素之后,接下来就是要对元素进⾏操作了。常⻅的操作有点击、提交、输⼊、清 除、获取⽂本

点击/提交对象

click()
//找到百度⼀下按钮并点击
driver.findElement(By.cssSelector("#su")).click();

模拟按键输⼊

sendKeys("")
driver.findElement(By.cssSelector("#kw")).sendKeys("输⼊⽂字");

清除⽂本内容

输⼊⽂本后⼜想换⼀个新的关键词,这⾥就需要⽤到 clear()

driver.findElement(By.cssSelector("#kw")).sendKeys("我爱游戏");
driver.findElement(By.cssSelector("#kw")).clear();
driver.findElement(By.cssSelector("#kw")).sendKeys("我爱学习");

获取⽂本信息

如果判断获取到的元素对应的⽂本是否符合预期呢?获取元素对应的⽂本并打印⼀下~~ 获取⽂本信息:

 getText()
String bdtext = driver.findElement(By.xpath("//*[@id="title-content"]/span[1]")).getText();
System.out.println("打印的内容是:"+bdtext);

问题:是否可以通过 getText() 获取到“百度⼀下按钮”上的⽂字“百度⼀下”呢?尝试⼀下


注意:⽂本和属性值不要混淆了。获取属性值需要使⽤⽅法 getAttribute("属性名称")

获取当前⻚⾯标题

getTitle()

获取当前⻚⾯URL

getCurrentUrl()

窗⼝

打开⼀个新的⻚⾯之后获取到的title和URL仍然还是前⼀个⻚⾯的?

当我们⼿⼯测试的时候,我们可以通过眼睛来判断当前的窗⼝是什么,但对于程序来说它是不知道当 前最新的窗⼝应该是哪⼀个。对于程序来说它怎么来识别每⼀个窗⼝呢?每个浏览器窗⼝都有⼀个唯一的属性句柄(handle)来表⽰,我们就可以通过句柄来切换

切换窗⼝

获取当前⻚⾯句柄
driver.getWindowHandle();
获取所有⻚⾯句柄
driver.getWindowHandles()
切换当前句柄为最新⻚⾯
String curWindow = driver.getWindowHandle();
Set<String> allWindow = driver.getWindowHandles();
for( String w : allWindow){
     if(w!=curWindow){
         driver.switchTo().window(w);
     }
}

注意:执⾏了driver.close()之前需要切换到未被关闭的窗⼝

窗⼝设置⼤⼩

窗⼝的⼤⼩设置
//窗⼝最⼤化
driver.manage().window().maximize();
//窗⼝最⼩化
driver.manage().window().minimize();
//全屏窗⼝
driver.manage().window().fullscreen();
//⼿动设置窗⼝⼤⼩
driver.manage().window().setSize(new Dimension(1024, 768));
窗⼝切换

去掉等待后,获取跳转后的⻚⾯元素失败

//获取所有句柄
//获取当前停留⻚⾯句柄
String curWindow = driver.getWindowHandle();
Set<String> allWindow = driver.getWindowHandles();
for( String w : allWindow){
     if(w!=curWindow){
         driver.switchTo().window(w);
     }
}

屏幕截图

我们的⾃动化脚本⼀般部署在机器上⾃动的去运⾏,如果出现了报错,我们是不知道的,可以通过抓 拍来记录当时的错误场景

屏幕截图⽅法需要额外导⼊包:

<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));

代码演⽰

//简单版本
File srcfile = driver.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(srcfile,new File("my.png"));
//⾼阶版本
List<String> times = getTime();
//⽣成的⽂件夹路径./src/test/autotest-2022-08-01/goodsbroser-20220801-214130.png
String filename ="./src/test/autotest-"+times.get(0)+"/"+str+"-
"+times.get(1)+".png";
File srcfile = driver.getScreenshotAs(OutputType.FILE);
//把屏幕截图放到指定的路径下
FileUtils.copyFile(srcfile,new File(filename));

关闭窗⼝

driver.close();
注意:窗⼝关闭后driver要重新定义

等待

通常代码执⾏的速度⽐⻚⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可 以使⽤selenium中提供的三种等待⽅法

强制等待

Thread.sleep()
  • 优点:使⽤简单,调试的时候⽐较有效
  • 缺点:影响运⾏效率,浪费⼤量的时间

隐式等待

隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码 继续执⾏,直到超时没找到元素才会报错。

implicitlyWait() //参数:Duration类中提供的毫秒、秒、分钟等⽅法
//隐式等待1000毫秒
driver.manage().timeouts().implicitlyWait(Duration.ofMillis(1000));
//隐式等待5秒
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
  • 隐式等待作⽤域是整个脚本的所有元素。即只要driver对象没有被释放掉(driver.quit()),隐式等待 就⼀直⽣效
  • 优点:智能等待,作⽤于全局

显⽰等待

显⽰等待也是⼀种智能等待,在指定超时时间范围内只要满⾜操作的条件就会继续执⾏后续代码

new WebDriverWait(driver, Duration.ofSeconds(3)).until($express)
//$press:涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类

返回值:boolean

⽰例

WebDriverWait foo = new WebDriverWait(driver, Duration.ofSeconds(3))
foo.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

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("#hotsear
    ch-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....
  • 结论:不要混合隐式和显式等待,可能会导致不可预测的等待时间。

浏览器导航

常⻅操作

打开⽹站

// 更⻓的⽅法
driver.navigate().to("https://selenium.dev");
// 简洁的⽅法
driver.get("https://selenium.dev");

浏览器的前进、后退、刷新

driver.navigate().back();
driver.navigate().forward();
driver.navigate().refresh();

案例:百度⾸⻚测试https://tool.lu/标签⼊⼝

弹窗

弹窗是在⻚⾯是找不到任何元素的,这种情况怎么处理?使⽤selenium提供的Alert接⼝

Alert alert = driver.switchTo.alert();
//确认
alert.accept()
//取消
alert.dismiss()

提⽰弹窗

Alert alert = driver.switchTo.alert();
alert.sendKeys("hello");
alert.accept();
alert.dismiss();

⽂件上传

  • 点击⽂件上传的场景下会弹窗系统窗⼝,进⾏⽂件的选择
  • selenium⽆法识别⾮web的控件,上传⽂件窗⼝为系统⾃带,⽆法识别窗⼝元素
  • 但是可以使⽤sendkeys来上传指定路径的⽂件,达到的效果是⼀样的
WebElement ele = driver.findElement(By.cssSelector("body > div > div >
input[type=file]"));
ele.sendKeys("D:\\selenium2html\\selenium2html\\upload.html");

浏览器参数设置

设置⽆头模式

ChromeOptions options = new ChromeOptions();
options.addArguments("-headless");

ChromeDriver driver = new ChromeDriver(options);
driver.get("https://www.baidu.com");
driver.quit();

设置浏览器加载策略

options.setPageLoadStrategy(PageLoadStrategy.NONE);

本文转载自: https://blog.csdn.net/2301_79450337/article/details/142753113
版权归原作者 SizeTheMoment 所有, 如有侵权,请联系我们删除。

“Selenium”的评论:

还没有评论