目录:

  1. Web自动化测试价值与体系
  1. 功能测试场景:
  2. UI自动化测试场景:
  3. 什么时候可以做UI自动化测试?
  4. Web自动化测试相关技术:
  5. Web自动化测试学习路线
  6. 必修-初级
  7. 必修-中级
  8. 必修-高级
  9. 资深与拓展
  1. 环境安装与使用
  1. Selenium的简介
  2. Selenium架构图:
  3. Selenium环境配置步骤
  4. Selenium的安装(Python)
  5. Selenium的安装(Java)
  6. Driver的下载与配置步骤
  7. chromedriver的下载-Windows
  8. chromedriver环境变量配置-Windows
  9. 验证配置chromedriver是否成功-Windows
  10. geckodriver配置-Windows
  11. chromedriver的下载-Mac
  12. chromedriver环境变量配置-Mac
  13. 验证配置chromedriver是否成功-Mac
  14. geckodriver配置-Mac
  15. 在python中的使用
  16. 在python中的使用
  17. 在java中的使用
  18. 在java中的使用
  1. 自动化用例录制
  1. SeleniumIDE用例录制使用场景
  2. SeleniumIDE的下载以及安装:
  3. SeleniumIDE常用功能
  4. 其他常用功能
  5. SeleniumIDE脚本导出
  1. 自动化测试用例结构分析
  1. 标准的用例结构
  2. 自动化测试用例结构:
  3. 代码示例:
  1. web浏览器控制
  1. 代码示例:
  2. 浏览器操作总结
  1. 常见控件定位方法
  1. 代码示例:
  2. 元素定位总结
  1. 强制等待与隐式等待
  1. 为什么要添加等待?
  2. 代码示例:
  3. 直接等待
  4. 隐式等待
  5. 隐式等待无法解决的问题
  6. 显式等待基本使用(初级):
  7. 总结
  1. 常见控件交互方法
  1. 点击,输入,清空
  2. 获取元素属性信息
  3. 获取元素属性信息的方法
  4. 代码示例:
  1. 自动化测试定位策略
  1. 通用Web定位方式
  2. 选择定位器通用原则
  3. Web弹框定位
  4. 下拉框/日期控件定位
  5. 文件上传定位
  1. 搜索功能自动化测试
  1. 测试用例:
  2. 代码示例:
  3. 例题:
  1. 用户端Web自动化测试
  1. 需求:
  2. 场景描述
  3. 代码示例:

1.Web自动化测试价值与体系

功能测试场景:

PageRequest 如何测试_自动化测试

 UI 自动化测试场景:

PageRequest 如何测试_自动化测试_02

 什么时候可以做UI自动化测试?

PageRequest 如何测试_前端_03

  • 业务流程不频繁改动
  • UI 元素不频繁改动
  • 需要频繁回归的场景
  • 核心场景等
 Web自动化测试相关技术:
  • Selenium:支持多语言,行业内最火最主流
  • Pytest/JUnit5:最好用最全面的单元测试框架
  • Allure:测试报告
 Web自动化测试学习路线

PageRequest 如何测试_PageRequest 如何测试_04

必修-初级

形式

章节

描述

知识点

Web 自动化测试价值与体系

价值体系 技术选型 学习路线

知识点

环境安装与使用

selenium、 chromedriver、 firefox geckodriver

知识点

自动化用例录制

selenium IDE、录制、回放、基本使用

知识点

自动化测试用例结构分析

录制代码解析,代码结构优化

知识点

web 浏览器控制

打开网页、刷新、回退、最大化、最小化

知识点

常见控件定位方法

id name css xpath link 定位

知识点

强制等待与隐式等待

介绍 selenium 经典的三种等待方式

知识点

常见控件交互方法

点击,输入,清空,获取元素文本、尺寸等属性信息

实战

测试人论坛搜索功能自动化测试

用例设计、用例编写、断言

必修-中级

形式

章节

描述

知识点

高级定位-css

css 使用场景、语法

知识点

高级定位-xpath

xpath 使用场景、语法

知识点

显式等待高级使用

显式等待原理与使用

知识点

高级控件交互方法

右键点击、页面滑动、表单填写等自动化动作

知识点

网页 frame 与多窗口处理

多窗口,多 frame 下的窗口识别与切换

知识点

文件上传弹框处理

文件上传的自动化与弹框处理机制

知识点

自动化关键数据记录

行为日志、截图,page source

实战

电子商务产品实战

用例设计、日志封装、测试报告

训练营

知名产品web自动化测试实战

用例设计、日志封装、测试报告

必修-高级

形式

章节

描述

知识点

浏览器复用

利用远程调试技术实现自动化登录

知识点

Cookie 复用

利用 cookie 复用实现自动化登录

知识点

page object 设计模式

page object 模式的发展历史介绍、六大设计原则

知识点

异常自动截图

测试用例失败时自动截图

知识点

测试用例流程设计

测试装置的应用,套件级别的初始化与清理、用例级别的初始化与清理

实战

电子商务产品实战

page object 设计模式应用、BasePage 封装、基于 page object 模式的测试用例编写

训练营

web自动化测试进阶实战

page object 设计模式应用、BasePage 封装、基于 page object 模式的测试用例编写

资深与拓展

形式

章节

描述

