博客系统测试报告

一、项目背景

  1. 我的博客系统是一个典型的前后端分离的是一个Web项目。
  2. 由四个页面构成:博客登录页面、博客列表页面、博客详情页面、博客编辑页面。其主要功能有:登录、查看博客、编辑博客、发布博客以及删除博客等。
  3. 该系统涵盖了Web应用常见的核心模块,包括​​用户登录、​​数据操作​​(文章的增、删、改、查)、​​UI交互​​(表单填写、按钮点击、导航跳转)以及​​状态管理​​(登录前后界面差异)。这为自动化测试脚本的编写提供了丰富且具有代表性的场景。

二、项目功能

1. 登录页面

登录页面:

  • 输入账号和密码登录(注:账号和密码直接写入数据库的,所以没有注册功能)
  • 登录成功后跳转到博客列表页
  • 菜单栏:在右上角存在主页(博客列表页)和写博客两个按钮
    • 登录状态下:点击主页可以跳转到博客详情页;点击写博客可以跳转到博客编辑页
    • 未登录状态下:点击主页不跳转,强制登录

2. 博客列表页

博客列表页:

  • 登录状态下:页面才可以正常打开。在博客列表可以看到三个模块。
    • 个人信息模块:可以看到登录的用户名,头像,以及已发布的文章数和文章分类
    • 博客列表模块:可以看到博客标题、博客发布时间、博客内容,还可以通过“查看全文”按钮查看详细的博客无安稳
    • 菜单栏:有三个按钮,分别是编写博客,点击编写博客可以跳转到博客编辑页面;点击主页可以回到博客列表;点击注销跳转到登录页面,重新登录
  • 未登录状态下:强制用户登录,直接跳转到登录页面

3. 博客详情页

博客详情页:

  • 登录状态下:在博客列表点击“查看全文”或直接输入链接就可以进入博客详情页。在博客详情页,可以看到博客标题、发布时间、博客内容,并且在文章内容后面有两个按钮。一个“编辑”按钮点击可以修改博客,一个“删除按钮”,点击会出现一个删除确认框,确认则删除博客回到博客列表页,取消则不删除不跳转。
  • 未登录状态下:强制用户登录,直接跳转到登录页面

4. 博客编辑页

博客编辑页:

  • 登录状态下:在任意界面点击“写博客”进入博客编辑页,此时可以编写博客标题,博客内容。如果要发布文章,必须标题和内容均不为空,最后点击发布文章即可发布成功。
  • 未登录状态下:在登录页面点击“写博客”按钮也可以进入博客编辑页,但是不能编写博客、发布博客。未登录做编写/发布博客操作,跳转到登录页面,强制登录。

三、测试计划

测试计划:

  • 设计自动化测试用例
    • 工具:脑图/思维导图
  • 参考测试用例,创建自动化测试项目,编写自动化测试脚本
    • 工具:PyCharm、selenium库

1. 编写web测试用例

在这里插入图片描述

2. 编写自动化脚本

参考测试用例,创建自动化测试项目,编写自动化测试脚本

  • 一个页面一个测试类
    • BlogLogin.py:博客登录页面相关测试用例
    • BlogList.py:博客列表页面相关测试用例
    • BlogDetail.py:博客详情页面相关测试用例
    • BlogEdit.py:博客编辑页面相关测试用例
  • 将生成测试文件中需要用到的配置内容放在一个Utils.py工具类

2.1 工具类Utils.py

  1. 创建驱动:每一个页面都会创建浏览器对象,请求url访问对应的页面,进入到对应页面之后,才可以执行一系列的测试用例
  2. 截图保存:方便问题溯源
    a. 图片路径:…/images/调用方法-2025-10-15-156777.png
    b. 先建立一个images目录存放所有截图
    c. 根据每天的日期进行分类,当天运行的自动化图片文件放到当天的文件夹下
    d. 拼接调用的方法名,快速定位到是哪一个用例的截图
