自动化测试(selenium篇)

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快

一、什么是自动化测试

自动化测试通俗一些来讲,就是相当于将人工测试手段进行转换,让代码去自动执行。
自动化测试主要分为:单元测试,接口测试,UI测试;

本篇文章先对于UI自动化测试中的 web 测试的 selenium 测试框架进行讲解;

UI自动化测试是可以大大提高测试效率的,例如版本的更新,是需要进行大量的回归测试的,随着版本的更新,功能会越来越多,而每一次版本更新都进行手动测试,显然不太现实,效率也很低下,此时就可以使用自动化来进行回归测试,可以来代替大部分的手动测试,减少重复测试的时间。

二、selenium

selenium是用来做web自动化测试框架;适用于多种语言,多种浏览器和多种平台,有着丰富的API;

1. selenium的工作原理

编写自动化脚本代码,发送请求给 webdrive浏览器驱动,由 webdrive浏览器驱动进行解析后,发送给浏览器进行执行,再将结果依次返回。

2. selenium+Java的环境搭建(Chrome浏览器)

1. 先确定Chrome当前的版本,然后下载对应版本的Chrome浏览器驱动:https://chromedriver.chromium.org/downloads

2. 解压下载好的驱动压缩包,将下载好的Chromedriver.exe放大Java系统环境变量下 ,也就是jdk所在环境下。

3. 验证环境是否搭建成功,需要在Java项目中引入selenium依赖,进入 Maven Repository: Search/Browse/Explore (mvnrepository.com) 查找 selenium 对应的依赖,然后添加到 pom 文件中。

4. 执行代码,如果打开了浏览器,则说明环境搭建成功,此时就是借助驱动程序来打开浏览器,并执行。

复制代码
public class Test {
    public static void main(String[] args) {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        WebDriver webDriver = new ChromeDriver(options);
        webDriver.get("https://www.baidu.com");
    }
}

如果pom.xml中引入的是selenium3版本或以上的话,可以直接写

WebDriver webDriver = new ChromeDriver();

webDriver.get("https://www.baidu.com");

三. selenium中常用的API

1. 定位元素 findElement

( findElement() 只返回一个WebElement,而 findElements() 返回类型为 List<WebElement> )

主要有两种方式,一种是 css选择语法 ,另一种是 xpath ;

返回类型都为 WebElement

  1. WebElement element = webDriver.findElement(By.cssSelector("css选择器"));

  2. WebElement element = webDriver.findElement(By.xpath("xpath路径"));

1.1 css选择语法
  1. id选择器:#id

  2. 类选择器:.class

  3. 标签选择:标签名

  4. 后代选择器:父级选择器 子级选择器

1.2 xpath
  1. 绝对路径:例如:/html/head/title 但这种方法一般不用 ;

  2. 相对路径 :

相对路径 + 索引 ://form/span[1]/input

相对路径 + 属性值 ://input [@class=""]

相对路径 + 通配符://*[@*=""]

相对路径 + 文本匹配://a[text()=""]

绝对路径下: (如果是该路径下同一个标签有多个,可以用[n]进行选择,默认从1开始;后同)

相对路径1:

相对路径2:

相对路径3:

相对路径4:

在定位元素的时候,也通常可以直接从后台管理中去复制:

从整体来看,css选择器定位元素效率是要比xpath更高的,所以一般也更推荐css选择器法;因为css选择器是浏览器原生支持的,而Xpath需要引入额外的解析器来解析xpath表达式。

2. 操作测试对象

2.1 sendKeys-在对象上模拟按键输入

webElement.sendKeys(" ");

2.2 click-点击对象

webElement.click();

2.3 clear-清除对象输入的文本内容

webElement.clear();

2.4 submit-提交

webElement.submit();

如果点击的元素在form标签中,此时submit实现的效果是和click一样的,如果点击的元素放 在非form标签中,此时使用submit会报错,所以一般还是使用 click 更好一些。

