【软件测试】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 测试报告主要内容


类似这种:

相关推荐
楠楠子呀1 小时前
从零构建高性能 WhatsApp 链接生成器与重定向服务:架构与路由解析
redis·python·容器·架构·flink·散列表·flume
OPEN-F1 小时前
Python进阶教程:算法与数据结构入门
开发语言·python
薛定猫AI1 小时前
【技术干货】Claude Code多模型代理与反馈闭环:Python实现可验证的AI编程工作流
开发语言·python·ai编程
每天一道题2 小时前
从 async/await 到幂等恢复:把 Python 并发和 Agent Runtime 一次讲清楚
分布式·python
一只积极向上的小咸鱼2 小时前
pytorch 与资源核算
人工智能·pytorch·python
reasonsummer2 小时前
【办公类110-08】20260807园园通-“小班“户籍地址和居住地址补充完整+外省市所在“省市区”两个按钮手工填写(Python+EXCEL)
python·excel·园园通
whcyhhh2 小时前
头歌实践教学平台:数据科学与大数据技术导论(五)
大数据·数据库·python
overmind2 小时前
oeasy python 139 字典排序_快速生成_sorted
python