知识点

selenium 多浏览器处理

chrome、firefox 等浏览器的自动化支持

知识点

执行 javascript 脚本

使用 selenium 直接在当前页面中进行 js 交互

知识点

selenium option 常用操作

selenium option 的介绍与使用

知识点

capability 配置参数解析

capability 用法 ,firefox chrome 等浏览器的专属 capability

 

 

2.环境安装与使用

Selenium的简介
  • 官方网站

https://www.selenium.dev/

  • 简介
  • 用于web浏览器测试的工具
  • 支持的浏览器包括IE,Firefox,Safari,Chrome,Edge等
  • 使用简单,可使用Java,Python等多种语言编写用例脚本
  • 主要由三个工具构成:WebDriver、IDE、Grid
Selenium架构图:

PageRequest 如何测试_自动化测试_05

Selenium环境配置步骤
  1. 准备好Python/Java环境
  2. 准备好selenium依赖
  3. driver的下载与配置(Mac与Windows不同)
  4. 在代码中import对应的依赖
Selenium的安装(Python)
  • 前提:
  • 配置好python环境
  • 配置好pip工具
  • 安装: pip install selenium
Selenium的安装(Java)
  • 前提:
  • Java环境
  • maven环境
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.0.0-rc-2</version>
</dependency>

 

<properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>11</java.version>
        <!-- 使用 Java 11 语言特性 ( -source 11 ) 并且还希望编译后的类与 JVM 11 ( -target 11 )兼容,您可以添加以下两个属性,它们是默认属性插件参数的名称-->
        <maven.compiler.target>11</maven.compiler.target>
        <!-- 对应junit Jupiter的版本号;放在这里就不需要在每个依赖里面写版本号,导致对应版本号会冲突-->
        <junit.jupiter.version>5.8.2</junit.jupiter.version>
        <maven.compiler.version>3.8.1</maven.compiler.version>
        <maven.surefire.version>3.0.0-M5</maven.surefire.version>
        <hamcrest.version>2.2</hamcrest.version>
        <!-- plugins -->
        <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>

    </properties>
    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0-rc-2</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.jupiter.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <version>${junit.jupiter.version}</version>
        </dependency>
    </dependencies>
    <build>
        <!-- maven 运行的依赖插件 -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <parameters>true</parameters>
                    <source>11</source>
                    <target>11</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M7</version>
                <configuration>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>
Driver的下载与配置步骤
  1. 下载浏览器对应的driver,谷歌浏览器和火狐浏览器选一个即可。
  • 官方链接:https://www.selenium.dev/documentation/en/webdriver/driver_requirements/
  1. 配置 driver 的环境变量
  2. 重启命令行工具,验证是否配置成功
chromedriver的下载-Windows
  • chromedriver的下载
  • 确定与浏览器匹配的driver版本
  • 根据使用的操作系统下载相应的 chromedriver
  • 淘宝镜像:
chromedriver 环境变量配置-Windows
验证配置chromedriver是否成功-Windows
  • 重启命令行,输入:chromedriver --version
  • 出现chromedriver版本信息则配置成功
geckodriver 配置-Windows
  • 下载geckodriver。
  • 没有chromedriver类似的对应关系,默认下载最新的driver版本
  • 根据使用的操作系统下载相应的 geckodriver
  • 淘宝镜像:https://registry.npmmirror.com/binary.html?path=geckodriver/
  • 配置步骤与谷歌浏览器的相同。
  • 输入geckodriver --version,验证是否配置成功。
chromedriver的下载-Mac
  • chromedriver的下载
  • 确定与浏览器匹配的driver版本
  • 根据使用的操作系统下载相应的 chromedriver
  • 淘宝镜像:

 

chromedriver 环境变量配置-Mac
  1. 进入命令行工具,确定当前的SHELL环境:echo $SHELL
  2. 根据自己的SHELL环境选择执行命令:
  • 如果显示/bin/bash,则vim ~/.bash_profile
  • 如果显示/bin/zshvim ~/.zshrc
  1. 在文件中添加:export PATH=$PATH:[chromedriver所在路径]
  2. 重启命令行工具
验证配置chromedriver是否成功-Mac
  • 输入chromedriver,验证是否配置成功
 geckodriver 配置-Mac
  • 下载geckodriver。
  • 没有chromedriver类似的对应关系,默认下载最新的driver版本
  • 根据使用的操作系统下载相应的 geckodriver
  • 淘宝镜像:https://registry.npmmirror.com/binary.html?path=geckodriver/
  • 配置步骤与谷歌浏览器的相同。
  • 输入geckodriver --version,验证是否配置成功。
在 python 中的使用
  • 谷歌浏览器演示
# 导入selenium 包
from selenium import webdriver

# 创建一个 Chromdriver 的实例。Chrome()会从环境变量中寻找浏览器驱动
driver = webdriver.Chrome()
# 打开网址
driver.get("https://www.baidu.com/")
# 关闭driver
driver.quit()
在 python 中的使用
  • 火狐浏览器演示
# 导入selenium 包
from selenium import webdriver