2.5 getText()-获取元素的文本信息

webElement.getText();

2.6 getAttribute("对应属性")-获取元素的属性信息

webElement.getAttribute();

getText 只能获取到标签之间的对应值 eg: <a> 111 </a>,而不能获取属性值 eg: <a value = "111"> </a>,所以就有了 getAttribute("对应的属性")获取属性值;

2.7 场景分析

在进行登录自动化测试的时候,验证码无法获取到,要怎么去测试?

答:可以在自动化测试账号加一个白名单,设定一个账号,当使用这个账号登录的时候,此时就不需要要验证码处理;

2.8 sleep-强制等待

sleep(ms);

2.9 智能等待中的隐式等待

隐式等待 等待的是所有的元素生成,如果超过设定的时间,还没生成就会报错,一旦生成获取到页面上的元素,就会继续往下执行。

webDrive.manage().timeouts().implicitlyWait( 单位长度 , TimeUnit类型(包含秒,分钟,小时...) );

例如如下语句表示隐式等待 3小时

webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.HOURS);

2.10 智能等待中的显式等待

显式等待 等待的是对应的条件,条件满足了则继续往下执行,等待时间到了还没满足条件那么就会报错。

WebDriverWait wait = new WebDriverWait(WebDriver driver, long timeOutInSeconds);

wait.until(Function<? super T, V> isTrue);

eg:如下代码表示的是:在显式等待三秒中 ,如果满足页面中的 title 是"百度一下,你就知道",那么就继续往下执行,如果显式等待三秒后,条件依旧不满足,则报错。

WebDriverWait wait = new WebDriverWait(webDriver,3); wait.until(ExpectedConditions.titleIs("百度一下,你就知道"));

2.11 显式等待和隐式等待的区别

因此我们也可以得知,智能等待中显式等待和隐式等待的区别:

隐式等待等待的是所有的元素;

显式等待等待的是一定的条件,这个条件也是由程序员自定义的;

2.12 获取页面的 URL 和 title

webDrive.getCurrentUrl() 和 webDrive.getTitle() ;

3. 浏览器的操作

3.1 浏览器前进后退和刷新

webDriver.navigate().back(); // 浏览器后退

webDriver.navigate().refresh(); // 浏览器刷新

webDriveer.navigate().forward(); // 浏览器前进

3.2 浏览器滚动条的操作

浏览器滚动条的操作需要借助转换 JS 来执行;

((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=高度");

3.3 窗口的最大化,满屏,和设置像素大小

webDriver.manage().window().maximize(); // 窗口最大化

webDriver.manage().window().fullscreen(); // 窗口满屏

weebDriver.manage().window().setSize(new Dimension(width,height)); // 设置像素大小

3.4 代码演示:
复制代码
    private static void test07() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(3000);
        // 浏览器后退
        webDriver.navigate().back();                    // navigate 表示导航
        sleep(3000);
 
        // 刷新
        webDriver.navigate().refresh();
        sleep(3000);
 
        // 浏览器前进
        webDriver.navigate().forward();
 
        sleep(3000);
        // 浏览器的滚动条,需要借助转换 JS 来执行
        ((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");
 
        // 窗口最大化
        webDriver.manage().window().maximize();
        sleep(2000);
        // 窗口满屏
        webDriver.manage().window().fullscreen();
        sleep(3000);
        // 设置像素点
        webDriver.manage().window().setSize(new Dimension(1000,1000));
 
    }

4. 键盘的操作

在sendKeys的基础上操作:

例如要输入ctrl+A:sendKeys(Keys.CONTROL,"A");

代码演示:

复制代码
private static void test08() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");
        // 键盘操作   Keys.
        // ctrl + A
        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"A");
        sleep(1000);
        // ctrl + X
        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"X");
        sleep(1000);
        // ctrl + V
        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"V");
        sleep(1000);
 
    }

