博客系统测试报告

目录

1、项目背景

2、项目简介

编写测试用例

执行测试用例

手工执行测试用例

1、登录测试

异常登录测试:

正常登录

博客首页

博客编辑页

博客编辑页各个功能是否正确可以显示且功能是否正常

异常编写博客提交失败

正常编写博客发布文章

博客详情页

查看当前用户发布的博客

查看非当前用户发布的博客

BUG简述

自动化执行测试用例

自动化测试简介

使用Selenium进行自动化测试

环境配置

编写自动化测试脚本

登录功能自动化测试

博客首页自动化测试

博客查看全文、编辑页、更新文章自动化测试

发布博客自动化测试

在runtest.py文件整体运行

selenium+驱动+浏览器的⼯作原理


1、项目背景

此次开发的博客系统是一个轻量级的内容管理平台,主要是在为用户提供便捷的文章发布、分享知识和记录生活等功能

2、项目简介

系统包含五个核心页面:用户登录页博客发布页博客编辑页博客列表页博客详情页

用户登录页 :用户输入用户名和密码进行登录。错误处理:输入错误密码时提示「用户名或密码错误」,连续5次失败后锁定账号10分钟。

**博客发布页:**用户可输入博客标题、正文内容、添加标签(如#技术、#生活)或选择已有分类。点击「发布」按钮提交至后台,成功后跳转到博客详情页。

博客编辑页: 加载已有博客内容(标题、正文、标签等)供用户修改。点击「更新」按钮后覆盖原内容。**权限控制:**仅博客作者和管理员可编辑,其他用户访问时返回403错误。

**博客列表页:**分页展示所有公开博客(默认按发布时间倒序)。点击博客标题或「阅读更多」跳转至详情页。

**博客详情页:**展示博客完整内容(标题、作者、发布时间、正文、标签)。

编写测试用例

设计测试用例一般需要包含:界面测试,功能测试,性能测试,兼容性测试,安全性测试,易用性测试等

执行测试用例

手工执行测试用例

1、登录测试

异常登录测试:

1、输入正确的用户名和错误的密码(用户名:lisi,密码:123)

预期结果:页面弹出错误提示:密码错误

实际结果:页面弹出错误提示:密码错误。测试通过

2、输入错误的用户名和正确的密码(用户名:zs,密码:123456)

预期结果:页面弹出错误提示:用户不存在

实际结果:页面弹出错误提示:用户不存在。测试通过

正常登录

1、输入正确的用户名和密码(用户名:lisi,密码:123456)

预期结果:成功登录则跳转到博客首页

实际结果:成功登录则跳转到列表页,测试通过

博客首页

成功登录后跳转到博客首页,见上图

预期结果:

博客首页可以看到当前用户博客文章、分类的数量。当前用户的头像、用户名、查看已发布博客的有限博客信息(包括标题、日期、内容)、查看全文按钮等。

实际结果:

文章数量和分类显示数量错误。测试不通过

博客编辑页

在页面右上角点击"写博客",即可进入博客编辑页面,用户可以进行写文章操作。

博客编辑页各个功能是否正确可以显示且功能是否正常

预期结果:页面正常显示,有输入标题和内容的文本框,有工具栏,有发布文章按钮

实际结果:页面正常显示,有输入标题和内容的文本框,有工具栏,有发布文章按钮。测试通过

异常编写博客提交失败

1、不写标题点击发布文章

预期结果:出现提示弹窗点击确定返回博客编辑页

实际结果:出现提示弹窗点击确定返回博客编辑页。测试通过

2、不写内容点击发布文章

预期结果:出现提示弹窗点击确定返回博客编辑页

实际结果:出现提示弹窗点击确定返回博客编辑页。测试通过

正常编写博客发布文章

1、写上合法标题和合法的内容,点击发布文章

预期结果:成功发布,并且跳转到博客首页

实际结果:成功发布,并且跳转到博客首页。测试通过

博客详情页

选择任意一篇博客,点击"查看全文"按钮,即可进入博客详情页,此时可以看到该篇博客的所有内容。如果所查看的文章所是当前用户发布的,即可进行"编辑"和"删除"操作,如果所查看的文章是其他用户所发布的,则对文章的权限是"只读"。

查看当前用户发布的博客

预期结果:可以看到博客所有内容,还可进行"编辑"和"删除"操作

实际结果:可以看到博客所有内容,还可进行"编辑"和"删除"操作。测试通过

查看非当前用户发布的博客

预期结果:可以看到博客的所有内容,但没有编辑和删除按钮

实际结果:可以看到博客的所有内容,但没有编辑和删除按钮。测试通过

BUG简述

本次项目手工测试阶段发现了bug,0个崩溃级别的bug,0个严重级别的bug,1个一般级别的bug

|-------------|-----|------|
| bug标题 | 报告人 | 是否修复 |
| 文章和分类数量显示异常 | 何浩华 | 修改完成 |
[bug表单]

自动化执行测试用例

自动化测试简介

自动化测试是指利用脚本和工具(如 Selenium、Cypress、Postman、JMeter)自动执行测试用例,减少人工干预,提高测试速度和可重复性。

  • 相比手工测试,自动化测试可以在几分钟内完成数百个用例的执行(如批量测试不同浏览器的兼容性)。

    高覆盖率

  • 可覆盖复杂场景(如并发用户测试、大数据量查询),手工测试难以模拟。

    可重复性

  • 相同的测试脚本可以反复运行,确保每次代码变更后的一致性。

    持续集成(CI/CD)支持

  • 结合 Jenkins/GitHub Actions ,可在代码提交后自动触发测试,快速发现BUG。

    减少人为错误

  • 避免手工测试中的遗漏或误操作(如忘记测试某个边界条件)。

使用Selenium进行自动化测试

本次测试环境

Selenium:4.0.0

python:3.10.11

PyCharm Community Edition 2024.3.5

环境配置

安装驱动管理(建议使用国内pypi镜像源下载,速度更快,因为官方源在国外)

作者用的是清华大学的pip镜像源

在windows powershell命令工具中输入

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ webdriver-manager

安装selenium库,selenium版本很多,作者用的是4.0.0版本

在windows powershell命令工具中输入

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ selenium==4.0.0

下载完成后打开PyCharm Community Edition 软件,点击菜单左上角文件-设置-项目-python解释器

检查python解释器,确定selenium库和WebDriverManager库都安装成功并加载到当前项⽬中

看到作者有标红的就说明环境配置完成,就可以写对应的自动化脚本了

下面可以简单写一个脚本看看是否能够脚本正常运行

python 复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager

#驱动程序管理的⾃动化
#创建驱动对象
#1.打开浏览器
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
#2.输⼊百度⽹址:https://www.baidu.com
driver.get("https://www.baidu.com")
#3、找到输⼊框并输⼊"章若楠"
driver.find_element(By.CSS_SELECTOR,"#kw").send_keys("章若楠")
#4、找到"百度⼀下"按钮并点击
driver.find_element(By.CSS_SELECTOR,"#su").click()
#退出浏览器
#driver.quit()

编写自动化测试脚本

避免重复创建和销毁浏览器实例的开销。防止多个浏览器窗口同时存在导致资源浪费或操作冲突。在 Web 自动化测试中,通常只需要一个浏览器实例贯穿整个测试流程。

新建项目,项目中创建了一个名为common的包,在其中放置了utils模块。在utils文件夹里,定义一个Driver类,该类包含一个构造方法,用于初始化浏览器实例以便后续复用;同时还封装了一个截图功能的方法,以便在自动化测试过程中轻松捕获页面截图,便于排查问题。

python 复制代码
# 导入必要的模块
import datetime  # 用于处理日期和时间
import os       # 用于操作系统相关功能(如文件路径操作)
import sys      # 用于访问Python解释器相关的功能
from os import mkdir  # 专门导入mkdir函数用于创建目录

from requests import options  # 导入requests库的options(虽然代码中未使用)
from selenium import webdriver  # 导入Selenium的WebDriver
from selenium.webdriver.edge.service import Service  # Edge浏览器的服务类
from webdriver_manager.microsoft import EdgeChromiumDriverManager  # Edge驱动管理


class Driver:
    # 类变量,用于存储WebDriver实例
    driver = ""

    def __init__(self):
        # 初始化Edge浏览器选项
        options = webdriver.EdgeOptions()
        # 添加允许远程源的参数(用于解决某些跨域问题)
        options.add_argument("--remote-allow-origins=*")
        # 创建Edge浏览器实例
        # 使用EdgeChromiumDriverManager自动管理驱动版本
        # 传入配置好的options
        self.driver = webdriver.Edge(service=Service(EdgeChromiumDriverManager().install()), options=options)

    def GetScreenshot(self):
        # 获取当前日期,格式为"年-月-日"(如"25-04-25")
        dirname = datetime.datetime.now().strftime("%y-%m-%d")
        
        # 检查图片存储目录是否存在
        # 完整路径为"../images/年-月-日"
        if not os.path.exists("../images/" + dirname):
            # 如果不存在则创建目录
            os.mkdir("../images/" + dirname)
        
        # 生成文件名:
        # 1. 获取调用此方法的方法名(通过调用栈回溯)
        # 2. 加上当前时间的"年-月-日-时分秒"格式
        filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime("%y-%m-%d-%H%M%S")
        
        # 保存截图到指定路径
        # 格式:"../images/年-月-日/调用方法名-年-月-日-时分秒.png"
        self.driver.save_screenshot("../images/" + dirname + "/" + filename + ".png")


# 创建Driver类的实例
Blogdriver = Driver()
登录功能自动化测试
python 复制代码
import time

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

from common.Utils import Blogdriver


class BlogLogin:
    driver = ""
    url = ""
    def __init__(self):
        self.url = "http://8.137.19.140:9090/blog_login.html"
        self.driver = Blogdriver.driver
        self.driver.get(self.url)

    def SucLoginTest(self):
        self.driver.find_element(By.CSS_SELECTOR,"#username").clear()
        self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")

        self.driver.find_element(By.CSS_SELECTOR,"#password").clear()
        self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
        time.sleep(2)
        Blogdriver.GetScreenshot()

    def FailLoginTest1(self):
        #send_keys如果不清楚,就会把输入的内容拼接起来
        #使用clear清楚
        self.driver.find_element(By.CSS_SELECTOR,"#username").clear()
        self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")

        self.driver.find_element(By.CSS_SELECTOR,"#password").clear()
        self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123")
        self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
        #等待弹窗加载出来,不然程序执行的速度太快可能没有找到弹窗
        #添加显示等待
        wait = WebDriverWait(self.driver,3)
        #EC.alert_is_present()检查是否出现弹窗,如果出现那么就返回这个弹窗,否则抛异常
        alert = wait.until(EC.alert_is_present())

        alertTest = alert.text
        #确认是否登录失败
        #注意:先断言在确认弹窗
        assert alertTest == "密码错误"
        #确认弹窗
        alert.accept()
        Blogdriver.GetScreenshot()

    def FailLoginTest2(self):
        #send_keys如果不清楚,就会把输入的内容拼接起来
        #使用clear清楚
        self.driver.find_element(By.CSS_SELECTOR,"#username").clear()
        self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsa")

        self.driver.find_element(By.CSS_SELECTOR,"#password").clear()
        self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")
        self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
        #等待弹窗加载出来,不然程序执行的速度太快可能没有找到弹窗
        #添加显示等待
        wait = WebDriverWait(self.driver,3)
        #EC.alert_is_present()检查是否出现弹窗,如果出现那么就返回这个弹窗,否则抛异常
        alert = wait.until(EC.alert_is_present())

        alertTest = alert.text
        #确认是否登录失败
        #注意:先断言在确认弹窗
        assert alertTest == "用户不存在"
        #确认弹窗
        alert.accept()
        #获取截图
        Blogdriver.GetScreenshot()


# Login = BlogLogin()
# Login.FailLoginTest1()
# Login.FailLoginTest2()
# Login.SucLoginTest()
博客首页自动化测试
python 复制代码
import time
from telnetlib import EC

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

from common.Utils import Blogdriver
from test.BlogLogin import BlogLogin


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

    def CheckSecLoginMain(self):

        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > img")
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > a")
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3")
        self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(4)")
        self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(5)")
        self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(6)")
        # WebDriverWait(self.driver, 20).until(
        #     EC.presence_of_element_located((By.ID, "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.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.right > div:nth-child(1) > div.date")
        self.driver.quit()

# BlogMain = Main()
# BlogLogin().SucLoginTest()
# BlogMain.CheckSecLoginMain()
博客查看全文、编辑页、更新文章自动化测试
复制代码
import time

from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from common.Utils import Blogdriver
from test.BlogLogin import BlogLogin
from test.BlogMain import BlogMain



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

        wait = WebDriverWait(self.driver, 20)
        # invisibility_of_element 是等待元素不可见:等待 弹窗或提示框 自动关闭。等待 临时元素(如进度条、Toast 提示)消失后再继续操作。
        # visibility_of_element_located等待元素可见:确保元素 可以被点击或交互(如按钮、输入框)。
        #添加显示等待
        wait.until(EC.visibility_of_element_located((By.XPATH, '/html/body/div[2]/div[2]/div/div[4]/button[1]')))
        #进入编辑页
        self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div > div.operating > button:nth-child(1)").click()
        # time.sleep(4)
        wait = WebDriverWait(self.driver,10)
        wait.until(EC.visibility_of_element_located((By.XPATH,'//*[@id="editor"]/div[1]/div[6]')))
        #输入内容
        self.driver.find_element(By.CSS_SELECTOR,"#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll").send_keys("自动化测试更新文章")
        #点击更新文章
        self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
        time.sleep(3)


        # self.driver.quit()
# Detail = BlogDetail()
# Main = BlogMain()
# Login = BlogLogin()
# Login.SucLoginTest()
# Main.CheckSecLoginMain()
# Detail.DetailReadText()
发布博客自动化测试
复制代码
import time

from selenium.webdriver.common.by import By

from common.Utils import Blogdriver
from test.BlogDetail import BlogDetail
from test.BlogLogin import BlogLogin
from test.BlogMain import BlogMain


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

    def Publish(self):
        self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(5)").click()
        time.sleep(10)
        self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys("自动化测试")

        #self.driver.find_element(By.CSS_SELECTOR,"#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div > div > div.CodeMirror-code > div > pre > span > span").send_keys("完成自动化")
        self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
在runtest.py文件整体运行
python 复制代码
from test.BlogDetail import BlogDetail
from test.BlogLogin import BlogLogin
from test.BlogMain import BlogMain
from test.BlogPublish import BlogPulish

if __name__ == "__main__":
    BlogLogin().FailLoginTest1()
    BlogLogin().FailLoginTest2()
    BlogLogin().SucLoginTest()
    BlogMain().CheckSecLoginMain()
    BlogDetail().DetailReadText()
    BlogPulish().Publish()

selenium+驱动+浏览器的⼯作原理

实现web⾃动化测试需要浏览器、浏览器驱动、selenium⾃动化脚本。这三者是如何交互最终实现 web的⾃动化测试?

  1. 通过selenium编写的⾃动化脚本代码中在ChromeDriverService中创建⼀个服务

  2. 通过创建好的服务打开webdriver,安装在本地的驱动服务IP为localhost,PORT为 ChromeDriverService中创建的端⼝号,该服务地址为selenium向webdriver发送请求的服务地 址。

  3. 向浏览器驱动程序发送HTTP请求,浏览器驱动程序解析请求,打开浏览器,并获得sessionid,如 果再次对浏览器操作需携带此id

  4. 打开浏览器后,所有的selenium的操作(访问地址,查找元素等)均通过创建好的服务链接到 webdriver,然后使⽤execute发送请求

  5. 驱动收到请求并对请求进⾏解析,转成浏览器能够解析的脚本并发送给浏览器,浏览器通过请求的 内容执⾏对应动作

6.浏览器再把执⾏的动作结果通过浏览器驱动程序返回给测试脚本

简单的流程图

+-----------------------+

| 自动化测试脚本 |

| (Selenium Client) |

+-----------+-----------+

| (1) 创建ChromeDriverService

| (localhost:PORT)

v

+-----------------------+

| ChromeDriverService |

| (HTTP Server) |

+-----------+-----------+

| (2) WebDriver API请求

| (携带Session ID)

v

+-----------------------+

| 浏览器驱动程序 |

| (ChromeDriver) |

+-----------+-----------+

| (3) 转成浏览器可执行脚本

| (如DevTools Protocol)

v

+-----------------------+

| 浏览器 |

| (Chrome/Firefox等) |

+-----------+-----------+

| (4) 执行动作并返回结果

v

+-----------------------+

| 返回结果给测试脚本 |

+-----------------------+

相关推荐
王磊鑫5 小时前
软件测试全攻略:Postman工具的使用
测试工具·postman
江梦寻10 小时前
最新Chrome与Selenium完美兼容指南(含驱动下载与配置)
前端·chrome·selenium·测试工具·edge·edge浏览器
奔跑吧邓邓子1 天前
探索Selenium:自动化测试的神奇钥匙
自动化测试·selenium·测试工具
测试界清流1 天前
Selenium4+Pytest自动化测试框架
selenium·测试工具·pytest
not coder1 天前
Selenium 查找页面元素的方式
selenium·测试工具
CIb0la2 天前
Ai自动补全编程工具:llama vscode
运维·开发语言·学习·测试工具·程序人生