import datetime
import os
import sys

from selenium import webdriver
from selenium.webdriver.chrome.service import Service


# 创建一个浏览器对象
class Driver:
    driver = ""
    def __init__(self):
        driver_path = "D:\\ChromeDriver\\chromedriver.exe"
        service = Service(executable_path=driver_path)
        # 浏览器参数设置
        options = webdriver.ChromeOptions()
        self.driver = webdriver.Chrome(service=service, options=options)
        #隐式等待
        self.driver.implicitly_wait(3)
    # 创建屏幕截图
    def getScreeShot(self):
        # 图片路径:../images/调用方法-2025-10-15-156777.png
        dirname = datetime.datetime.now().strftime("%Y-%m-%d")
        # 判断dirname文件夹是否已经存在,若不存在则创建文件夹
        if not os.path.exists("../images/"+dirname):
            os.mkdir("../images/"+dirname)
        # sys._getframe().f_back.f_code.co_name获取调用的方法名
        # 截图名称
        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)
# 全局Driver实例
BlogDriver = Driver()

2.2 登录页面测试类BlogLogin.py

  1. 调用工具类创建驱动,并打开页面
  2. 创建成功登录的测试用例脚本
  3. 创建异常登录的测试用例脚本
# 测试博客登录页面
from selenium.webdriver.common.by import By
import time

from selenium.webdriver.support.expected_conditions import alert_is_present
from selenium.webdriver.support.wait import WebDriverWait

from commin.Utils import BlogDriver


class BlogLogin:
    url = ""
    driver = ""
    def __init__(self):
        self.url ="http://8.137.19.140:9090/blog_login.html"
        # BlogDriver.driver.get(self.url)
        self.driver = BlogDriver.driver
        self.driver.get(self.url)
    # 成功登录的测试用例
    def LoginSucTest(self):
        # 建议在输入之前都清空
        self.driver.find_element(By.CSS_SELECTOR, "#username").clear()
        self.driver.find_element(By.CSS_SELECTOR, "#password").clear()
        # 输入正确的用户名
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhangsan")
        # 输入正确的密码
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
        # 点击提交
        self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
        # 检测是否成功
        # 登录成功,跳转到博客首页,并能在博客首页找到个人信息模块的“账号”, 否则登录失败
        # time.sleep(2)
        self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3")
        # 添加屏幕截图
        BlogDriver.getScreeShot()
        #self.driver.quit()
        # 返回登录页面
        # time.sleep(2)
        self.driver.back()
    # 异常登录的测试用例
    def LoginFailTest(self):
        # 若连续多次的send_keys则会出现将关键词连接的情况,而不是替换。若要替换需要先clear
        # 建议在输入之前都清空
        self.driver.find_element(By.CSS_SELECTOR, "#username").clear()
        self.driver.find_element(By.CSS_SELECTOR, "#password").clear()
        # 输入正确的用户名
        self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhangsan")
        # 输入错误的密码
        self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123")
        # 点击提交
        self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
        # 避免截图失败
        time.sleep(3)
        # 检查是否登录失败
        alert = self.driver.switch_to.alert
        # 打印弹窗内容(调试用)
        print("弹窗内容:", alert.text)
        #确认
        alert.accept()
        # 添加屏幕截图
        # 调用 getScreeShot()时,可能会遇到弹窗(Alert)导致截图失败
        BlogDriver.getScreeShot()
        # self.driver.quit()



# 测试
# login = BlogLogin()
# login.LoginSucTest()
# login.LoginFailTest()

2.3 博客列表页面类BlogList.py

  1. 调用工具类创建驱动,并打开页面
  2. 创建登录状态下的博客列表的测试脚本
  3. 创建未登录状态下的博客列表的测试脚本
# 测试博客列表页面
from selenium.webdriver.common.by import By

from commin.Utils import BlogDriver