5. 鼠标操作

通过 Actions 对象来操作:Actions actions = new Actions(webDriver);

鼠标右击:contextClick();

鼠标双击:doubleClick();

鼠标移动:moveToElement(webElement);

执行行为:perform();
场景设计:在百度这个页面中,搜索 "520" ,点击百度进行搜索,然后对页面中的图片超链接 进行右击; 注意最后要进行 perform() 进行执行!!!

复制代码
private static void test09() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("http://www.baidu.com");
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("520");
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(3000);
        // 找到图片这个按钮
        WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-pic"));
        // 鼠标右击
        Actions actions = new Actions(webDriver);
        // 先移动到对应的元素,然后右击,最后执行,注意要加上perform执行
        sleep(3000);
        actions.moveToElement(webElement).contextClick().perform();
    }

6. 对多选框和单选框进行区分选择

在如下页面中,实现对多选框( type = checkbox )进行选择,单选框( type = radio )不选择。

代码实现:

复制代码
private static void page01() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("");    // 对应页面
        // 由于有些页面找的元素有些多,害怕有些元素渲染不出来,可以进行一个隐式等待(智能)
        webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.DAYS);
        List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));
        for (int i = 0; i < webElements.size(); i++) {
            // 如果元素type值等于checkbox进行点击
            // getAttribute 来获取页面上元素的属性值,里面的 type 是当前元素属性,返回值就为对应的属性值
            if (webElements.get(i).getAttribute("type").equals("checkbox")){
                webElements.get(i).click();
            }else {
                // 否则什么也不操作
                ;
            }
        }
    }

7. 多层框架定位

对于在 <iframe> 标签下的标签,不可直接通过 findElement 来进行查找并click。

而应该先通过对应的 id 或者 name 或者iframe自带的其他属性来定位到对应的框架下,此处可以使用webDriver.switchTo().frame("id属性值");来定位

例如如下页面中,想要对 页面中的 click元素 进行一个点击,通过后台可以看到 click元素 属于<iframe id="f1">,所以此时就应该先定位到对应的框架下,再去 click 。

代码实现:

复制代码
   private static void page02() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("");
 
        webDriver.switchTo().frame("f1");     // 参数可以为 要选择的标签 位于的那个<iframe>标签下的 id 属性值(string)
        webDriver.findElement(By.cssSelector("body > div > div > a")).click();   
    }

8. 下拉框处理

对如下页面中的下拉框进行选择,此时需要进行两次定位,先定位到下拉框,对下拉框进行操作,再定位到下拉框中要选择的选项。

首先需要定位到下拉框,然后使用 Select select = new Select(webElement) 对其进行选定,再进行选项的选定。

代码实现:

复制代码
private static void page03() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("");
        WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));
        Select select = new Select(webElement);
        select.selectByIndex(1);    // 下标从0开始算
        sleep(3000);
        select.selectByValue("10.69");  // value属性对应的值
    }

9. 针对 alter 弹窗的一个操作

如下页面中,要实现点击 "这是一个弹窗" 后会出现一个弹窗。

实现弹窗取消:webDriver.switchTo().alter().dismiss();

再点击弹窗,进行输入。

最后进行弹窗确认:webDriver.switchTo().alter().accept();

代码实现:

复制代码
private static void page04() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("");
        webDriver.findElement(By.cssSelector("button")).click();
        sleep(3000);
        // alter弹窗取消
        webDriver.switchTo().alert().dismiss();
        sleep(3000);
        // 点击按钮
        webDriver.findElement(By.cssSelector("button")).click();
        // 在 alter 弹窗输入 xxx
        webDriver.switchTo().alert().sendKeys("11");
        // alter弹窗确认
        sleep(3000);
        webDriver.switchTo().alert().accept();
    }

10. 上传文件

上传文件的操作较简单,例如下图中实现文件的选择,只需要对 " 选择文件 "进行定位,然后 sendKeys("要选择文件的路径");

