【软件测试】8. 自动化测试实践
- [一、 编写web测试用例](#一、 编写web测试用例)
- 二、自动化测试脚本开发
-
- [2.1 用例需要用到的配置(common包)](#2.1 用例需要用到的配置(common包))
- [2.2 存放测试用例文件(tests包)](#2.2 存放测试用例文件(tests包))
- 三、将自动化测试补充到测试报告
-
- [3.1 测试报告模板](#3.1 测试报告模板)
- [3.2 测试报告主要内容](#3.2 测试报告主要内容)
以码海阁博客系统为例,基于web项目进行完整的自动化实战。

一、 编写web测试用例

二、自动化测试脚本开发
参考测试用例,创建自动化测试项目,编写自动化测试脚本。
项目代码结构:
2.1 用例需要用到的配置(common包)
(1) Utils.py
python
import datetime
import os.path
import sys
# 创建一个浏览器对象
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from webdriver_manager.microsoft import EdgeChromiumDriverManager
class Driver:
driver = ""
def __init__(self):
options = webdriver.EdgeOptions()
self.driver = webdriver.Edge(service = Service(EdgeChromiumDriverManager().install()), options=options)
self.driver.implicitly_wait(2)
def getScreeShot(self):
# 创建屏幕截图
# 图片文件名称:./2024-07-19-134936.png
dirname = datetime.datetime.now().strftime("%Y-%m-%d")
# 判断dirname文件夹是否已经存在,若不存在则创建文件夹
# ../images/2024-07-19
if not os.path.exists("../images/" + dirname): # ../images/2024-07-19
os.mkdir("../images/" + dirname)
# 2024-07-19-134936.png
# 图片路径:./images/调用方法-2024-07-19/2024-07-19-134936.png
# 图片路径:./images/LoginSucTest-2024-07-19/2024-07-19-134936.png
# 图片路径:./images/LoginFailTest-2024-07-19/2024-07-19-134936.png
filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S") + ".png"
self.driver.save_screenshot("../images/" + dirname + "/" + filename)
BlogDriver = Driver()
2.2 存放测试用例文件(tests包)
(1)BlogLogin.py(博客登录页相关测试用例)
python
# 导入time模块,可以让程序暂停等待(比如等待页面加载)
import time
# 从selenium库中导入By,用来告诉程序"用哪种方式找元素"(比如用ID、CSS选择器)
from selenium.webdriver.common.by import By
# 从common文件夹的Utils.py文件中导入BlogDriver(就是之前创建好的浏览器对象)
from common.Utils import BlogDriver
# 定义一个类,用来测试"博客登录页面"的所有功能
# 类就相当于一个"工具箱",里面放着跟登录相关的所有测试方法
class BlogLogin:
# 类的属性:存放登录页面的网址(暂时是空字符串,后面会赋值)
url = ""
# 类的属性:存放浏览器驱动对象(暂时是空字符串,后面会赋值)
driver = ""
# 构造方法:当你写 BlogLogin() 创建对象时,这个方法会自动执行
def __init__(self):
# 把登录页面的网址存到 self.url 里
self.url = "http://192.168.47.135:8653/blog_system/blog_login.html"
# 把之前创建好的浏览器对象拿过来,存到 self.driver 里
# 注意:所有测试类都共用这一个浏览器,不会重复打开
self.driver = BlogDriver.driver
# 让浏览器打开登录页面
self.driver.get(self.url)
# 测试用例1:测试"用正确的账号密码能否登录成功"
def LoginSucTest(self):
# 步骤1:找到"用户名输入框",先清空里面可能已有的文字
self.driver.find_element(By.CSS_SELECTOR, "#username").clear()
# 步骤2:找到"密码输入框",先清空里面可能已有的文字
self.driver.find_element(By.CSS_SELECTOR, "#password").clear()
# 步骤3:在用户名框里输入正确的用户名 "zhangsan"
self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhangsan")
# 步骤4:在密码框里输入正确的密码 "123456"
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
# 步骤5:找到"登录按钮"并点击
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
# 步骤6:验证是否登录成功
# 登录成功后页面会跳转到首页,首页上会显示用户的昵称
# 如果能找到这个昵称元素,说明登录成功;如果找不到,程序会报错
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3")
# 步骤7:截个图,保存当前页面的样子(方便以后看结果)
BlogDriver.getScreenShot()
# 步骤8:返回登录页面(为了下一个测试用例能重新开始)
self.driver.back()
# 测试用例2:测试"用错误的密码能否登录失败"
def LoginFailTest(self):
# 注意:如果多次调用 send_keys,文字会拼在一起,而不是替换
# 比如先 send_keys("abc") 再 send_keys("123"),结果变成 "abc123"
# 所以要先用 clear() 清空输入框,再输入新内容
# 步骤1:找到"用户名输入框",清空
self.driver.find_element(By.CSS_SELECTOR, "#username").clear()
# 步骤2:找到"密码输入框",清空
self.driver.find_element(By.CSS_SELECTOR, "#password").clear()
# 步骤3:输入正确的用户名 "zhangsan"
self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhangsan")
# 步骤4:输入错误的密码 "123"(正确密码应该是 "123456")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123")
# 步骤5:点击登录按钮
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
# 步骤6:获取页面上的错误提示文字
# 登录失败时,页面上会显示"用户名或密码错误!"
# 用 find_element 找到这个提示,用 .text 取出里面的文字,存到 actual 变量里
actual = self.driver.find_element(By.CSS_SELECTOR, "#body").text
# 步骤7:截个图,保存错误页面
BlogDriver.getScreenShot()
# 步骤8:用 assert 断言来检查结果是否符合预期
# 如果 actual 等于 "用户名或密码错误!",说明测试通过,程序继续
# 如果 actual 不等于 "用户名或密码错误!",说明测试失败,程序报错停止
assert actual == "用户名或密码错误!"
(2)BlogList.py(博客首页相关测试用例)
python
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver
# 博客首页测试用例
class BlogList:
url = ""
driver = ""
def __init__(self):
# 注意:列表页URL,不是登录页
self.url = "http://8.137.19.140:9090/blog_list.html"
self.driver = BlogDriver.driver
self.driver.get(self.url)
# 测试首页(登录情况下)
def ListTestByLogin(self):
# 1. 测试博客标题是否存在(第一篇文章的标题链接)
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > a")
# 2. 测试编辑按钮是否存在
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > a.btn-edit")
# 3. 测试博客内容是否存在
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > p")
# 4. 个人信息-检查昵称是否存在
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3")
# 5. 添加屏幕截图
BlogDriver.getScreenShot()
(3)BlogDetail.py(博客详情页相关测试用例)
python
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver
# 测试博客详情页
class BlogDetail:
url = ""
driver = ""
def __init__(self):
self.url = "http://8.137.19.140:9090/blog_detail.html?blogId=2"
self.driver = BlogDriver.driver
self.driver.get(self.url)
# 登录状态下的博客详情页的测试
def DetailTestByLogin(self):
# 检查标题
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.title")
# 检查时间
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.date")
# 检查内容
self.driver.find_element(By.CSS_SELECTOR, "#detail > p")
# 屏幕截图
BlogDriver.getScreenShot()
(4)BlogEdit.py(博客编辑页相关测试用例)
python
import time
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver
# 测试博客编辑页面
class BlogEdit:
url = ""
driver = ""
def __init__(self):
self.url = "http://8.137.19.140:9090/blog_login.html"
self.driver = BlogDriver.driver
self.driver.get(self.url)
# 正确发布博客(登录状态下)
def EditSucTestByLogin(self):
self.driver.find_element(By.CSS_SELECTOR, "#title").send_keys("自动化测试创建")
# 找到编辑区,输入关键词(编辑区域不可操作)
# 通过点击菜单栏达到编辑区域不为空的目的
# 博客系统编辑区域默认情况下就不为空,可以暂不处理
# 直接点击发布按钮来发布博客
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
# 点击完成之后出现页面跳转,页面跳转需要加载时间,可能会出现代码执行的速度比页面渲染的速度更快,导致元素查找不到
# 可以添加隐式等待/显示等待
# 隐式等待:创建浏览器对象之后就可以加上,因为隐式等待的作用域在driver整个生命周期
# 显示等待:可以作用在当前代码中
actual = self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > a").text
assert actual == "自动化测试创建"
# 屏幕截图
BlogDriver.getScreenShot()
(5)RunTest.py
python
from tests import BlogLogin
from tests import BlogList
from tests import BlogDetail
from common.Utils import BlogDriver
from tests import BlogEdit
if __name__ == "__main__":
BlogLogin.BlogLogin().LoginFailTest()
BlogLogin.BlogLogin().LoginSucTest()
# 登录成功之后就可以调用博客首页测试首页的用例(登录状态)
BlogList.BlogList().ListTestByLogin()
# 测试登录状态下的博客详情页
BlogDetail.BlogDetail().DetailTestByLogin()
# 博客编辑页面
BlogEdit.BlogEdit().EditSucTestByLogin()
# 执行浏览器的退出
BlogDriver.driver.quit()

三、将自动化测试补充到测试报告

3.1 测试报告模板

类似这种:

3.2 测试报告主要内容


类似这种:


