简墨博客系统测试报告
一、项目背景
在日常学习中,难免会产生对学习内容的记录,从而有了一篇篇学习笔记,而众多的笔记难免会出现管理困难的问题。因此,为了更好的管理自己编辑的文章,从而开发出这个系统——简墨。
简墨是一个基于SSM
框架的基础上实现的博客系统,它共由四个页面构成:用户登录页,博客首页,博客详情页,博客编辑页。
为了验证简墨博客系统的功能是否正常,现在对其进行手动和自动化测试。项目的具体测试内容为:登录、首页、博客详情以及博客编辑的页面呈现和功能,进而验证登录博客、发布博客、重新编辑博客、删除博客、查看博客、退出博客等业务逻辑是否正确。
二、项目简介
简墨博客系统共有四大功能,对应四个页面,分别是:
1)用户登录页: 登录页作为系统唯一入口,提供账号密码输入与提交功能
2)博 客 首 页: 采用双栏设计,左侧是个人信息栏展示头像、昵称、文章及其数量、分类及其数量;中间及右侧是博客列表栏,支持加载本系统的全部博客
3)博客详情页: 详情页顶部固定展示标题和发布时间,正文区域显示文章内容。其中,若博客是本账号发布,则下面会出现出现“编辑”与“删除”按钮。“编辑”按钮可以跳转到编辑页进行更新博客;"删除"需二次确认警告弹窗,确认后同步删除首页列表缓存并刷新
4)博客编辑页: 编辑页可以输入博客标题和正文内容进行发布,顶部是博客标题输入区,中下部分采用markdown
插件,左侧是markdown
源代码格式,右侧同步有文字。若通过“写博客”按钮进入,标题输入框最右侧则是“发布文章”按钮;若为详情页进入,则为“更新文章”按钮
三、测试用例
对于一款软件的测试来说,一般可以分为6个方面: 功能测试、性能测试、界面测试、易用性测试、安全测试、兼容性测试。而简墨系统的主要由前端页面和后端接口组成,因此本次测试以功能测试、自动化测试和性能测试为主
1)功能测试:主要覆盖了用户登录页,博客首页,博客详情页,博客编辑页四个功能
2)自动化测试:主要覆盖了用户登录页,博客首页,博客详情页,博客编辑页四个页面及功能
3)性能测试:主要覆盖了5个接口,对其错误率、活跃线程、响应时间、吞吐进行分析
根据测试覆盖的功能、页面、接口,共设计出以下的测试用例:
四、测试工具
本次测试工具主要为编写测试用例、自动化测试和性能测试做准备,两者需要下载安装的工具如下:
1)编写测试用例工具:Xmind
思维导图
2)自动化测试工具:PyCharm
、Python3.11
、selenium4.0.0
软件包、webdriver-manager
软件包
3)性能测试工具:Postman
、 JMeter
、jdk-17
、jmeter-plugins-manager-1.11.jar
插件管理工具、Page Data Extractor
插件、Custom Thread Groups
插件、 jpgc - Standard Set
插件、Basic Graphs
插件
五、手动测试
1、用户登录页
因为账号和密码都已经储存在数据库里面,只要对应的输入框输入正常的账号和密码就可以,跳转到博客列表页了
a)登录界面展示
b)在对应的输入框输入正常的账号和密码:(账号:zhangsan
密码:123456
)
预期效果:跳转到博客列表页
实际效果展示:
c)输入错误的账号和正确的密码(账号:zhangsan_
密码:123456
)
预期结果:弹出弹窗并显示用户不存在
实际结果展示:
d)输入正确的账号和错误的密码(账号:zhangsan
密码:12345
)
预期结果:密码错误
实际结果展示:
e)输入错误的账号和错误的密码(账号:zhangsa
密码:1234567
)
预期结果:用户不存在
实际结果展示:
2、博客首页
在登录页面对应的输入框输入正确账号和正确密码后,会跳转到博客首页,左侧可以看到个人信息:当前登录的用户头像、昵称、发布文章及数量和分类及数量;中右侧可以看到列表区:可以看到已发布博客文章信息(包括标题、时间、博客内容、“查看全文”按钮)
a)个人信息展示和列表区展示
预期结果:个人信息有:头像、昵称、发布文章及数量和分类及数量、列表区每篇博客都有:标题、时间、博客内容、“查看全文”按钮
实际结果展示:显示正常
b)退出博客:点击“注销”按钮后返回到登录页
预期结果:跳转首页,账号密码输入框为空
实际结果展示: 成功返回到登录页
3、博客详情页
博客详情页里面也可以看到个人信息,还可以看到发布的博客文章相关内容,包含:标题,发布时间以及博客详情内容,若为本账号发布,还可以看到“编辑”按钮和”删除“按钮
a)详情页展示(本账号发布的博客):可以看到“编辑”和“删除”按钮
预期结果:博客的标题、时间、博客内容、“编辑”按钮和”删除“按钮
实际结果展示:显示正常
b)详情页展示(非本账号发布的博客):没有“编辑”和“删除”按钮
预期结果:博客的标题、时间、博客内容
实际结果展示:显示正常
c)删除博客:会弹出弹出进行确认,确认后返回首页,列表区不会有该文章
预期结果:删除后跳转首页,列表刷新后不存在被删除博客
实际结果展示: 返回首页,列表区不存在第二篇博客
4、博客编辑页
此页面可以输入博客标题,在markdown
插件的左侧输入文章内容,右侧也可以同步看到文章内容,点击右上方的按钮可以发布博客。若通过“写博客”按钮进入,标题输入框最右侧则是“发布文章”按钮;若为详情页进入,则为“更新文章”按钮
a)编辑页面展示:在首页点击“写博客”按钮进入
预期结果:插件正常加载、可以输入标题和文章内容
实际结果展示:显示正常及功能正常
b)通过“写博客”按钮进入并输入标题和文章内容发布
预期结果:博客的标题、博客内容正常输入并发布成功,并跳转到首页,列表中有发布的博客,发布时间正确
实际结果展示: 列表更新,出现发布的博客
c)通过详情页”编辑“按钮进入并输入标题和文章内容更新(从第四篇博客详情页的“编辑”按钮进入)
预期结果:博客的标题、博客内容是更新前的内容,修改后点击按钮可以更新成功,并跳转到首页,列表中的博客更新内容成功,时间不变
实际结果展示:
六、自动化测试
由于测试用例过多、手工测试的效率和成本过高,所以需要加入自动化测试帮助我们快速实现多个测试用例的检验。这时,需编写测试脚本,通过将大量测试用例交给机器来检查软件功能是否存在问题。
1、环境安装
这里用Python
脚本编写Selenium
脚本进行web
自动化测试,但前提是要配置好相关环境
Selenium
软件包:Selenium
是⼀个web
自动化测试⼯具,它提供了丰富的⽅法供给使⽤者进⾏web
⾃动化测试
webdriver-manager
软件包驱动:若通过自行下载并配置驱动的⽅式来启动浏览器,每次浏览器更新后对应的驱动也需要更新。为了解决这个问 题,Selenium
中提供了驱动管理⼯具webdriver-manager
,它是⼀个开源的命令⾏⼯具,可以帮助我们⾃动下载和安装适⽤于当前浏览器的驱动
首先,需要下载好PyCharm
和Python
环境,在PyCharm
中新建项目并选择本地Python
环境,创建好项目后在左上角File
中选择Settings
左侧列表中选择Project: xxx
中的Python Interpreter
右侧点击+
号,搜索Selenium
和webdriver-manager
并下载
注意: Selenium
选择的版本是4.0.0,webdriver-manager
直接下载最新版本即可
2、编写自动化测试脚本
2.1 项目目录
简墨博客系统由4个页面构成,且自动化测试脚本每次都需要创建对象、截图等功能,因此将重复使用的功能提取成一个配置内容,并针对四个页面分别创建4个不同对象,最后创建一个聚合运行,方便一次性全部测试。因此,项目的目录大致如下:
BlogAutoTest/
├─common
│ └─ Utils.py # 配置文件
├─images
│ └─2025-09-21 # 截图目录(以时间作为一个子目录)
└─tests├─ BlogDetail.py # 博客详情页├─ BlogEdit.py # 博客编辑页├─ BlogList.py # 博客首页├─ BlogLogin.py # 用户登录页└─ RunTests.py # 聚合测试
2.2 添加配置文件
创建Python
包common
,并在里面添加Python
文件Utils.py
:
之后创建一个驱动对象,以及三个构造函数,分别是对象成员的构造函数、两个截图函数(一个是系统级别截图,方便截取弹窗;另一个是页面级别截图,用于对执行结果的截图)以及一个退出浏览器函数。其中,截图有利于在程序报错时查找错误时的页面情况,从而可以快速解决问题
具体代码如下:
import datetime
import os
import sys
# 系统级截图依赖
import pyautogui
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()# 在本地环境变量中查找驱动,因此不用install# self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()),options=options)self.driver = webdriver.Chrome(options=options)def getScreeShot(self):# 创建屏幕截图名称driname = datetime.datetime.now().strftime("%Y-%m-%d")# 创建目录-判断是否存在目录if not os.path.exists("../images/"+driname):os.mkdir("../images/"+driname)# 进行页面级别屏幕截图操作# 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/"+driname+"/"+filename)def getAlertScreenshot(self):# 创建屏幕截图名称driname = datetime.datetime.now().strftime("%Y-%m-%d")# 创建目录-判断是否存在目录if not os.path.exists("../images/"+driname):os.mkdir("../images/"+driname)# 进行系统级别屏幕截图操作filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S")+".png"pyautogui.screenshot().save("../images/"+driname+"/"+filename)def driverQuit(self):self.driver.quit()# 单例模式-只生成一个
BlogDriver = Driver()
2.3 用户登录页自动化测试
a)测试内容:
在密码输入框中分别输入账号和密码,错误的测试用例是否登录失败并弹出提示;正确的测试用例是否登录成功并在首页中找到个人信息区的元素
b)测试流程:
1)创建Python
包tests
,并在里面添加Python
文件BlogLogin.py
2)创建一个BlogLogin
的类,并定义两个成员变量driver
和url
,以及一个构造函数和四个测试用例函数(包含一个正确测试用例LoginSucTest
,三个错误测试用例LoginFailUserTest
、LoginFailPassTest
、LoginFailAllTest
)
3)创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
注意: 在输入框中输入内容时要先执行清空操作,避免造成字符串拼接导致出错
具体代码如下:
from time import sleep
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:url = ""driver = ""wait = ""def __init__(self):self.url = "http://8.137.19.140:9090/blog_login.html"self.driver = BlogDriver.driverself.driver.get(self.url)self.driver.maximize_window()self.wait = WebDriverWait(self.driver, 3)# 成功登录的测试用例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()# 能找到简墨首页用户昵称,则说明登录成功,否则登录失败self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "body > div.container > div.left > div > h3")))# 屏幕截图记录BlogDriver.getScreeShot()self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3")# 打印成功信息print("LoginSucTest:>"+self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3").text)# # 返回登录界面# self.driver.back()# 用户名错误的测试用例def LoginFailUserTest(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()# 检查是否登录失败self.wait.until(EC.alert_is_present())# 屏幕截图记录sleep(0.3)BlogDriver.getAlertScreenshot()# 出现弹窗,点击确定print("LoginFailUserTest:>"+self.driver.switch_to.alert.text)self.driver.switch_to.alert.accept()# 密码错误的测试用例def LoginFailPassTest(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("12345")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()# 检查是否登录失败# 检查是否登录失败self.wait.until(EC.alert_is_present())# 屏幕截图记录sleep(0.3)BlogDriver.getAlertScreenshot()# 出现弹窗,点击确定print("LoginFailPassTest:>"+self.driver.switch_to.alert.text)self.driver.switch_to.alert.accept()# 用户名密码都错误的测试用例def LoginFailAllTest(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("1234567")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()# 检查是否登录失败# 检查是否登录失败self.wait.until(EC.alert_is_present())# 屏幕截图记录sleep(0.3)BlogDriver.getAlertScreenshot()# 出现弹窗,点击确定print("LoginFailAllTest:>"+self.driver.switch_to.alert.text)self.driver.switch_to.alert.accept()BlogLoginDriver = BlogLogin()
BlogLoginDriver.LoginFailUserTest()
BlogLoginDriver.LoginFailPassTest()
BlogLoginDriver.LoginFailAllTest()
BlogLoginDriver.LoginSucTest()
BlogDriver.driverQuit()
c)执行的结果:
2.4 博客首页自动化测试
a)测试内容:
未登录状态下通过网址进入首页,会退回到登录页;登录状态下进入首页,查找个人信息相关元素(当前登录的用户头像、昵称、发布文章及数量和分类及数量),以及博客列表区其中一篇博客的基本元素(包括标题、时间、博客内容、“查看全文”按钮)
b)测试流程:
1)在Python
包tests
中添加Python
文件BlogList.py
2)创建一个BlogList
的类,并定义两个成员变量driver
和url
,以及一个构造函数和两个个测试用例函数(包含未登录状态测试用例ListByNotLogin
,以及一个登录状态下的测试用例ListByLogin
)
3)创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
具体代码如下:
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver
from tests.BlogLogin import BlogLoginDriver
from time import sleep# 测试简墨首页
class BlogList:url = ""driver = ""def __init__(self):self.url = "http://8.137.19.140:9090/blog_list.html"self.driver = BlogDriver.driverself.driver.get(self.url)self.driver.maximize_window()# 登录状态下的简墨列表的测试用例def ListByLogin(self):# 查找简墨博客列表元素:标题、发布时间、内容、"查看详情"按钮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.date")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 > img")self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3")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(5) > 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 > div:nth-child(5) > span:nth-child(2)")# 屏幕截图记录BlogDriver.getScreeShot()# 打印成功相关信息print("ListByLogin:>"+self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3").text)print("ListByLogin:>"+self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(2) > div.title").text)# 未登录状态下的简墨列表的测试用例def ListByNotLogin(self):# 会自动跳转回简墨登录页sleep(0.5)current_url = self.driver.current_urlassert current_url != self.urlprint("ListByNotLogin-before_url:>"+self.url)print("ListByNotLogin-after_url :>"+current_url)# 屏幕截图记录BlogDriver.getScreeShot()BlogListDriver = BlogList()
BlogListDriver.ListByNotLogin()
BlogLoginDriver.LoginSucTest()
BlogListDriver.ListByLogin()
BlogDriver.driver.quit()
c)执行的结果:
2.5 博客详情页自动化测试
a)测试内容:
未登录状态下通过网址进入博客详情页,会退回到登录页;登录状态下进入详情页,页面会显示该博客的基本元素(标题,发布时间以及博客详情内容),查找元素是否存在,从而检查页面是否正常;若是本账号发布,还可以看到“编辑”按钮和“删除”按钮
b)测试流程:
1)在Python
包tests
中添加Python
文件BlogDetail.py
2)创建一个BlogDetail
的类,并定义两个成员变量driver
和url
,以及一个构造函数和两个个测试用例函数(均用本账号发布博客进行编写,包含未登录状态测试用例DetailByNotLogin
,以及一个登录状态下的测试用例DetailByLogin
)
3)创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
具体代码如下:
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver
from tests.BlogLogin import BlogLoginDriver
from time import sleep# 测试简墨博客详情页
class BlogDetail:url = ""driver = ""def __init__(self):self.url = "http://8.137.19.140:9090/blog_detail.html?blogId=158477"self.driver = BlogDriver.driverself.driver.get(self.url)self.driver.maximize_window()# 登录状态下的简墨博客详情的测试用例def DetailByLogin(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")# 查找简墨博客个人信息:头像、昵称、文章、文章数量、分类、分类数量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 > h3")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(5) > 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 > div:nth-child(5) > span:nth-child(2)")# 屏幕截图记录BlogDriver.getScreeShot()print("ListByLogin:>"+self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3").text)print("ListByLogin:>"+self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.title").text)print("ListByLogin:>"+self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.operating > button:nth-child(1)").text)# 未登录状态下的简墨博客详情的测试用例def DetailByNotLogin(self):# 会自动跳转回简墨登录页sleep(0.5)current_url = self.driver.current_urlassert current_url != self.urlprint("DetailByNotLogin-before_url:"+self.url)print("DetailByNotLogin-after_url:"+current_url)# 屏幕截图记录BlogDriver.getScreeShot()BlogDetailDriver = BlogDetail()
BlogDetailDriver.DetailByNotLogin()
BlogLoginDriver.LoginSucTest()
BlogLoginDriver.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(2) > a").click()
BlogDetailDriver.DetailByLogin()
BlogDriver.driverQuit()
c)执行的结果:
2.6 博客编辑页自动化测试
a)测试内容:
未登录状态下通过网址进入博客编辑页,会退回到登录页;登录状态下进入编辑页,等待页面加载完成后,输入标题内容并发布,发布完成后会回到首页并刷新,列表会显示出刚刚发布的博客
b)测试流程:
1)在Python
包tests
中添加Python
文件BlogEdit.py
2)创建一个BlogEdit
的类,并定义三个成员变量driver
、url
和wait
,以及一个构造函数和两个个测试用例函数(包含未登录状态测试用例EditByNotLogin
,以及一个登录状态下的测试用例EditByLogin
)
3)创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
具体代码如下:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from common.Utils import BlogDriver
from tests.BlogLogin import BlogLoginDriver
from time import sleep
from selenium.webdriver.support import expected_conditions as EC# 测试简墨博客编辑页
class BlogEdit:url = ""driver = ""wait = ""def __init__(self):self.url = "http://8.137.19.140:9090/blog_edit.html"self.driver = BlogDriver.driverself.driver.get(self.url)self.driver.maximize_window()self.wait = WebDriverWait(self.driver, 5)# 登录状态下的简墨博客编辑的测试用例def EditByLogin(self):# 等待页面加载出来self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#editor > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")))# 输入简墨博客文章标题和内容并发布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(21) > a > i").click()# 屏幕截图记录BlogDriver.getScreeShot()self.driver.find_element(By.CSS_SELECTOR, "#submit").click()# 查找最后一篇文章标题是自动化测试创建的self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(6) > div.title")))text = self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(6) > div.title").textBlogDriver.getScreeShot()assert text == "第一篇文章-测试"print("EditByLogin:>"+text)# 未登录状态下的简墨博客编辑的测试用例def EditByNotLogin(self):# 等待页面加载出来self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#editor > div.editormd-toolbar > div > ul > li:nth-child(21) > a > i")))# 输入简墨博客文章标题和内容并发布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(21) > a > i").click()# 屏幕截图记录BlogDriver.getScreeShot()self.driver.find_element(By.CSS_SELECTOR, "#submit").click()# 会自动跳转回简墨登录页sleep(0.5)current_url = self.driver.current_urlassert current_url != self.urlprint("EditByNotLogin-before_url:"+self.url)print("EditByNotLogin-after_url:"+current_url)# 屏幕截图记录BlogDriver.getScreeShot()BlogEditDriver = BlogEdit()
BlogEditDriver.EditByNotLogin()
BlogLoginDriver.LoginSucTest()
BlogLoginDriver.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(5)").click()
BlogEditDriver.EditByLogin()
BlogDriver.driverQuit()
c)执行的结果:
2.7 回归测试
a)测试内容:
将四个页面功能按照一定顺序排列出来,并进行一次完整的测试,从而检查页面是否存在问题
b)测试流程:
1)在Python
包tests
中添加Python
文件RunTests.py
2)创建__main__
3)创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
具体代码如下:
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver
from tests.BlogLogin import BlogLoginDriver
from tests.BlogList import BlogListDriver
from tests.BlogDetail import BlogDetailDriver
from tests.BlogEdit import BlogEditDriverif __name__ == '__main__':# 未登录状态下的简墨列表、简墨博客详情、简墨博客发布BlogListDriver.ListByNotLogin()BlogDetailDriver.DetailByNotLogin()BlogEditDriver.EditByNotLogin()# 异常登录BlogLoginDriver.LoginFailAllTest()BlogLoginDriver.LoginFailUserTest()BlogLoginDriver.LoginFailPassTest()# 成功登录BlogLoginDriver.LoginSucTest()# 检查简墨列表BlogListDriver.ListByLogin()# 进入简墨博客详情页并检查元素BlogLoginDriver.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(2) > a").click()BlogDetailDriver.DetailByLogin()# 进入简墨博客发布页发布BlogDriver.driver.back()BlogLoginDriver.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(5)").click()BlogEditDriver.EditByLogin()BlogDriver.driverQuit()
c)执行的结果:
七、性能测试
Apache JMeter
是 Apache
组织基于 Java
开发的压力测试工具,用于对软件做性能测试
为了更好的在JMeter
中配置好相关内容进行性能测试,在配置之前先在Postman
中进行简单的验证,接口的获取则在浏览器中按F12
进入开发者模式,之后选择Network
,再选择Fetch/XHR
,在Name
列表中选择请求,右侧便可以看到接口、请求方法
1、相关工具使用说明
1)浏览器开发者模式选项
2)Postman
2、性能测试相关配置
2.1 通用配置文件
1)添加梯度压测线程组,并进行相关配置
2)线程组中添加HTTP请求默认值,可以简化后面接口填写内容
3)配置用户登录凭证,用于测试用户登录行为
4)用户自定义变量,用于详情页博客的查询
5)账号密码数据文件设置,保存多个用户的账号密码,可以模拟多用户登录场景
2.2 用户登录接口配置
添加用户登录接口请求,进行用户登录接口测试,需要配置接口的请求方法、路径以及账号密码参数,同时这里需要保存登录凭证,为后面的接口调用提供合法请求
这里也可以对数据进行Json
断言,判断返回的数据是否符合要求
2.3 用户信息接口配置
添加用户信息接口请求,进行用户信息接口测试,用于获取用户账号、密码、登录凭证等信息
2.5 首页接口配置
添加首页接口请求,进行首页接口测试,并从中提取有效的博客id,用于详情页的接口测试
2.6 详情页接口配置
添加详情页接口请求,进行详情页接口测试
2.7 添加博客接口配置
添加添加博客接口请求,进行添加博客接口测试,因为要写入标题和内容,因此用消息体数据的方式写入数据
同时,也要改消息体的数据格式为Json
,因此要添加Http
消息头管理器,改Content-Type
内容为application/json
2.8 添加相关监听器
可以根据监听器相关组件获取的数据,最终对数据进行分析
3、进行性能测试并分析报告
点击开始,进行性能测试,等待运行时间结束可以看到运行成功
在这里,对比响应时间和吞吐量,可以发现:响应时间变长、吞吐量就变小,可以关注这几个点进行优化
接下来用命令的格式出具性能测试报告,命令基本格式如下
# 成性能测试报告的命令
Jmeter -n -t 脚本文件 -l 日志文件 -e -o 目录
-n : 无图形化运行
-t : 被运行的脚本
-l : 将运行信息写入日志文件,后缀为jtl的日志文件
-e : 生成测试报告
-o : 指定报告输出目录
在测试计划保存目录下使用cmd
运行命令jmeter -n -t jmeter-test.jmx -l jmeter-test.jtl -e -o ./jmeter-test/.
,并等待结束
性能测试报告生成成功后,在jmeter-test
目录下将出现以下内容,点击index.html
就可以看到详细内容
在聚合报告中,可以看到首页的响应时间最大值很大,可能存在问题
还可以看到活跃进程数量、响应时间、吞吐量
活跃进程数:
吞吐量:
响应时间:
八、测试总结
项目不足:
1、输入密码框缺少显示密码可见功能,当用户设置的密码比较繁琐时,并不利于用户正确输入密码
2、博客列表的更新是从下往上更新不便查找更新内容,不利于查找内容
3、文章和分类下面的数字仅仅是装饰,并不能计算
4、文章详情页的作者信息位置和个人信息位置重叠,会让人难以分辨本次登录的账号是哪个
测试总结:
本次项目测试的内容基本通过,但还存在需要改进的地方:
1、建议可以实现文章分类功能,加入可以计算分类数量和文章数量的功能
2、可以优化博客详情页,让个人信息区固定左侧,文章发布的作者并列在发布时间
3、建议去除首页写博客按钮,因为此按钮虽然可以进入编辑博客页面,但点击发布后仍然会回到登录页,写入的内容也不会保存