代码实现:

复制代码
private static void page05() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("");
        webDriver.findElement(By.cssSelector("input")).sendKeys("D:\\桌面\\image");
    }

11. 关闭浏览器

关闭浏览器,主要有两种方式:

  1. webDriver.close(); 这种方式只会关闭一个页面,关闭原始的那个页面,而不会关闭新的页面,也不会清空缓存;

  2. webDriver.quit();这种方式会把整个浏览器都关闭,会清空缓存(cookie);

12. 切换窗口操作

当获取到新的页面后,对于新的页面,无法直接 findElement() 进行定位元素了,因为此时的 findElement() 还是针对第一次 GET 获取到的页面 (首页) 而言的。

所以此时需要对窗口进行定位:通过 webDriver.getWindowHandles() 获取到当前所有的窗口句柄,此时的返回类型为 Set<String> ,里面存放着当前每一个页面的窗口句柄。对这个返回类型进行遍历,所得到的 set 的最后一个元素就是最后一个生成页面的窗口句柄。因此就可以使用 webDriver.switchTo().window(String 对应页面的窗口句柄); 将自动化找元素的操作页面转换为新的页面了,再进行 findElement() 等操作即可;

代码实现:

复制代码
private static void test11() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
        sleep(3000);
 
        // 直接这样操作是不可行的!!!
//        webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");
//        webDriver.findElement(By.cssSelector("#s_btn_wr")).click();
 
        // 通过 getWindowHandles 获取所有的窗口句柄
        // 通过 getWindowHandle 获取的 get 打开的页面窗口句柄
        System.out.println(webDriver.getWindowHandle());
        Set<String> handles = webDriver.getWindowHandles();
        String target_handle = "";
        for (String handle:handles ) {
            target_handle = handle;
        }
        // 这样遍历到最后 ,对应的 handle 就为对应的页面,也就是最后一个生成的页面
 
        webDriver.switchTo().window(target_handle); // 此处的操作就相当于把 自动化找元素的操作的页面转换为新的页面了(target_handle)
        sleep(3000);
        // 此时就可以对新生成的页面进行定位操作了
        webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");
        webDriver.findElement(By.cssSelector("#s_btn_wr")).click();
    }

13. 截图操作

截图操作,需要引入依赖。

可以使用 ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);以文件的形式返回,然后将文件放置对应的路径即可。

复制代码
<!--        截图-->
        <!-- ht tps://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

代码实现:

复制代码
private static void test12() throws InterruptedException, IOException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com");
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(3000);
        File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
        // 将文件放到某个位置
        FileUtils.copyFile(file,new File("D://test_jietu.png"));  // 将file文件放到第二个参数对应的位置
    }

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。

相关推荐
_深海凉_3 分钟前
LeetCode热题100-颜色分类
python·算法·leetcode
AC赳赳老秦26 分钟前
OpenClaw email技能:批量发送邮件、自动回复,高效处理工作邮件
运维·人工智能·python·django·自动化·deepseek·openclaw
zhaoshuzhaoshu34 分钟前
Python 语法之数据结构详细解析
python
AI问答工程师1 小时前
Meta Muse Spark 的"思维压缩"到底是什么?我用 Python 复现了核心思路(附代码)
人工智能·python
zfan5202 小时前
python对Excel数据处理(1)
python·excel·pandas
小饕2 小时前
我从零搭建 RAG 学到的 10 件事
python
老歌老听老掉牙2 小时前
PyQt5+Qt Designer实战:可视化设计智能参数配置界面,告别手动布局时代!
python·qt
格鸰爱童话3 小时前
向AI学习项目技能(六)
java·人工智能·spring boot·python·学习
悟空爬虫-彪哥3 小时前
VRChat开发环境配置,零基础教程
python
数据知道3 小时前
《 Claude Code源码分析与实践》专栏目录
python·ai·github·claude code·claw code