# 创建一个 Geckodriver 的实例。Firefox()会从环境变量中寻找浏览器驱动
driver = webdriver.Firefox()
# 打开网址
driver.get("https://www.baidu.com/")
# 关闭driver
driver.quit()
在 java 中的使用
  • 谷歌浏览器演示
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ChromeDemo {
    public static void main(String[] args) {
        // 创建一个 ChromeDriver 的实例,会自动从环境变量中寻找浏览器驱动
        WebDriver driver = new ChromeDriver();
        // 打开网页
        driver.get("https://ceshiren.com/");
        //关闭driver进程
        driver.quit();
    }
}
在 java 中的使用
  • 火狐浏览器演示
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class FireFoxDemo {
    public static void main(String[] args) {
      // 创建一个 Geckodriver 的实例。Firefox()会从环境变量中寻找浏览器驱动
        WebDriver driver = new FirefoxDriver();
        // 打开网页
        driver.get("https://ceshiren.com/");
        // 关闭driver进程
        driver.quit();
    }
}

3.自动化用例录制

SeleniumIDE用例录制使用场景
  • 刚开始入门UI自动化测试
  • 团队代码基础较差
  • 技术成长之后学习价值不高
SeleniumIDE的下载以及安装:
  • 官网:https://www.selenium.dev/
  • Chrome插件:https://chrome.google.com/webstore/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd
  • Firefox插件:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/
  • github release:https://github.com/SeleniumHQ/selenium-ide/releases
  • 其它版本:https://addons.mozilla.org/en-GB/firefox/addon/selenium-ide/versions/ 注意:Chrome插件在国内无法下载,Firefox可以直接下载。
 SeleniumIDE常用功能

PageRequest 如何测试_chrome_06

  1. 新建、保存、打开
  2. 开始和停止录制
  3. 运行8中的所有的实例
  4. 运行单个实例
  5. 调试模式
  6. 调整案例的运行速度
  7. 要录制的网址
  8. 实例列表
  9. 动作、目标、值
  10. 对单条命令的解释
  11. 运行日志
其他常用功能
  • 用例管理
  • 保存和回放
 SeleniumIDE脚本导出
  • Java
  • Python

4.自动化测试用例结构分析

标准的用例结构
  • 用例标题
  • 前提条件
  • 用例步骤
  • 预期结果
  • 实际结果
自动化测试用例结构:

用例标题

测试包、文件、类、方法名称

用例的唯一标识

前提条件

setup、setup_class(Pytest);

BeforeEach、BeforeAll(JUnit)

测试用例前的准备动作,比如读取数据或者driver的初始化

用例步骤

测试方法内的代码逻辑

测试用例具体的步骤行为

预期结果

assert 实际结果 = 预期结果

断言,印证用例是否执行成功

实际结果

assert 实际结果 = 预期结果

断言,印证用例是否执行成功

后置动作

teardown、teardown_class(Pytest);

@AfterEach、@AfterAll(JUnit)

脏数据清理、关闭driver进程

代码示例:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By


class TestDemo01():
    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # 添加全局隐式等待
        self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()

    def test_demo01(self):
        # 访问网站
        self.driver.get("https://www.baidu.com/")
        # 设置窗口
        self.driver.set_window_size(1330, 718)
        # 点击输入框
        self.driver.find_element(By.ID, "kw").click()
        # 输入框输入信息
        self.driver.find_element(By.ID, "kw").send_keys("斗破苍穹")
        # 点击搜索按钮
        self.driver.find_element(By.ID, "su").click()
        # 等待界面加载
        time.sleep(5)
        # 元素定位后获取文本信息
        res = self.driver.find_element(By.XPATH, '//*[@id="1"]/div/div[1]/h3/a[1]').text
        # 打印文本信息
        print(res)
        # 添加断言
        assert "斗破苍穹" in res
        # 查看界面展示
        time.sleep(5)

运行结果:

PageRequest 如何测试_前端_07

5.web浏览器控制

操作

使用场景

get

打开浏览器

web自动化测试第一步

refresh

浏览器刷新

模拟浏览器刷新

back

浏览器退回

模拟退回步骤

maximize_window

最大化浏览器

模拟浏览器最大化

minimize_window

最小化浏览器

模拟浏览器最小化

代码示例:
from selenium import webdriver
import time


class TestBrowserControl:

    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # 添加全局隐式等待
        self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()

    def test_open_web_page(self):
        # 打开网站
        self.driver.get('https://www.baidu.com/')
        # 等待一秒
        time.sleep(1)

    def test_refresh_web_page(self):
        # 打开网站
        self.driver.get('https://www.baidu.com/')
        # 等待一秒
        time.sleep(1)
        # 刷新网页
        self.driver.refresh()
        time.sleep(1)

    def test_window_back(self):
        # 打开网站
        self.driver.get('https://www.baidu.com/')
        # 等待2秒
        time.sleep(2)
        self.driver.get('https://www.sougou.com/')
        # 等待2秒
        time.sleep(2)
        # 返回上一个界面
        self.driver.back()
        # 等待2秒
        time.sleep(2)

    def test_max_window(self):
        # 打开网站
        self.driver.get('https://www.baidu.com/')
        # 等待一秒
        time.sleep(1)
        # 屏幕最大化
        self.driver.maximize_window()
        # 等待一秒
        time.sleep(1)

    def test_min_window(self):
        # 打开网站
        self.driver.get('https://www.baidu.com/')
        # 等待一秒
        time.sleep(1)
        # 屏幕最小化
        self.driver.minimize_window()
        # 等待一秒
        time.sleep(1)
 浏览器操作总结