class BlogList:
    url = ""
    driver = ""
    def __init__(self):
        self.url = "http://8.137.19.140:9090/blog_list.html"
        self.driver = BlogDriver.driver
        self.driver.get(self.url)

    # 测试登录状态下
    def ListTestByLogin(self):
        import time
        time.sleep(1)
        # 测试博客列表模块的博客标题是否存在
        self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > div.title")
        # 测试博客列表模块的博客内容是否存在
        self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > div.desc")

        # 测试博客列表模块的“查看全文”按钮是否存在
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > a")

        # 测试个人信息模块的账号是否存在
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3")

        #添加屏幕截图
        BlogDriver.getScreeShot()

        # 点击菜单栏模块的“写博客”,是否跳转到编写页面
        self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(5)").click()
        # 获取当前页面URL current_url
        url = self.driver.current_url
        print(url)
        assert url == "http://8.137.19.140:9090/blog_edit.html"
        # 添加屏幕截图
        BlogDriver.getScreeShot()
    # 未登录状态下,强制登录
    def ListTestByNotLogin(self):
        # 获取当前页面URL current_url
        url = self.driver.current_url
        print(url)
        assert url == "http://8.137.19.140:9090/blog_login.html"
        # 添加屏幕截图
        BlogDriver.getScreeShot()
        # 指定浏览器的退出
        BlogDriver.driver.quit()

# 测试
list = BlogList()
# list.ListTestByLogin()
list.ListTestByNotLogin()

2.4 博客编辑页类BlogEdit.py

  1. 调用工具类创建驱动,并打开页面
  2. 创建博客是否可以正确发布的测试脚本
# 测试博客编辑页面
from selenium.webdriver.common.by import By
import time

from commin.Utils import BlogDriver


class BlogEdit:
    url = ""
    driver = ""
    def __init__(self):
        self.url = "http://8.137.19.140:9090/blog_edit.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,"#editor > div.editormd-toolbar > div > ul > li:nth-child(7)").send_keys("自动化自动化自动化")
        time.sleep(2)
        # 点击发布按钮来发布博客
        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(5) > div.title").text
        assert actual == "自动化测试创建"
        # 屏幕截图
        BlogDriver.getScreeShot()
        time.sleep(2)
    

2.5 博客详情页类BlogDetail.py

  1. 调用工具类创建驱动,并打开页面
  2. 创建测试编辑页是否正确打开的测试脚本
  3. 测试“删除”按钮是否可以正常使用
  4. 测试“编辑”按钮是否可以正常跳转
# 测试博客详情页
from selenium.webdriver.common.by import By

from commin.Utils import BlogDriver


class BlogDetail:
    url = ""
    driver = ""
    def __init__(self):
        self.url = "http://8.137.19.140:9090/blog_detail.html?blogId=158477"
        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.getScreeShot()


    # 丰登录状态下

2.6 测试套件类RunTest.py

# 程序执行入口
from commin.Utils import BlogDriver
from tests import BlogList
from tests import BlogLogin
from tests import BlogDetail
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. 注意测试用例的执行顺序
  2. 驱动关闭的位置要注意,一般放在最后一个用例测试结束才关闭
  3. 屏幕截图的保存方式:按照一天一个目录存放截图,并且截图名字拼接调用的方法名,方便快速定位问题
  4. 在创建对象之后使用隐式等待,避免出现代码执行的速度比页面渲染的速度快,导致元素找不到
  5. 只创建一次驱动对象,避免每个用例重复创建驱动造成时间和资源的浪费
  6. 在重要的测试后面添加屏幕截图
  7. 若连续多次的send_keys则会出现将关键词连接的情况,而不是替换。若要替换需要先clear。建议在输入之前都清空
  8. 调用屏幕截图,可能会遇到弹窗(Alert)导致截图失败,可在前面加强制等待
  9. 使用思维导图,覆盖大多数功能测试
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值