【软件测试】8. 自动化测试实践

【软件测试】8. 自动化测试实践

以码海阁博客系统为例,基于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 测试报告主要内容


类似这种:

相关推荐
AINative软件工程2 小时前
LLM Prompt Registry 工程实践:集中管理 Prompt,让模型调用不再散落在代码各处
后端·python·llm
Patrick在香港2 小时前
MCP 的 initialize 握手真的没了?67 行标准库实测 2026-07-28 规范
python·agent·claude·mcp·json-rpc
vx_Biye_Design2 小时前
springboot角色扮演服务平台65161-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·spring·课程设计
追烽少年x3 小时前
从零构建一个3D点云预览器:Python + PySide6 + pyqtgraph 实战
python·3d
weixin_440401693 小时前
质朴的爬虫+数据处理
爬虫·python·数据分析·pandas
估值探索者3 小时前
【Python量化系统工程实战 #01】数据存储选型 CSVSQLiteMySQL 对比与 SQLite 实战建库
开发语言·jvm·python·sqlite·api接口·数据api接口·股票数据api接口
计算机毕业编程指导师3 小时前
计算机毕设答辩技巧:基于Hadoop+Django的公共交通运营数据分析与可视化系统怎么做 源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·spark·毕业设计·课程设计·交通运行
砚底藏山河3 小时前
量化实战:行情数据 Schema 演进与向后兼容
java·python·金融·maven
苏离~Hack3 小时前
InfoScraper:面向授权目标的一站式资产信息收集工具
python
计算机毕业编程指导师3 小时前
【计算机毕设选题推荐】基于Hadoop+Django高频电力消耗大数据分析系统从0到1 源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
hadoop·python·数据分析·spark·毕业设计·课程设计·电力