PageRequest 如何测试_自动化测试_08

6.常见控件定位方法

方式

描述

class name

class 属性对应的值

css selector(重点)

css 表达式

id(重点)

id 属性对应的值

name(重点)

name 属性对应的值

link text

查找其可见文本与搜索值匹配的锚元素

partial link text

查找其可见文本包含搜索值的锚元素。如果多个元素匹配,则只会选择第一个元素。

tag name

标签名称

xpath(重点)

xpath表达式

代码示例:
import time
from selenium import webdriver

from selenium.webdriver.common.by import By


class TestElementLocation:

    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # 添加全局隐式等待
        self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()

    # 通过id定位
    def test_id(self):
        # 打开网站
        self.driver.get('https://www.baidu.com/')
        # 等待一秒
        time.sleep(1)

        self.driver.find_element(By.ID, "s-usersetting-top").click()
        # 等待两秒
        time.sleep(2)

    # name定位
    def test_name(self):
        # 打开网站
        self.driver.get('https://www.baidu.com')
        # 等待一秒
        time.sleep(1)

        self.driver.maximize_window()
        time.sleep(1)

        # 点击更多
        self.driver.find_element(By.NAME, "tj_briicon").click()
        # 等待两秒
        time.sleep(2)

    # css selector 定位
    def test_css_selector(self):
        # 打开网站
        self.driver.get('https://www.baidu.com')
        # 等待一秒
        time.sleep(1)

        self.driver.maximize_window()
        time.sleep(1)

        # 点击图片
        self.driver.find_element(By.CSS_SELECTOR, "#s-top-left > a:nth-child(6)").click()
        # 等待两秒
        time.sleep(2)

    # xpath定位
    def test_xpath(self):
        # 打开网站
        self.driver.get('https://www.baidu.com')
        # 等待一秒
        time.sleep(1)

        self.driver.maximize_window()
        time.sleep(1)

        # 点击图片
        self.driver.find_element(By.XPATH, '//*[@id="s-top-left"]/a[6]').click()
        # 等待两秒
        time.sleep(2)

    # link定位(1.一定是a标签 2.输入的元素为标签内的文本)
    def test_link(self):
        # 打开网站
        self.driver.get('https://www.baidu.com')
        # 等待一秒
        time.sleep(1)

        self.driver.maximize_window()
        time.sleep(1)

        # 点击图片
        self.driver.find_element(By.LINK_TEXT, '图片').click()
        # 等待两秒
        time.sleep(2)

    # class_name 定位
    def test_class(self):
        pass

    # 使用tag_name定位元素
    def test_tag_name(self):
        pass

    # 使用partial_link_text定位元素
    def test_partial_link_text(self):
        pass
元素定位总结

PageRequest 如何测试_自动化测试_09

7.强制等待与隐式等待

为什么要添加等待?
  • 避免页面未渲染完成后操作,导致的报错
 代码示例:
from selenium import webdriver
from selenium.webdriver.common.by import By


class TestElementLocation:

    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # # 添加全局隐式等待
        # self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()


    def test_wait_sleep(self):
        self.driver.get("https://")
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")
 直接等待
  • 解决方案:在报错的元素操作之前添加等待
  • 原理:强制等待,线程休眠一定时间
  • time.sleep(3)
import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class TestElementLocation:

    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # # 添加全局隐式等待
        # self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()


    def test_wait_sleep(self):
        self.driver.get("https://")
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")

    def test_direct_wait(self):
        self.driver.get("https://")
        time.sleep(3)
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")
 隐式等待
  • 问题:难以确定元素加载的具体等待时间。
  • 解决方案:针对于寻找元素的这个动作,使用隐式等待添加配置。
  • 原理:设置一个等待时间,轮询查找(默认0.5秒)元素是否出现,如果没出现就抛出异常
import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class TestElementLocation:

    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # # 添加全局隐式等待
        # self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()


    def test_wait_sleep(self):
        self.driver.get("https://")
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")

    def test_direct_wait(self):
        self.driver.get("https://")
        time.sleep(3)
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")

    def test_implicit_wait(self):
        self.driver.get("https://")
        self.driver.implicitly_wait(5)
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")
 隐式等待无法解决的问题
  • 元素可以找到,使用点击等操作,出现报错
  • 原因:
  • 页面元素加载是异步加载过程,通常html会先加载完成,js、css其后
  • 元素存在与否是由HTML决定,元素的交互是由css或者js决定
  • 隐式等待只关注元素能不能找到,不关注元素能否点击或者进行其他的交互
  • 解决方案:使用显式等待
显式等待基本使用(初级):
  • 示例: WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件)
  • 原理:在最长等待时间内,轮询,是否满足结束条件
  • 注意:在初级时期,先关注使用
import time

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait


