目录
一、概述
一)项目背景
本项目旨在设计并实现一个轻量级的博客系统,采用前后端分离的架构,结合数据库进行数据存储,并部署在云服务器上。博客系统在当今互联网环境中具有广泛的应用场景,它不仅为用户提供了一个友好的学习和交流平台,还可以作为个人知识管理和分享的工具。博客系统为用户提供了一个便捷的平台,用于发布和分享知识笔记、技术文章和个人见解,促进知识的传播与交流。
通过博客系统,用户可以系统地整理和存储自己的学习笔记、项目经验和技术总结,形成个人知识库,便于日后查阅和回顾。通过博客系统,用户可以将零散的知识点系统化地整理和存储,避免信息碎片化带来的知识流失。该博客系统能满足个人用户基本的博客记录需求,用户可以查看每篇博客的发布时间、标题、内容及发布者等详细信息。通过本项目,用户能够体验到一个简洁而实用的博客系统。
二)项目功能简介
登录功能: 该系统没有实现账户注册功能。用户名及密码已经存储在后端数据库中,登录成功即可跳转到博客首页。登录页面首页右上角有2个可以点击的按键,在未登录情况下无论什么操作均只会跳转到博客登录界面。
博客首页: 登录成功后进入博客首页,在博客首页可以查看到用户头像,以及GitHub地址。同时会显示博客的名称、发布日期及发布的内容。可以点击“查看全文“按钮进入博客详情页面查看全文。同时该页面右上角有3个按键,点击“主页”按键依旧跳转到博客首页,点击”写博客“按键会跳转到博客编辑页,点击”注销“按键会跳转到博客登录界面。
博客详情页: 在博客首页点击”查看全文“按钮会跳转到博客详情页,在博客详情页可以看到用户头像、GitHub地址。会显示博客标题,博客发布时间以及博客详情内容,在这些内容下面还有2个按键,编辑按键以及删除按键。点击”编辑“按键会跳转到博客编辑页,博客内容编辑结束点击更新文章,在博客详情页会找到我们刚刚更新的博客(不会改变该博客发布的时间)。点击“删除按键”会弹出“确定删除?”弹窗,点击“确定”会跳转到博客详情页,同时删除博客。
博客编辑页: 无论从以上哪个页面都可以进入到博客编辑页,只需点击右上角的”写博客“按钮,即可跳转。在博客编辑页面可以写入博客标题和内容,内容可以使用页面提供的一些功能来展示出不同的样式,输入标题和内容后点击发布文章,跳转页面到博客详情页,博客列表是按照发布博客的时间顺序依次向下排列,向下拉动即可找到发布的博客。但是在登录页面未登录的情况下写博客发布博客不会发布成功。
二、测试策略
一)测试目标
本项目的测试目标旨在全面验证博客系统的四大主要功能界面(登录页、博客首页、博客详情页和博客编辑页)的完善性和稳定性。基于理想化的博客系统功能,通过系统化的测试流程,发现并记录系统中存在的问题,确保系统在实际应用中的可靠性和用户体验。因本项目是Web项目,所以主要测试点聚焦在该项目的界面测试上。具体测试目标包括以下几个方面:
- 功能测试:
验证用户登录、注销、博客编辑、删除博客等核心功能的正确性和完整性。检查博客系统的强制登录功能是否能够有效限制未登录用户的访问。确保博客系统的各个页面(登录页、博客首页、博客详情页、博客编辑页)能够正常显示和交互。 - 界面测试:
验证界面元素是否符合功能预期,确保只有经过身份验证的用户才能进行敏感操作,如编辑和删除博客。 - 兼容性测试:
验证博客系统在不同浏览器(如Chrome、Firefox、Safari等)和不同设备(如PC、平板、手机)上的兼容性,确保用户在不同环境下都能正常使用系统。 - 用户体验测试:
评估系统的用户界面(UI)和用户体验(UX),确保界面设计简洁、易用,符合用户预期。检查系统的交互逻辑是否合理,确保用户能够顺畅地完成各项操作。 - 性能测试:
使用性能测试工具JMeter进行性能测试。 - 自动化测试:
使用python+selenium工具,依旧编写的自动化测试用例,编写自动化测试脚本执行自动化测试。
二)测试用例设计
1)功能测试用例
2)自动化测试用例
三)测试类型
1)功能测试
登录界面功能测试:
-
正常登录:输入正确账号以及正确密码,登录成功会立即跳转到博客首页。
测试结果如下:
-
异常登录:登录失败
a)输入正确的用户名和错误的密码,页面跳出弹窗显示密码错误。
b)输入错误的用户名和正确的密码,页面跳出弹窗显示用户不存在。
c)输入错误的用户名和错误的密码,页面跳出弹窗显示用户不存在。
-
测试2中3个测试用例,当出现弹窗时,无法点击页面元素,当弹窗关闭后才能点击页面元素。
博客首页界面功能测试:
- 登录状态下:
a)个人信息显示:头像、昵称、GitHub、文章、分类
b)博客列表:博客标题、博客内容、博客发布时间、查看全文按键
- 未登录状态下:
未登录状态下会跳转到博客登录首页进行登录。
博客详情页面测试:
- 登录状态下:
a)个人信息显示:头像、昵称、GitHub、文章、分类
b)博客列表:博客标题、博客内容、博客发布时间、编辑按键、删除按键
- 未登录状态下:
未登录状态下会跳转到博客登录首页进行登录。
博客编辑页面测试:
- 登录状态下:正常发布博客
输入标题和内容,点击发布文章按键即可成功发布博客,在博客详情页面可以找到刚刚发布的博客。
- 登录状态下:异常发布博客
a)没有博客标题有博客内容点击发布博客
b)有标题没有博客内容点击发布博客
c)同时有博客标题也有博客内容但是没有点击发布键
- 页面元素检查
a)对博客标题输入框进行检查:测试输入框是否能够输入文本
b)对博客内容输入框进行检查:对输入框内的各种元素进行检查
c)对博客发布按键进行检查:成功发布博客
2)性能测试
在梯度压测线程组中启动20个线程,设置每3s增加5个线程,20个线程运行结束后,每1s关闭5个线程。
-
吞吐量
-
响应时间随时间变化
-
随时间变化的活跃线程
性能测试报告:
性能测试分析:
通过分析Response time,可以发现一个很明显的问题,博客列表页面的响应时间明显比其他页面的响应时间高出很多倍,分析主要由以下几点原因引起:
1)系统不稳定,经过很多次测试发现,博客列表页面的响应时间并不在一个稳定的范围内波动,有时候查找的很快,有时候很慢。随着并发线程增多,系统压力变大,导致响应时间增大。
2)由于博客列表页面的博客较多,同时我们也没有进行分页功能,导致每次进行测试要遍历全部的博客,随着博客的增加,响应时间也会增大。
3)兼容性测试
- 项目在Chrome浏览器下正常打开
- 项目在Edg浏览器下正常打开
- 项目在Safari浏览器下正常打开
- 项目在平板端正常打开
- 项目在手机端正常打开
4)自动化测试
概述:个人博客自动化测试主要针对登录页、博客首页、博客详情页、博客编辑页进行测试,依据二)2)设计的自动化测试用例编写自动化测试脚本执行。
- 代码架构
common软件包内部存放公共属性(创建驱动、保存方法调用时的现场截图),方便代码复用。
images文件夹存放屏幕截图
Tests软件包存放4个界面的自动化测试脚本
RunTest.py调用Tests内4个界面自动化测试脚本的函数执行自动化测试
- Utils.py
import datetime
import os
import sys
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
class Driver:
driver = ""
#类的构造对象
def __init__(self):
options= webdriver.ChromeOptions()
self.driver = webdriver.Chrome(service = Service(ChromeDriverManager().install()),options = options)
#添加隐式等待——隐式等待的作用域在driver的整个生命周期
self.driver.implicitly_wait(3)
def getScreenShot(self):
#创建屏幕截图
#图片文件名称:./2025-03-15-124578.png
#图片路径:../images/调用方法-2025-03-15/2025-03-15-124578.png
#sys._getframe().f_back.f_code.co_name该方法用来获取调用的方法名
#先生成当天屏幕截图的文件夹
dirname = datetime.datetime.now().strftime("%Y-%m-%d")
#判断dirname文件夹是否已经存在,若不存在则创建文件夹
if not os.path.exists("../images/"+dirname): #../images/2025-03-15/
os.mkdir("../images/"+dirname) #不存在则创建
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()
- RunTest.py
from Tests import blog_login_test, blog_edit_test
from Tests import blog_list_test
from Tests import blog_detail_test
from common.Utils import BlogDriver
if __name__ == '__main__':
#创建类对象
blog_login_test.BlogLogin().LoginFailTest()
blog_login_test.BlogLogin().LoginSucTest()
#登录成功后就可以调用博客首页测试首页的用例(登录状态)
blog_list_test.BlogList().ListTestByLogin()
blog_detail_test.BlogDetail().DetailTestByLogin()
blog_edit_test.BlogEdit().EditSucTestByLogin()
#执行浏览器退出
BlogDriver.driver.quit()
- blog_login_test.py
import time
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver
class BlogLogin:
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 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(1)
self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > img")
# 添加屏幕截图,方便观察结果 self是Blog类里面的成员
BlogDriver.getScreenShot()
self.driver.back()
#异常登录测试用例
def LoginFailTest(self):
#连续多次send_keys会出现关键词拼接而不是替换
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("12345")
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
#检查是否登录失败,切换弹窗
time.sleep(1)
alert = self.driver.switch_to.alert
time.sleep(1)
string = alert.text
# 断言弹窗内容是否符合预期
assert string == "密码错误"
alert.accept()
# 添加屏幕截图,方便观察结果
BlogDriver.getScreenShot()
login = BlogLogin()
- blog_edit_test.py
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_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,"#submit").click()
time.sleep(5)
actual = self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(16) > div.title").text
assert actual == "自动化测试创建"
#屏幕截图
BlogDriver.getScreenShot()
time.sleep(1)
- blog_list_test.py
import time
from selenium.webdriver.common.by import By
from common.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):
#测试博客标题是否存在
time.sleep(1)
self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > div.title")
time.sleep(1)
#博客时间是否存在
self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > div.date")
time.sleep(1)
#博客内容是否存在
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > div.desc")
time.sleep(1)
#博客按键查看全文是否存在
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > a")
time.sleep(1)
#博客个人信息是否存在
self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3")
time.sleep(1)
#添加屏幕截图
BlogDriver.getScreenShot()
List = BlogList()
- blog_detail_test.py
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=25532"
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_elements(By.CSS_SELECTOR, "body > div.container > div.right > div > div.date")
#检查内容
self.driver.find_elements(By.CSS_SELECTOR,"#detail > p")
#屏幕截图
BlogDriver.getScreenShot()
1.注意RunTest.py内部方法调用的执行顺序。
2.注意send_keys()输入文本前面要调用clear方法清空输入框。
3.注意驱动关闭的位置,4大页面内部不需要调用driver.quit()避免测试执行中断。
4.注意屏幕截图保存格式,方便测试出错时快速定位问题,以便于问题的解决。
5.可以使用无头模式创建驱动
6.自动化测试的过程中可能由于代码执行速度比页面渲染的速度快导致测试出现问 题,可以使用隐式等待作用于整个driver执行的生命周期。
7.注意selenium的截图功能,在使用截图功能之前一定要将弹窗处理之后再进行。
四)测试工具
自动化测试工具: Python+PyCharm+selenium
测试用例管理工具: Xmind
性能测试工具: JMeter
其他工具: Postman、Git
三、测试难点及总结
难点:
- 博客系统涉及的功能模块较多,每个模块之间又存在复杂的交互关系,测试用例的设计和执行需要覆盖各种场景,工作量较大。
- 部分功能测试依赖于特定的数据状态,测试数据准备和清理工作较为繁琐。
- 博客系统需要承受一定的用户访问量,性能测试需要模拟高并发场景,识别系统瓶颈并进行优化,这对测试工具和测试环境提出了较高的要求。
总结:
尽管面临一些挑战,通过合理的测试策略和工具选择,最终完成了博客系统的测试工作,保证了系统功能完整性,通过全面的测试,验证了博客系统各项功能的正确性和稳定性,确保了系统能够满足用户的基本需求。