class TestElementLocation:

    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # # 添加全局隐式等待
        # self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()


    def test_wait_sleep(self):
        self.driver.get("https://")
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")

    def test_direct_wait(self):
        self.driver.get("https://")
        time.sleep(3)
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")

    def test_implicit_wait(self):
        self.driver.get("https://")
        self.driver.implicitly_wait(5)
        # 不加等待,可能会因为网速等原因产生报错
        self.driver.find_element(By.XPATH, "//*[text()='个人中心']")

    def test_explicit_wait(self):
        self.driver = webdriver.Chrome()
        self.driver.get("https://")
        WebDriverWait(self.driver, 10).until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, '#success_btn')))
        self.driver.find_element(By.CSS_SELECTOR, "#success_btn").click()
总结

类型

使用方式

原理

适用场景

直接等待

time.sleep(等待时间))

强制线程等待

调试代码,临时性添加

隐式等待

driver.implicitly_wait(等待时间)

在时间范围内,轮询查找元素

解决找不到元素问题,无法解决交互问题

显式等待

WebDriverWait(driver实例, 最长等待时间, 轮询时间).until(结束条件)

设定特定的等待条件,轮询操作

解决特定条件下的等待问题,比如点击等交互性行为

PageRequest 如何测试_PageRequest 如何测试_10

8.常见控件交互方法

点击,输入,清空
  • 点击百度搜索框
  • 输入”三国杀,启动!”
  • 清空搜索框中信息
import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class TestControl():
    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # 添加全局隐式等待
        self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()

    def test_click_send_clear(self):
        self.driver.get('https://www.baidu.com')
        # 点击百度搜索框
        self.driver.find_element(By.ID, "kw").click()
        # 输入"三国杀,启动!"
        self.driver.find_element(By.ID, "kw").send_keys("三国杀,启动!")
        time.sleep(2)
        # 清空搜索框中信息
        self.driver.find_element(By.ID, "kw").clear()
        time.sleep(2)
 获取元素属性信息
  • 原因:
  • 定位到元素后,获取元素的文本信息,属性信息等
  • 目的:
  • 根据这些信息进行断言或者调试
获取元素属性信息的方法
  • 获取元素文本
  • 获取元素的属性(html的属性值)

PageRequest 如何测试_用例_11

 代码示例:
import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class TestControl():
    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # 添加全局隐式等待
        self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()

    def test_click_send_clear(self):
        self.driver.get('https://www.baidu.com')
        # 点击百度搜索框
        self.driver.find_element(By.ID, "kw").click()
        # 输入"三国杀,启动!"
        self.driver.find_element(By.ID, "kw").send_keys("三国杀,启动!")
        time.sleep(2)
        # 清空搜索框中信息
        self.driver.find_element(By.ID, "kw").clear()
        time.sleep(2)

    def test_get_element_attribute(self):
        self.driver.get('https://')
        # ** 元素的文本获取
        result = self.driver.find_element(By.ID, 'locate_id').text
        print(result)
        # # ** 元素的标签获取
        result = self.driver.find_element(By.ID, 'locate_id').tag_name
        print(result)
        # # ** 元素的属性获取
        result = self.driver.find_element(By.ID, 'locate_id').get_attribute('name')
        print(result)
        result = self.driver.find_element(By.ID, 'locate_id').get_attribute('class')
        print(result)
        result = self.driver.find_element(By.ID, 'locate_id').get_attribute('style')
        print(result)
        result = self.driver.find_element(By.ID, 'locate_id').get_attribute('id')
        print(result)

9.自动化测试定位策略

  • 不知道应该使用哪种定位方式?
  • 元素定位不到无法解决?

PageRequest 如何测试_前端_12

通用 Web 定位方式

定位策略

描述

class name

通过 class 属性定位元素

css selector

通过匹配 css selector 定位元素

id

通过 id 属性匹配元素

name

通过 name 属性定位元素

link text

通过 <a>text</a> 标签中间的 text 文本定位元素

partial link text

通过 <a>text</a> 标签中间的 text 文本的部分内容定位元素

tag name

通过 tag 名称定位元素

xpath

通过 xpath 表达式匹配元素

选择定位器通用原则
  1. 与研发约定的属性优先(class属性: [name='locate'])
  2. 身份属性 id,name(web 定位)
  3. 复杂场景使用组合定位:
  • xpath,css
  • 属性动态变化(id,text)
  • 重复元素属性(id,text,class)
  • 父子定位(子定位父)
  1. js定位
 Web 弹框定位
  • 场景
  • web 页面 alert 弹框
  • 解决:
  • web 需要使用 driver.switchTo().alert() 处理
下拉框/日期控件定位
  • 场景:
  • <input>标签组合的下拉框无法定位
  • <input>标签组合的日期控件无法定位
  • 解决:
  • 面对这些元素,我们可以引入 JS 注入技术来解决问题。
 文件上传定位
  • 场景:
  • input 标签文件上传
  • 解决:
  • input 标签直接使用 send_keys()方法

10.搜索功能自动化测试

测试用例:

用例标题

前提条件

用例步骤

预期结果

实际结果

搜索功能

进入论坛首页

1. 点击搜索按钮

2. 输入搜索关键词

3. 点击搜索按钮

1. 搜索成功

2. 搜索结果列表包含关键字

代码示例:
import time

from selenium import webdriver
from selenium.webdriver.common.by import By


class TestForum():
    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # 添加全局隐式等待
        self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()

    # 动态元素的定位
    def test_dynamic_id(self):
        self.driver.get('https://')
        self.driver.find_element(By.CSS_SELECTOR, "[placeholder='搜索']").send_keys("appium")
        self.driver.find_element(By.CSS_SELECTOR, '.search-cta').click()
        time.sleep(2)
        web_element = self.driver.find_element(By.CSS_SELECTOR, ".topic-title")
        print(web_element.text)
        assert "appium" in web_element.text.lower()
例题:

1.以下关于css选择器语法说明正确的是

 选项A:A:并集使用逗号:, 【正确答案】

 选项B:B:并集使用空格:

 选项C:C:并集使用大于号:>

 选项D:D:并集使用加号:+

正确答案: 选项A:A:并集使用逗号:,

逗号表示并集,空格是子孙,大于号是父子,加号是相邻兄弟

2.下面关于selenium 说法,错误的是

选项A:A:selenium 根据网页元素的属性来定位元素

选项B:B:支持桌面应用软件的自动化测试 【正确答案】

选项C:C:支持移动端网页应用的自动化测试

选项D:D:支持web端页面的UI自动化测试

正确答案: 选项B:B:支持桌面应用软件的自动化测试

selenium 根据网页元素的属性来定位元素,支持移动端网页应用的自动化测试,支持web端页面的UI自动化测试不支持桌面应用软件的自动化测试 

 3.Selenium定位中link定位适用于哪个标签

 选项A:A:<div>标签

 选项B:B:<span>标签

 选项C:C:<a>标签 【正确答案】

 选项D:D:<input>标签

正确答案: 选项C:C:<a>标签

link定位只针对于<a>标签,其他标签均无法使用

4.关于selenium 下面说法正确的是

 选项A:A:selenium 对web页面有良好的支持 【正确答案】

 选项B:B:测试 Chrome/Firefox 浏览器,可以使用任意版本的 webdriver

 选项C:C:只有windows和mac可以安装selenium

 选项D:D:selenium 只支持 java 和 python 语言

正确答案: 选项A:A:selenium 对web页面有良好的支持

1、selenium 安装方式 pip install selenium,

2、测试浏览器需要下载对应浏览器版本的webdriver,

3、selenium 支持多平台windows,mac,linux,

4、selenium 支持多语言java,python, ruby等

 5.下面关于动态元素说法不正确的是

 选项A:A:元素的属性会动态变化

 选项B:B:动态元素可以使用相对定位进行定位

 选项C:C:动态元素可以使用xpath 的轴定位方式进行元素定位

 选项D:D:动态元素必须使用绝对定位 【正确答案】

正确答案: 选项D:D:动态元素必须使用绝对定位

动态元素是元素的属性会动态变化,可以通过遍历的方式找到对应的的元素,动态元素可以使用xpath 的轴定位方式进行元素定位,动态元素不必须使用绝对定位,可以使用相对位置定位

6.web自动化中,通过下面哪种方法可以获取元素的属性信息

 选项A:A:java语法:getAttribute('属性');python语法:get_attribute('属性') 【正确答案】

 选项B:B:java语法:getElement('属性');python语法:get_element('属性')

 选项C:C:java语法:getAttributes('属性');python语法:get_attributes('属性')

 选项D:D:java语法:getElements('属性');python语法:get_elements('属性')

正确答案: 选项A:A:java语法:getAttribute('属性');python语法:get_attribute('属性')

java语法:getAttribute('属性');python语法:get_attribute('属性')可以获取元素属性信息,其他均无法拿到

7.xpath语法中,通过下标获取最后一个元素正确的是

 选项A:A:[last()] 【正确答案】

 选项B:B:[-1]

 选项C:C:[first()]

 选项D:D:[last]

正确答案: 选项A:A:[last()]

last()可以获取最后一个元素,下标里只能是正序,无法通过倒序-1获取

8.判断面上的元素是否成功展示,下面错误的说法

 选项A:A:当未找到元素时,添加捕获异常的代码块

 选项B:B:使用elements 获取一组元素,判断元素组的长度

 选项C:C:使用显式等待来判断元素是否展示

 选项D:D:使用隐式等待来判断元素是否展示 【正确答案】

正确答案: 选项D:D:使用隐式等待来判断元素是否展示

使用隐式等待无法准确的判断元素是否展示

9.如何定位页面上动态加载的元素,下面解决方法正确的是

 选项A:A:使用查找元素的方法直接可以找到

 选项B:B:触发动态事件,然后使用查找元素的方法

 选项C:C:使用隐式等待,然后使用查找元素的方法

 选项D:D:触发动态事件,同时启动隐式等待,然后使用查找元素的方法 【正确答案】

正确答案: 选项D:D:触发动态事件,同时启动隐式等待,然后使用查找元素的方法

定位页面上动态加载的元素,需要在触发动态事件,同时启动隐式等待,然后使用查找元素的方法

10.web自动化中,高级控件交互ActionChains模拟回车的关键字是?

 选项A:A:SHIFT

 选项B:B:ENTER 【正确答案】

 选项C:C:CONTROL

 选项D:D:ALT

正确答案: 选项B:B:ENTER

键盘中ENTER为回车键,所以ActionChains模拟回车就使用ENTER关键字

11.关于xpath定位元素说法正确的是

 选项A:A:可以通过子元素定位父元素 【正确答案】

 选项B:B:不可以通过父元素定位子元素

 选项C:C:`.` 代表父结点

 选项D:D:`*`代表父结点

正确答案: 选项A:A:可以通过子元素定位父元素

xpath可以通过子元素定位到父元素

12.web自动化过程中,frame可以通过什么来定位然后进行切换

 选项A:A:index下标定位 【正确答案】

 选项B:B:id定位(id属性存在) 【正确答案】

 选项C:C:name定位(name属性存在) 【正确答案】

 选项D:D:css或xpath定位 【正确答案】

正确答案: 选项A:A:index下标定位,选项B:B:id定位(id属性存在),选项C:C:name定位(name属性存在),选项D:D:css或xpath定位

多frame切换时,可以使用下标,id,name和WebElement对象来定位

13.下面关于 selenium 说法正确的是:

 选项A:A:selenium 支持chrome,firefox等多浏览器 【正确答案】

 选项B:B:selenium 支持多平台 【正确答案】

 选项C:C:selenium 可以作为浏览器兼容性测试的工具 【正确答案】

 选项D:D:selenium 支持分布式 【正确答案】

正确答案: 选项A:A:selenium 支持chrome,firefox等多浏览器,选项B:B:selenium 支持多平台,选项C:C:selenium 可以作为浏览器兼容性测试的工具,选项D:D:selenium 支持分布式selenium 多浏览器处理,支持chrome,firefox等多浏览器,支持多平台,可以作为浏览器兼容性测试的工具,selenium 支持分布式

14.适合做UI自动化测试的场景有哪些

 选项A:A:业务流程不频繁改动 【正确答案】

 选项B:B:UI 元素不频繁改动 【正确答案】

 选项C:C:需要频繁回归的场景 【正确答案】

 选项D:D:核心用例场景 【正确答案】

正确答案: 选项A:A:业务流程不频繁改动,选项B:B:UI 元素不频繁改动,选项C:C:需要频繁回归的场景,选项D:D:核心用例场景

ABCD均符合做UI自动化测试的场景

15.下面关于Selenium 定位正确的是

 选项A:A:通过css 定位可以通过父元素找子元素 【正确答案】

 选项B:B:通过css 定位可以通过子元素找父元素

 选项C:C:通过xpath 定位可以通过父元素找子元素 【正确答案】

 选项D:D:通过xpath 定位可以通过子元素找父元素 【正确答案】

正确答案: 选项D:D:通过xpath 定位可以通过子元素找父元素,选项A:A:通过css 定位可以通过父元素找子元素,选项C:C:通过xpath 定位可以通过父元素找子元素

通过xpath 定位可以通过父元素找子元素 通过xpath 定位可以通过子元素找父元素 通过css 定位可以通过父元素找子元素

16.用例在运行过程中经常会出现不稳定的情况,比如这次可以通过,下次就执行失败,如何去提升用例的稳定性?

 选项A:A:多加强制等待

 选项B:B:用例中使用隐式等待或显式等待 【正确答案】

 选项C:C:不使用绝对定位 【正确答案】

 选项D:D:以上都不正确得分:

正确答案: 选项B:B:用例中使用隐式等待或显式等待,选项C:C:不使用绝对定位

隐式等待,用例在运行过程中经常会出现不稳定的情况,比如这次可以通过,下次就执行失败,可以在创建完driver 之后设置 隐式等待,隐式等待是全局生效的。每次查找元素的时候都会动态的找到这个元素。使用相对定位可以提升用例稳定性

17.使用 css selector 定位时,当父标签中有很多相同的子标签时,通过索引找到所需要定位的元素,下面说法错误的是

 选项A:A:父标签[父标签属性名=父标签属性值]>子标签:nth-child(索引序号)

 选项B:B:父标签[父标签属性名=父标签属性值]>子标签:nth-child[索引序号] 【正确答案】

 选项C:C:索引号从1开始

 选项D:D:索引号从0开始 【正确答案】

正确答案: 选项B:B:父标签[父标签属性名=父标签属性值]>子标签:nth-child[索引序号],选项D:D:索引号从0开始表达式写法:父标签[父标签属性名=父标签属性值]>子标签:nth-child(索引序号) 索引号从1开始 

18.webdriver 提供哪些常见类型的驱动程序

 选项A:A:FireFoxDriver(geckodriver) 【正确答案】

 选项B:B:InternetExploer Driver 【正确答案】

 选项C:C:ChromeDriver 【正确答案】

 选项D:D:Safari Driver 【正确答案】得分:

正确答案: 选项A:A:FireFoxDriver(geckodriver),选项B:B:InternetExploer Driver,选项C:C:ChromeDriver,选项D:D:Safari Driver

webdriver 提供的常见的驱动程序 有FireFoxDriver(geckodriver), InternetExploer Driver.   ChromeDriver.  Safari Driver等

19.selenium 可以模拟的操作,下面说法正确的

 选项A:A:点击,输入操作 【正确答案】

 选项B:B:滑动操作 【正确答案】

 选项C:C:拖拽操作 【正确答案】

 选项D:D:页面滚动操作 【正确答案】

正确答案: 选项D:D:页面滚动操作,选项A:A:点击,输入操作,选项B:B:滑动操作,选项C:C:拖拽操作元素操作,selenium 不可以模拟向页面发送鼠标滚轮操作

20.关于 selenium 组件下面说法正确的是

 选项A:A:selenium 包括三大组件 【正确答案】

 选项B:B:selenium IDE 用于录制回放脚本 【正确答案】

 选项C:C:selenium Grid 实现分布并发执行用例 【正确答案】

 选项D:D:selenium webdriver 负责自动化测试 【正确答案】

正确答案: 选项A:A:selenium 包括三大组件,选项B:B:selenium IDE 用于录制回放脚本,选项C:C:selenium Grid 实现分布并发执行用例,选项D:D:selenium webdriver 负责自动化测试selenium 包括三大组件- selenium  IDE 用于录制回放脚本- selenium Grid 实现分布并发执行用例- selenium webdriver 负责自动化测试

11.用户端Web自动化测试

需求:
  1. 要求实现搜索功能的Web自动化测试。
  2. Selenium 常用操作与用例编写。
  3. 使用隐式等待优化代码。
  4. 考虑特殊场景的验证。
  • 输入内容过长。
  • 特殊字符。
  • 其他。
  1. 使用参数化优化代码。
场景描述
  1. 打开测试人论坛。
  2. 跳转到高级搜索页面
  3. 搜索输入框输入搜索关键字。关键字清单如下:
Selenium
Appium
面试
  1. 打印搜索结果的第一个标题。
  2. 断言:第一个标题是否包含关键字。
代码示例:

test_search.py

import os
import time

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

from web_automation_testing.test_search_ceshiren.utils.utils import Utils


def get_datas(level):
    root_path = os.path.dirname(os.path.abspath(__file__))
    # print(root_path)
    yaml_path = os.sep.join([root_path, 'datas\\document\\search.yaml'])
    # print(yaml_path)
    yaml_datas = Utils.get_yaml_data(yaml_path)
    # print(yaml_datas)
    datas = yaml_datas.get('search').get(level).get('datas')
    return datas


class TestSearch():
    def setup_method(self, method):
        # 实例化chromedriver
        self.driver = webdriver.Chrome()
        # 添加全局隐式等待
        self.driver.implicitly_wait(5)

    def teardown_method(self, method):
        # 关闭driver
        self.driver.quit()

    @pytest.mark.parametrize('param', get_datas("P0"))
    def test_search(self, param):
        self.driver.get('https://ceshiren.com/search')
        input_field = self.driver.find_element(By.CSS_SELECTOR, "[placeholder='搜索']")
        input_field.send_keys(param)

        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, '.search-cta')))
        search_button = self.driver.find_element(By.CSS_SELECTOR, '.search-cta')
        search_button.click()

        title_first = self.driver.find_element(By.CSS_SELECTOR, '.topic-title')
        print(title_first.text)

        assert param.lower() in title_first.text.lower()

    @pytest.mark.parametrize('param', get_datas("P1"))
    def test_search_the_input_is_too_long(self, param):
        self.driver.get('https://ceshiren.com/search')
        input_field = self.driver.find_element(By.CSS_SELECTOR, "[placeholder='搜索']")
        input_field.send_keys(param)

        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, '.search-cta')))
        search_button = self.driver.find_element(By.CSS_SELECTOR, '.search-cta')
        search_button.click()

        time.sleep(2)
        title_first = self.driver.find_element(By.CSS_SELECTOR, '.no-results-suggestion')
        print(title_first.text)

        assert "找不到您要找的内容?" in title_first.text

    @pytest.mark.parametrize('param', get_datas("P2"))
    def test_search_special_characters(self, param):
        self.driver.get('https://ceshiren.com/search')
        input_field = self.driver.find_element(By.CSS_SELECTOR, "[placeholder='搜索']")
        input_field.send_keys(param)

        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, '.search-cta')))
        search_button = self.driver.find_element(By.CSS_SELECTOR, '.search-cta')
        search_button.click()

        time.sleep(2)
        title_first = self.driver.find_element(By.CSS_SELECTOR, '.no-results-suggestion')
        print(title_first.text)

        assert "找不到您要找的内容?" in title_first.text

conftest.py

def pytest_collection_modifyitems(session, config, items: list):
    print(items)
    for item in items:
        item.name = item.name.encode('utf-8').decode('unicode-escape')
        item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')

utils.py

import yaml


class Utils:

    @classmethod
    def get_yaml_data(cls, yaml_path):
        '''
        读取 yaml 文件数据
        :param yaml_path: yaml 文件路径
        :return: 读取到的数据
        '''
        with open(yaml_path, encoding="utf-8") as f:
            datas = yaml.safe_load(f)
        return datas

search.yaml

search:
  P0:
    datas:
      - 'Selenium'
      - 'Appium'
      - '面试'
  P1:
    datas:
      - 'f89465456ds4af894894654654894984fs8964f894a89s44f98d6sa4f84dsa98f4d9sa4fdsa4f5d6sa4f98d4f6a5s4df9684dsad89f4f4ds56f456sadf465as4df564asf65ds4af654dsa65f'
  P2:
    datas:
      - '/*--*/*-/-*/*-/-*/-*/-*/-*/*-/-*/-*/-*/-*/-*/++/-*/*-/-*/-+'

项目结构:

PageRequest 如何测试_用例_13

运行结果:

PageRequest 如何测试_前端_14