【项目测试】:问卷考试系统项目测试报告
朋友们、伙计们,我们又见面了,本期来给大家带来关于问卷考试系统的测试报告,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!
C 语 言 专 栏:C语言:从入门到精通
数据结构专栏:数据结构
个 人 主 页 :stackY、
C + + 专 栏 :C++
Linux 专 栏 :Linux
目录
1. 问卷考试系统项目
2. 测试计划
3. 测试工具
4. 设计测试用例
4.1 注册页面测试用例
4.2 登录页面测试用例
4.3 问卷考试系统测试用例
5. 手动测试
5.1 注册页面
5.2 登录页面
5.3 问卷考试系统
5.3.1 首页
5.3.2 我的项目
5.3.3 我的练习
5.3.4 题库中心
5.3.5 模板广场
5.3.6 系统管理
6. 自动化测试用例设计
6.1 设计自动化测试代码
6.2 common模块
6.3 QES_test模块
6.3.1 注册
6.3.2 登录
6.3.3 首页
6.3.4 我的项目
6.3.5 我的练习
6.3.6 题库中心
6.3.7 模板广场
6.3.8 系统管理
6.3.9 运行模块
7. 兼容性测试
8. 性能测试
8.1 单一性能接口测试
8.1.1 系统登录页面
8.1.2 登录接口
8.1.3 我的项目
8.1.4 我的练习
8.1.5 题库中心--我的题库
8.1.6 题库中心--问题管理
8.1.7 题库中心--我的笔记
8.1.8 模板广场
8.1.9 系统设置--用户管理
8.1.10 系统设置--角色管理
8.1.11 系统设置--组织机构
8.1.12 系统设置--岗位设置
8.1.13 系统设置--字典管理
8.1.14 系统设置--个人设置
8.2 聚合报告
8.3 吞吐量(Transactions per Second)
8.4 响应时间(Response Times Over Time)
8.5 随时间变化的活跃线程状态(Active Threads Over Time)
8.6 性能测试报告
8.6.1 Dashboard
8.6.2 Charts
9. 发现的BUG
9.1 功能异常
9.2 兼容性异常
9.3 接口异常
10. 测试总结
10.1 项目功能完整性
10.2 接口性能数据
附录
注册接口测试用例
登录接口测试用例
整体系统测试用例
自动化测试用例
自动化测试脚本
JMeter性能测试文件
性能测试报告
1. 问卷考试系统项目
项目背景:
该项目(问卷考试系统)是一款基于Web的在线测评平台,主要可以用于:创建以及管理不同类别的问卷及考试、发布在线问卷考试和练习最后进行数据收集、分析调查和数据汇总;另外还可以管理题库和试题资源。
该系统面向教育机构、企业培训部门和市场调研机构,提供从问卷/考试创建、发布、答题到结果分析的全流程解决方案。
系统包含以下核心模块:
用户管理:注册、登录、组织机构分配给用户
项目管理:创建问卷及考试,发布并进行数据统计以及汇总
题库管理:题库的创建、导入导出,题目的创建、错题本以及笔记
练习系统:已有的题目点击练习、查看结果、查看进度
模板管理:对问卷、考试已有模板的使用以及新建模板
系统设置:角色、组织、岗位、字典各种功能的设置以及个人信息的修改和安全设置
项目登录地址: http://8.155.1.153:8081/user/login
测试环境:
- 操作系统:Windows 11 / Windows10 64位
- 浏览器: Chrome--138.0.7204.184(正式版本)(64 位)
- Edge--138.0.3351.121 (正式版本) (64 位)
- 测试工具:Pycharm、selenium、JMeter、postman
2. 测试计划
① 根据不同的场景设计对应的测试用例
② 根据测试用例执行测试
③ 编写自动化测试脚本
3. 测试工具
Pycharm、selenium、chrome-driver(本地)、Chrome、Edge、JMeter、postman
4. 设计测试用例
测试测试用例一般从下面6个方面出发:
功能测试、界面测试、性能测试、易用性测试、兼容性测试、安全测试;
接下来我根据不同的使用场景设计对应的测试用例,其中有一些测试用例可以进行复用我们直接复用;
4.1 注册页面测试用例
4.2 登录页面测试用例
4.3 问卷考试系统测试用例
对整个系统设置的测试用例更多的注重于系统的功能测试:
5. 手动测试
分别对注册页面、登录页面、整个系统进行功能测试:
5.1 注册页面
预期结果:姓名、账号、密码、确认密码、角色选择都是必填的,全部填写完成才能成功注册账号;
只输入一个或者是有一个没有输入都是会有提示的,不能注册成功;
接下来注册的账号也用于后面的测试中,另外还有一键清除、密码的显示都进行测试:
点击注册之后会跳转到登录页面,并提示“注册成功”:
当我们在注册页面时,打开大小写时,是没有提示的;
另外,在注册时可以注册登录账号为空格的用户;
5.2 登录页面
预期结果:用户名和密码都必须填写,并且得输入正确的用户名和正确的密码;
当用户名和密码填写正确时,点击登录就会进入系统并提示“登录成功”:
但是在登录这里发现当用户名为空格时没有进行特殊处理;
5.3 问卷考试系统
整个系统的核心功能有:首页、我的项目、我的练习、题库中心、模板广场、用户设置;
分别对这些核心功能进行功能测试:
5.3.1 首页
因为是新注册的账号,所以没有考试和问卷记录,那么首先就来验证创建考试和创建文件的这两个功能;
创建问卷预期结果:在点击创建问卷之后,跳转到创建问卷的页面,然后将问卷题型模板拖入,根据所需进行修改,并点击保存,在提示“成功创建”之后可以在我的问卷页面看到新创建的问卷:
问卷可以创建成功,但是问卷创建成功之后保存在了我的项目里面,在个人首页的我的问卷是没有的,另外个人主页的问卷数也是可以增加的;
创建考试预期结果:在点击创建考试之后,跳转到创建考试的页面,然后将题型模板拖入,根据所需进行修改,并点击保存,在提示“创建成功”之后可以在我的考试页面看到新创建的考试:
但是实际情况同创建问卷一样,并没有在我的考试中显示出来;
问卷记录和考试记录:当我们填写了问卷或者是进行了考试之后,都会在这两栏进行显示具体的信息:
其中,这些记录也有刷新,密度、列设置这些功能都可以使用,不同的密度展示的记录紧凑程度不同,列设置如果不勾选,则不会出现:
5.3.2 我的项目
我的项目这个页面中首先测试新建项目;
预期结果:点击“新建项目”选择要创建的项目类型,选择之后跳转到对应的创建页面,选择对应的题型模板然后进行修改,点击保存之后就可以在我的项目页面找到新创建的项目:
项目展示这里的平铺展示和列表展示;
预期结果:每个展示的方式对于其对应:
在搜索输入关键字搜索项目;
预期结果:再输入关键字之后可以搜到带关键字的所有的项目:
对于项目的删除;
预期结果:在项目的右下角的“三个小点”点击之后有删除,点击删除之后在我的项目里面移除对应的项目:
项目设置;
点击项目下面的“小齿轮”可以进入到项目的具体设置页面:
5.3.3 我的练习
由于是新注册的账号,所以没有对应的练习,所以可以先在数学题库中测试一道题;
点击数学或者语文就可以看到对应的题库:
点击开始练习之后会跳转到选择“顺序练习”、“随机练习”、“错题练习”,点击“顺序练习”之后直接跳转到了答题页面:
答题结束之后就可以在我的练习页面查看到所做过的题可以通过状态的选择进行筛选,也可以看到完成的进度,没有完成的题也可以继续答题,完成的题可以查看结果,也可以对题目进行删除:
删除练习;
预期结果:点击最右面的“删除”,提示是否删除,点击OK,即可以删除练习:
5.3.4 题库中心
题库中心有三个模块:我的题库、问题管理、我的笔记;
依次对这三个模块进行功能测试:
题库中心:
搜索功能预期结果:名称栏输入题库名称,类型选择是问卷还是考试,然后点击查询即可以找到对应的题库:
并且点击重置之后我们之前输入的查询关键字都会被清空:
新建题库预期结果:点击新建之后跳转到新增题库的页面,其中可以创建新的题库,输入好题库信息之后点击确定便可以创建好题库了:
试题管理预期结果:点击试题管理之后会跳转到试题管理的页面,我们可以通过添加试题来为我们新创建的题库增添题目,另外也可以对我们添加好的试题进行再次编辑:
删除题库预期结果:点击题库最右边的“三个点”可以弹出编辑和删除,我们点击删除之后会有一个再次确认的弹窗,点击删除之后就可以将对应的题库从中删除掉:
问题管理:
问题管理模块是对我们创建的题库中新添加的题目的管理;
我们可以对这些题目进行编辑一些一些查询:
我的笔记:
在答题的时候,题目下面有一个笔的小标志,点击一下就可以进行笔记的记录,记录完成之后就会在我的笔记页面进行展示:
笔记的删除预期结果:我们点击删除操作之后,会有提示弹窗,点击OK之后就可以删除该条笔记:
5.3.5 模板广场
模板广场添加模板功能验证;
预期结果:点击“添加模版”之后跳转至添加模板的页面,然后选择题型进行修改,点击保存时会弹出一个设置模板的页面,其中可以填写模板的名称,分类以及标签,还可以勾选“添加到公共库”,点击保存,就可以看到我们新建的模板了:
搜索模板功能验证;
预期结果:输入关键字并点击“搜模板”即可以查找到对应的模板:
在搜索模板这里是有功能bug的,不能根据输入的关键字来查找对应的模板;
模板筛选功能验证:
预期结果:通过对模板分类的选择,筛选出对应分类的模板:
私有库的验证:
在创建模板时,我们不勾选“添加到公共库”然后点击保存之后,就可以在私有库中看到我们说创建的模板了:
5.3.6 系统管理
系统管理分为以下几个模块:用户管理、角色管理、组织机构、岗位设置、字典管理、个人设置;
接下来分别对这些模块进行功能验证:
用户管理
组织机构筛选验证:
可以根据选择对应的组织机构筛选出隶属于这个组织机构的用户:
输入查询功能验证:
通过输入姓名,点击查询之后可以筛选出对应姓名的用户:
用户编辑功能以及重置密码、删除用户验证:
点击“编辑”之后可以看到用户的各种信息,可以对这些信息进行修改,另外,点击“更多”之后会出现“重置密码”和“删除用户”的选项,可以点击达到对应的效果;
新建用户功能验证:
点击“新建”之后跳转到填写用户信息的页面,填写完成之后点击“确定”就可以完成对新用户的创建:
角色管理
搜索角色功能验证:
输入对应的关键字并点击查询就可以筛选出对应的角色信息:
新建角色功能验证:
点击“新建”跳转到角色信息填写页面,填写完对应的信息之后点击“确定”就可以新建新的角色:
编辑以及分配用户功能测试:
点击“编辑”就可以跳转到对应的角色信息,可以对角色信息进行修改,并点击确定进行保存,点击“三个点”会有一个“分配用户”的选择,点击之后可以对用户进行角色的分配:
组织机构
新建组织机构功能测试:
点击“新建”之后跳转到信息填写页面,填写完成之后点击“确定”即可以创建新的机构:
删除机构功能测试:
点击“删除”会跳出弹窗提示是否删除,点击“确定”即可以删除对应的机构:
岗位设置
搜索功能验证:
输入对应的关键字,并点击“查询”可以筛选出对应的岗位:
新建岗位功能验证:
点击“新建”跳转到信息填写页面,填写完成之后点击“确定”既可以完成新建:
删除岗位功能验证:
点击“删除”之后会有二次确认,点击“确定”既可以删除对应的岗位:
字典管理
查询字典功能验证:
输入对应的关键字,并点击“查询”就可以筛选出对应的字典:
新建字典功能验证:
点击“新建”然后跳转到填写字典信息页面,填写完对应的信息之后点击“确定”可以完成对字典的新建:
删除字典功能验证:
点击“三个小点”出现的删除,点击“删除”进行二次确认即可完成删除字典:
个人设置
基本设置:
可以修改姓名、手机号、邮箱、个人简介以及更换头像:
安全设置:
修改账户密码:
6. 自动化测试用例设计
6.1 设计自动化测试代码
自动化这里我们用的到工具是Pycharm以及selenium库;
在自动化测试这里我们分文件编写脚本代码,根据页面的不同,分为注册页面、登录页面、首页、我的项目、我的练习、题库中心、模板广场、系统管理这几个页面,我们根据不同的页面来针对性的设计自动化测试代码:
代码框架:
一个分为三个模块:
- common模块是对公共方法的编写
- images模块是对屏幕截图的保存
- QES_test模块是对核心功能的自动化测试
6.2 common模块
在这个文件里面,主要实现驱动的创建、屏幕截图、清空输入框、设计单例:
其中博主用的是本地驱动,只需要将本地驱动的路径更改为自己的即可;
Utils.py:
# 本文件用于驱动的创建 # 添加等待 # 屏幕截图 # 清空输入框 # 设计单例模式import datetime import os import sysfrom selenium import webdriver from selenium.webdriver import ActionChains, Keys from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Serviceclass Driver:driver = "" # 驱动对象def __init__(self):# 本地驱动所在路径chrome_driver_path = "E:\\Python\\chromedriver-win64\\chromedriver.exe"options = Options()options.add_argument("--remote-allow-origins=*")# 创建驱动self.driver = webdriver.Chrome(service=Service(chrome_driver_path), options=options)# 添加隐式等待self.driver.implicitly_wait(2)# 屏幕截图功能# ../images/当前日期/调用函数名-当前具体日期.pngdef GetScreenShot(self):# 文件夹名称(以日期为划分)dirname = datetime.datetime.now().strftime("%Y-%m-%d")# 判断该文件名是否存在# 不存在就创建if not os.path.exists("../images/" + dirname):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)# 清空指定输入框的内容def ClearInput(self, element):actions = ActionChains(self.driver)actions.click(element) # 点击元素actions.key_down(Keys.CONTROL).send_keys("a").key_up(Keys.CONTROL) # Ctrl+Aactions.send_keys(Keys.DELETE) # 删除actions.perform() # 执行所有动作# 创建单例 QESDriver = Driver()
屏幕截图是根据调用屏幕截图的函数以及调用时间进行命名,根据日期进行分类;
6.3 QES_test模块
在该模块中对问卷考试系统的主要功能进行自动化脚本的设计,为了更加直观,将每个页面都按文件分别编写:
- 首页:HomePage.py
- 注册页面:RegistrationPage.py
- 登录页面:LoginPage.py
- 我的项目:MyProjectPage.py
- 我的练习:MyPracticePage.py
- 题库中心:QuestionBankCenterPage.py
- 模板广场:TemplateSquarePage.py
- 系统管理:SystemManagementPage.py
- 运行模块:RunTest.py
6.3.1 注册
RegistrationPage.py:
import timefrom selenium.webdriver.common.by import Byfrom common.Untils import QESDriver# 注册页面 class RegPage:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/user/login"self.driver = QESDriver.driverself.driver.get(self.url)def GetRegPage(self):# 查找注册按钮并点击self.driver.find_element(By.CSS_SELECTOR, "#root > div > div.content___2zk1- > div.main___x4OjT > div > form > div:nth-child(4) > a").click()# 什么都不输入直接点击注册并截图self.driver.find_element(By.XPATH,'//*[@id="root"]/div/div[2]/div[2]/div/form/button').click()time.sleep(0.5)QESDriver.GetScreenShot()######################################################################################################### 查找姓名输入框并输入self.driver.find_element(By.XPATH, '//*[@id="name"]').send_keys("小王")# 查找登录账号输入框并输入self.driver.find_element(By.XPATH,'//*[@id="username"]').send_keys("xiaowang")# 查找密码输入框并输入self.driver.find_element(By.XPATH,'//*[@id="password"]').send_keys("123456")# 查找密码确认输入框并输入self.driver.find_element(By.XPATH,'//*[@id="rePassword"]').send_keys("123456")# 点击注册self.driver.find_element(By.XPATH,'//*[@id="root"]/div/div[2]/div[2]/div/form/button').click()time.sleep(0.5)
6.3.2 登录
验证正确密码、错误密码的登录效果;
LoginPage.py:
import timefrom selenium.webdriver.common.by import Byfrom common.Untils import QESDriver# 登录页面 class LoginPage:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/user/login"self.driver = QESDriver.driverself.driver.get(self.url)def GetLoginPage(self):# 不输入用户名点击登录self.driver.find_element(By.XPATH,'//*[@id="root"]/div/div[2]/div[2]/div/form/button').click()time.sleep(0.5)QESDriver.GetScreenShot() ################################################################################################# 查找用户名输入栏并输入“xiaowang”self.driver.find_element(By.XPATH,'//*[@id="username"]').send_keys("xiaowang")# 查找密码输入栏并输入错误密码“654321”self.driver.find_element(By.XPATH,'//*[@id="password"]').send_keys("654321")# 使用错误密码并点击登录然后截图展示self.driver.find_element(By.XPATH,'//*[@id="root"]/div/div[2]/div[2]/div/form/button').click()time.sleep(0.5)QESDriver.GetScreenShot() ########################################################################################################## 使用正确密码登录并截图查看# 先清空,再输入正确密码QESDriver.ClearInput(self.driver.find_element(By.XPATH,'//*[@id="password"]'))self.driver.find_element(By.XPATH,'//*[@id="password"]').send_keys("123456")self.driver.find_element(By.XPATH,'//*[@id="root"]/div/div[2]/div[2]/div/form/button').click()time.sleep(0.5)QESDriver.GetScreenShot()
6.3.3 首页
在首页我们对首页的元素进行查找,然后点击创建问卷或者点击创建考试并截图:
HomePage.py:
import timefrom selenium.webdriver.common.by import Byfrom common.Untils import QESDriverclass HomePage:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/home" # 首页对应的urlself.driver = QESDriver.driver # 创建驱动self.driver.get(self.url) # 访问首页# 点击、查找首页对应的元素def GetHomePage(self):# 查找首页元素并截图home = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[1]/div/span').text# assert home == "首页"navigation_bar = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[1]/div/div').textassert navigation_bar == "快速开始 / 便捷导航"QESDriver.GetScreenShot()########################################################################################### 查找“我的考试”并点击self.driver.find_element(By.XPATH,'//*[@id="rc-tabs-0-panel-exam"]/div/div/div/div[2]/div/div/div/div/div/table/thead/tr/th[1]').click()# 查找“我的问卷”并点击self.driver.find_element(By.XPATH,'//*[@id="rc-tabs-0-panel-exam"]/div/div/div/div[2]/div/div/div/div/div/table/thead/tr/th[2]').click()# 查找“问卷记录”并点击self.driver.find_element(By.XPATH,'//*[@id="rc-tabs-0-panel-exam"]/div/div/div/div[2]/div/div/div/div/div/table/thead/tr/th[3]').click()# 查找“考试记录”并点击self.driver.find_element(By.XPATH,'//*[@id="rc-tabs-0-panel-exam"]/div/div/div/div[2]/div/div/div/div/div/table/thead/tr/th[4]').click()def HP_CreateQuestionnaire(self):# 点击创建问卷并截图self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/a[1]').click()time.sleep(0.5)QESDriver.GetScreenShot()self.driver.back()def HP_CreateExaminations(self):# 点击创建考试并截图self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/a[2]').click()time.sleep(0.5)QESDriver.GetScreenShot()self.driver.back()
6.3.4 我的项目
MyProjectPage.py:
import timefrom selenium.webdriver.common.by import Byfrom common.Untils import QESDriverclass MyProject:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/project"self.driver = QESDriver.driverself.driver.get(self.url)def GetMyProject(self):# 列展示self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[2]/div/div/div/div/div/div/div/div/label[2]').click()time.sleep(0.5)QESDriver.GetScreenShot()# 平铺展示self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[2]/div/div/div/div/div/div/div/div/label[1]').click()time.sleep(0.5)QESDriver.GetScreenShot()# 新建项目self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[1]/span/div/div/button').click()QESDriver.GetScreenShot()# self.driver.find_element(By.XPATH,'/html/body/div[4]/div/div/ul/li[1]/span').click()
6.3.5 我的练习
我的练习页面,先查找页面元素,然后分别对数学练习以及语文练习进行测试并截图:
MyPracticePage.py:
import timefrom selenium.webdriver.common.by import Byfrom common.Untils import QESDriverclass MyPractice:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/exercise"self.driver = QESDriver.driverself.driver.get(self.url)def GetMyPractice(self):# 查找页面元素并截图title1 = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[1]/div/div[1]/div').textassert title1 == "我的练习"title2 = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[2]/div/div/div/div/div/table/thead/tr/th[1]').textassert title2 == "练习名称"title3 = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[2]/div/div/div/div/div/table/thead/tr/th[2]').textassert title3 == "练习进度"title4 = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[2]/div/div/div/div/div/table/thead/tr/th[3]').textassert title4 == "练习类型"title5 = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[2]/div/div/div/div/div/table/thead/tr/th[4]').textassert title5 == "状态"title6 = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[2]/div/div/div/div/div/table/thead/tr/th[5]').textassert title6 == "创建时间"title7 = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[2]/div/div/div/div/div/table/thead/tr/th[6]').textassert title7 == "操作"QESDriver.GetScreenShot()################################################################################def MathExercise(self):# 点击“数学”self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[1]/div[1]/div[1]/div').click()# 查找输入框并输入1self.driver.find_element(By.XPATH, '//*[@id="name"]').send_keys("1")# 查找“查询”并点击然后截图self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/button').click()time.sleep(0.5)QESDriver.GetScreenShot()# 查找“重置”并点击self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[1]/button').click()# 查找“开始练习”并点击self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[1]/td[3]/div/div/a').click()time.sleep(0.5)QESDriver.GetScreenShot()# 查找页面元素# title1 = self.driver.find_element(By.XPATH,'/html/body/div[5]/div/div[2]/div/div[2]/div/div/div[2]/div[1]/div/div/div').text# assert title1 == "顺序练习"# title2 = self.driver.find_element(By.XPATH,'/html/body/div[5]/div/div[2]/div/div[2]/div/div/div[2]/div[2]/div/div/div').text# assert title2 == "随机练习"# title3 = self.driver.find_element(By.XPATH,'/html/body/div[5]/div/div[2]/div/div[2]/div/div/div[2]/div[3]/div/div/div').text# assert title3 == "错题练习"# 顺序练习# def PracticeInSequence(self):# # 点击“顺序练习”并截图# self.driver.find_element(By.XPATH,'/html/body/div[5]/div/div[2]/div/div[2]/div/div/div[2]/div[1]/div/div/div').click()# # 点击“下一页”# self.driver.find_element(By.XPATH, '//*[@id="root"]/div[2]/div/div/div[5]/div/div[1]/button').click()# # 点击“答对自动跳转下一页”# self.driver.find_element(By.XPATH, '//*[@id="root"]/div[2]/div/div/div[5]/div/div[4]/button').click()# # 点击最后一题并点击“结束练习”# self.driver.find_element(By.XPATH, '//*[@id="root"]/div[2]/div/div/div[6]/div[2]/div[13]').click()# self.driver.find_element(By.XPATH, '//*[@id="root"]/div[2]/div/div/div[5]/div[2]/div[2]/button/div').click()# time.sleep(0.5)# QESDriver.GetScreenShot()def ChineseExercises(self):# 点击“语文”self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[1]/div[1]/div[1]/div/div[3]').click()# 查找输入框并输入1self.driver.find_element(By.XPATH, '//*[@id="name"]').send_keys("1")# 查找“查询”并点击然后截图self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/button').click()time.sleep(0.5)QESDriver.GetScreenShot()# 查找“重置”并点击self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[1]/button').click()# 查找“开始练习”并点击self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div[2]/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr/td[3]/div/div/a').click()time.sleep(0.5)QESDriver.GetScreenShot()
6.3.6 题库中心
题库中心这里分为三个模块,我们按照不同的模块设计了不同的类对象进行自动化测试:
- 我的题库:MyQuestionBank
- 问题管理:ProblemManagement
- 我的笔记:MyNotes
QuestionBankCenterPage.py:
import timefrom selenium.webdriver.common.by import Byfrom common.Untils import QESDriverclass MyQuestionBank:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/repo/index"self.driver = QESDriver.driverself.driver.get(self.url)def GetMyQuestionBank(self):# 查找输入框并输入“1”self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("1")# 查找“查询”并点击self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[3]/div/div/div[2]/div/div/div/div/div/div[2]/button').click()time.sleep(0.5)QESDriver.GetScreenShot()# 查找“重置”并点击self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[3]/div/div/div[2]/div/div/div/div/div/div[1]/button').click()# 新建题库def CreateNewQuestionBank(self):self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[1]/div/div[2]/div[1]/div/div[1]/button').click()# 查找输入“题库名称”self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("自动化测试新建题库")# 查找输入“题库分类”self.driver.find_element(By.XPATH,'//*[@id="category"]').send_keys("自动化")# 查找输入“题库描述”self.driver.find_element(By.XPATH,'//*[@id="description"]').send_keys("自动化")QESDriver.GetScreenShot()# 返回self.driver.back()# 试题管理def TestManagement(self):# 试题管理self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[2]/td[9]/div/div[3]/a').click()QESDriver.GetScreenShot()# 添加试题# self.driver.find_element(By.XPATH,'/html/body/div[5]/div/div[3]/div/div/div[2]/div/div[2]/div/div[1]/div/div[2]/div[1]/div/div/button').click()# time.sleep(0.5)# QESDriver.GetScreenShot()# # 关闭添加试题页面# self.driver.find_element(By.XPATH,'//*[@id="editor"]/div[2]/div[1]/div[2]/div/button[1]').click()# # 关闭试题管理# self.driver.find_element(By.XPATH, '/html/body/div[8]/div/div[3]/div/div/div[1]/div[2]/div/div/button').click()class ProblemManagement:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/repo/template"self.driver = QESDriver.driverself.driver.get(self.url)def GetProblemManagement(self):QESDriver.GetScreenShot()# 点击展开self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[5]/div/div/div[2]/div/div/div/div[2]/a').click()# 输入“单选”并搜索self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("单选")time.sleep(0.5)QESDriver.GetScreenShot()# 点击“重置”并点击“编辑”self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[5]/div/div/div[2]/div/div/div/div[1]/div/div[1]/button').click()self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[2]/td[10]/div/div/a').click()time.sleep(0.5)QESDriver.GetScreenShot()# 退出编辑self.driver.find_element(By.XPATH,'//*[@id="editor"]/div[1]/div[1]/div[2]/div/button[1]').click()# 我的笔记 class MyNotes:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/repo/book"self.driver = QESDriver.driverself.driver.get(self.url)def GetMyNotes(self):# 查找输入框并输入“一”“1”self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("一")# 点击展开self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[4]/div/div/div[2]/div/div/div/div[2]/a').click()self.driver.find_element(By.XPATH,'//*[@id="note"]').send_keys("1")# 点击查询self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[4]/div/div/div[2]/div/div/div/div[1]/div/div[2]/button').click()time.sleep(0.5)QESDriver.GetScreenShot()# 点击重置并点击删除self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[4]/div/div/div[2]/div/div/div/div[1]/div/div[1]/button').click()self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[1]/td[5]/div/div/a').click()# 出现二次确认截图并返回# self.driver.switch_to.alert.accept()# self.driver.find_element(By.XPATH,'/html/body/div[6]/div/div[2]/div/div[2]/div/div/div[2]/button[2]').click()time.sleep(0.5)QESDriver.GetScreenShot()self.driver.refresh()
6.3.7 模板广场
模板广场对元素的查找、添加模板、以及搜索模板的自动化测试:
TemplateSquarePage.py:
import timefrom selenium.webdriver.common.by import Byfrom common.Untils import QESDriverclass TemplateSquare:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/template"self.driver = QESDriver.driverself.driver.get(self.url)def GetTemplateSquare(self):# 查找页面元素title = self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[1]/div/span').textassert title == "模板广场"# 添加模板self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[1]/span/div/div/button').click()time.sleep(0.5)QESDriver.GetScreenShot()# 关闭添加模板self.driver.find_element(By.XPATH,'//*[@id="editor"]/div[2]/div[1]/div[2]/div/button[1]').click()# 公共库self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[3]/div/div[1]/div[1]/div/div[1]').click()# 私有库self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[3]/div/div[1]/div[1]/div/div[2]').click()# 分类选择self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/div/form/div[1]/div[2]/div/div/div/div/div/div/span[1]').click()self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/div/form/div[1]/div[2]/div/div/div/div/div/div/span[2]').click()self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/div/form/div[1]/div[2]/div/div/div/div/div/div/span[3]').click()# 搜索模板self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[2]/div/div/div/div/div/span/span/input').send_keys("测试")self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[1]/div[2]/div/div/div/div/div/span/span/span/button').click()time.sleep(0.5)QESDriver.GetScreenShot()
6.3.8 系统管理
系统管理这里分为6个模块,根据不同的模块分别设计对应的类对象进行自动化测试:
- 用户管理:UserManagement
- 角色管理:RoleManagement
- 组织机构:InstitutionalFramework
- 岗位设置:PostSetting
- 字典管理:Dictionarization
- 个人设置:PersonalSettings
SystemManagementPage.py:
import timefrom selenium.webdriver.common.by import Byfrom common.Untils import QESDriver# 用户管理 class UserManagement:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/system/user"self.driver = QESDriver.driverself.driver.get(self.url)def GetUserManagement(self):# 筛选机构self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[3]/div/div/div/div/span[4]/span[2]').click()time.sleep(0.5)QESDriver.GetScreenShot()self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/div/div[2]/div/div[3]/div/div/div/div/span[4]/span[2]').click()# 按照姓名搜索self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("张三")# 点击搜索self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/button').click()time.sleep(0.5)# 截图查看QESDriver.GetScreenShot()# 点击重置self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[1]/button').click()################################################################def CreateNewUsers(self):# 新建self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div[1]/div/div[2]/div[1]/div/div[1]/button').click()# 输入用户名:测试新建用户self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("测试新建用户")# 输入登录名:hellobitself.driver.find_element(By.XPATH,'//*[@id="username"]').send_keys("hellobit")# 输入密码:123456self.driver.find_element(By.XPATH,'//*[@id="password"]').send_keys("123456")# 输入确认密码:123456self.driver.find_element(By.XPATH,'//*[@id="rePassword"]').send_keys("123456")QESDriver.GetScreenShot()# 点击确定# self.driver.find_element(By.XPATH,'/html/body/div[7]/div/div[3]/div/div/div[3]/div/div/div[2]/button').click()self.driver.refresh()# 批量导入self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div[1]/div/div[2]/div[1]/div/div[2]/button').click()time.sleep(0.5)QESDriver.GetScreenShot()# self.driver.find_element(By.XPATH,'/html/body/div[6]/div/div[2]/div/div[2]/div[3]/button[1]').click()self.driver.refresh()# 编辑用户self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[2]/td[8]/div/div[1]/a').click()time.sleep(0.5)QESDriver.GetScreenShot()# self.driver.find_element(By.XPATH, '/html/body/div[7]/div/div[3]/div/div/div[3]/div/div/div[1]/button').click()self.driver.refresh()# 角色管理 class RoleManagement:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/system/role"self.driver = QESDriver.driverself.driver.get(self.url)def GetRoleManagement(self):# 查询self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("user")self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/button').click()time.sleep(0.5)self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[1]/button').click()# 新建self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[1]/div/div[2]/div[1]/div/div/button').click()# 输入角色信息self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("test")# 输入角色编码self.driver.find_element(By.XPATH,'//*[@id="code"]').send_keys("745300")# 输入描述self.driver.find_element(By.XPATH,'//*[@id="remark"]').send_keys("测试新建角色")QESDriver.GetScreenShot()self.driver.refresh()# 编辑角色self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[2]/td[6]/div/div[1]/a').click()time.sleep(0.5)QESDriver.GetScreenShot()self.driver.refresh()# 组织机构 class InstitutionalFramework:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/system/dept"self.driver = QESDriver.driverself.driver.get(self.url)def GetInstitutionalFramework(self):# 新建操作self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div/div/div/div[1]/div/div[2]/div[1]/div/div/button').click()QESDriver.GetScreenShot()self.driver.refresh()# 编辑操作self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div/div/div/div[2]/div/div/div/div/div/table/tbody/tr[2]/td[4]/div/div[1]/a').click()QESDriver.GetScreenShot()self.driver.refresh()# 岗位设置 class PostSetting:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/system/position"self.driver = QESDriver.driverself.driver.get(self.url)def GetPostSetting(self):# 输入查询self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("aaa")self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/button').click()time.sleep(0.5)QESDriver.GetScreenShot()self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[1]/button').click()# 新建岗位self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[1]/div/div[2]/div[1]/div/div/button').click()# 输入岗位名称self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("测试新建岗位")# 输入岗位编码self.driver.find_element(By.XPATH,'//*[@id="code"]').send_keys("745300")self.driver.refresh()# 编辑岗位self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[2]/td[4]/div/div[1]/a').click()QESDriver.GetScreenShot()self.driver.refresh()# 删除岗位self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[2]/td[4]/div/div[2]/a').click()time.sleep(0.5)self.driver.refresh()# 字典设置 class Dictionarization:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/system/dict"self.driver = QESDriver.driverself.driver.get(self.url)def GetDictionarization(self):# 输入查询self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("aaa")self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/button').click()time.sleep(0.5)QESDriver.GetScreenShot()self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[1]/form/div/div[2]/div/div/div[2]/div/div/div/div/div/div[1]/button').click()# 新建字典self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[1]/div/div[2]/div[1]/div/div/button').click()# 输入字典名称self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("cccc")# 输入字典编码self.driver.find_element(By.XPATH,'//*[@id="code"]').send_keys("745300")QESDriver.GetScreenShot()self.driver.refresh()# 字典项self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div[2]/div/div/div/div[2]/div/div[2]/div/div/div/div/div/table/tbody/tr[2]/td[6]/div/div[1]/a').click()QESDriver.GetScreenShot()self.driver.refresh()# 个人设置 class PersonalSettings:url = ""driver = ""def __init__(self):self.url = "http://8.155.1.153:8081/system/setting"self.driver = QESDriver.driverself.driver.get(self.url)def GetPersonalSettings(self):# 清空原有的姓名QESDriver.ClearInput(self.driver.find_element(By.XPATH,'//*[@id="name"]'))# 输入新的self.driver.find_element(By.XPATH,'//*[@id="name"]').send_keys("小小王")# 查找输入手机号self.driver.find_element(By.XPATH,'//*[@id="phone"]').send_keys("19290061455")# 查找输入邮箱self.driver.find_element(By.XPATH,'//*[@id="email"]').send_keys("3446066695@qq.com")# 查找输入个人简介self.driver.find_element(By.XPATH,'//*[@id="profile"]').send_keys("无个人简介")QESDriver.GetScreenShot()# 点击提交self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div/div/div[2]/div[2]/div[1]/form/div[5]/div[2]/button').click()# 点击安全设置self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div/div/div[1]/ul/li[2]/span').click()QESDriver.GetScreenShot()# 点击系统设置self.driver.find_element(By.XPATH,'//*[@id="sk-layout"]/div/div/section/div[2]/main/div/div/div/div[1]/ul/li[3]/span').click()QESDriver.GetScreenShot()
6.3.9 运行模块
该模块是将前面的所以核心功能的运行整合在一起,将所有的文件引入然后一起执行:
RunTest.py:
from common.Untils import QESDriverfrom RegistrationPage import RegPage from LoginPage import LoginPage from HomePage import HomePage from MyProjectPage import MyProject from MyPracticePage import MyPractice from QuestionBankCenterPage import MyQuestionBank from QuestionBankCenterPage import ProblemManagement from QuestionBankCenterPage import MyNotes from TemplateSquarePage import TemplateSquare from SystemManagementPage import UserManagement from SystemManagementPage import RoleManagement from SystemManagementPage import InstitutionalFramework from SystemManagementPage import Dictionarization from SystemManagementPage import PersonalSettings if __name__ == "__main__":# 注册RegPage().GetRegPage()############################################### 登录LoginPage().GetLoginPage()##################################################### 首页HomePage().GetHomePage()# 首页--创建问卷HomePage().HP_CreateQuestionnaire()# 首页--创建考试HomePage().HP_CreateExaminations()##################################################################### 我的项目MyProject().GetMyProject()######################################################################### 我的练习MyPractice().GetMyPractice()# 我的练习--数学MyPractice().MathExercise()# 我的练习--数学--顺序练习# MyPractice().PracticeInSequence()# 我的练习--语文MyPractice().ChineseExercises()####################################################################MyQuestionBank().GetMyQuestionBank()# 题库中心--我的题库--新建题库MyQuestionBank().CreateNewQuestionBank()# 题库中心--我的题库--试题管理MyQuestionBank().TestManagement()# 题库中心--问题管理ProblemManagement().GetProblemManagement()# 题库中心--我的笔记MyNotes().GetMyNotes()##################################################################### 模板广场TemplateSquare().GetTemplateSquare()##################################################################### 系统管理--用户管理UserManagement().GetUserManagement()# 系统管理--用户管理--新建用户UserManagement().CreateNewUsers()# 系统管理--角色管理RoleManagement().GetRoleManagement()# 系统管理--岗位设置InstitutionalFramework().GetInstitutionalFramework()# 系统管理--字典管理Dictionarization().GetDictionarization()# # 系统管理--个人设置PersonalSettings().GetPersonalSettings()# 关闭浏览器QESDriver.driver.quit()
7. 兼容性测试
本次兼容性测试用到的场景有:
- Edge 版本 138.0.3351.121 (正式版本) (64 位)
- Chrome 版本 138.0.7204.184(正式版本) (64 位)
- IOS 18.5系统
PC端:
场景一:在Chrome浏览器下运行
预期结果:布局正常、可以正常运行且无加载异常各项功能都完整
场景二:在Edge浏览器下运行
预期结果:可以正常运行、页面布局合理、加载正常、功能完善
移动端:
场景三:在IOS系统下运行
预期结果:正常运行、页面布局合理、功能正常
8. 性能测试
本次性能测试主要用到的工具有JMeter与Postman,对问卷考试系统进行性能评估:
- Postman配置
- 根据不同的接口先使用Postman发送请求;
- 设置对应的请求头信息;
- 查看状态码、请求头、请求体、响应头;
JMeter配置- 创建新的测试计划(Test Plan)
- 添加线程组(Thread Group)模拟并发用户
- 为每个测试页面配置HTTP请求采样器(HTTP Request Sampler)
- 添加监听器(View Results Tree, Summary Report等)收集测试结果
8.1 单一性能接口测试
8.1.1 系统登录页面
① 首先通过浏览器的开发者工具找到系统登录页面的接口:
② 在Postman上进行对应接口的请求,因为这里没有请求头信息,所以我们不用配置:
③ 使用JMeter发起请求:
首先创建HTTP请求默认值,把协议类型、ip、端口填写,后面的接口只需要拼接路径即可;
然后创建HTTP请求对系统登录页面发起请求:
点击运行之后可以再查看结果树中找到对应的请求情况:
响应体:
请求体:
请求头:
响应头:
8.1.2 登录接口
① 首先通过浏览器的开发者工具找到登录的接口:
② 使用Postman配置请求头信息发起请求:
先找到请求头需要配置的信息:
我们可以直接复制粘贴到Postman会自动生成请求头信息,也可以手动输入:
③ 使用JMeter发起请求:
因为需要配置请求头信息,所以我们新建一个HTTP请求,先手动添加请求头信息再发起请求:
请求体信息是一个json串,所以需要配置请求头的类型:
请求体:
请求头:
响应体:
响应头:
8.1.3 我的项目
① 通过浏览器找到我的项目的接口,然后复制url
② 使用Postman发送请求:
③ 使用JMeter发送请求:
在使用JMeter是,需要配置相关的登录cookie信息:
请求体:
请求头:
响应体:
响应头:
8.1.4 我的练习
① 在浏览器查找我的练习接口:
② 在Postman上发起请求:
③ 在JMeter上发起请求:
因为我们在测试我的项目时已经添加了HTTP请求头管理器,里面配置了cookie信息,是可以作用于整个测试的线程组中的,所以在我的练习这里不用再配置了:
请求体:
请求头:
响应体:
响应头:
8.1.5 题库中心--我的题库
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.6 题库中心--问题管理
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.7 题库中心--我的笔记
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.8 模板广场
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.9 系统设置--用户管理
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.10 系统设置--角色管理
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.11 系统设置--组织机构
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.12 系统设置--岗位设置
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.13 系统设置--字典管理
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.1.14 系统设置--个人设置
① 在浏览器查找对应的接口信息:
② 使用Postman发送请求:
③ 使用JMeter发送请求:
请求体:
请求头:
响应体:
响应头:
8.2 聚合报告
在214秒内请求了26115次;
导出的表格数据:
Label # 样本 平均值 中位数 90% 百分位 95% 百分位 99% 百分位 最小值 最大值 异常 % 吞吐量 接收 KB/sec 发送 KB/sec 系统登录页面 1895 240 192 431 524 1129 63 2236 0.00% 8.8599 7.56 4.62 登录接口 1891 840 880 1219 1331 1811 119 2921 0.00% 8.8407 7.26 6.66 我的项目 1874 255 233 468 532 712 35 2329 0.00% 8.79181 3.78 4.83 我的练习 1871 213 176 412 495 681 36 2437 0.00% 8.77765 8.27 4.95 题库中心--我的题库 1868 207 172 396 475 673 35 3139 0.00% 8.7607 8.26 4.78 题库中心--问题管理 1866 182 151 369 432 584 34 2145 0.00% 8.75087 3.76 4.81 题库中心--我的笔记 1865 186 155 376 429 566 33 4176 0.00% 8.74601 3.76 4.88 模板广场 1862 188 152 366 435 631 35 2316 0.00% 8.72912 6.3 5.05 系统设置--用户管理 1860 397 351 660 789 1205 76 7922 0.00% 8.69411 129.11 4.81 系统管理--角色管理 1856 224 185 429 521 878 34 2310 0.00% 8.69687 27.86 4.8 系统管理--组织机构 1855 179 144 363 438 582 32 2374 0.00% 8.70136 4.84 4.62 系统管理--字典管理 1853 182 147 360 437 578 33 3333 0.00% 8.69765 5.63 4.81 系统管理--岗位设置 1851 187 151 375 440 599 33 3423 0.00% 8.6754 4.68 4.82 系统管理--个人设置 1848 189 143 372 464 824 32 2722 0.00% 8.67573 13.81 4.57 总体 26115 263 192 522 821 1212 32 7922 0.00% 121.79765 234.05 68.65
8.3 吞吐量(Transactions per Second)
8.4 响应时间(Response Times Over Time)
8.5 随时间变化的活跃线程状态(Active Threads Over Time)
8.6 性能测试报告
① 生成性能测试报告:
jmeter -n -t 问卷考试系统.jmx -l first.jtl -e -o ./first/.
生成完成之后会在first文件下有一个index.html文件,点击之后就可以查看测试报告了:
8.6.1 Dashboard
8.6.2 Charts
Over Time:
Throughput:
Response Time:
9. 发现的BUG
9.1 功能异常
注册页面:
- 打开大小写输入框不会有提示;
- 在注册账号时登录账号设置为空格依然可以注册成功(没有对特殊符号进行处理);
登录页面:
- 使用为空格的用户名依旧可以登录成功(没有对特殊符号进行处理);
首页:
- 创建问卷之后,创建好的问卷并没有在“我的问卷”进行显示,只有问卷数的变化;
- 创建考试之后,创建好的考试并没有在“我的考试”进行显示,只有考试数的变化;
题库中心--我的题库:
- 点击导出并无任何反应:
模板广场:
- 在通过输入的关键字搜索模板时,并不能根据关键字检索出对应的模板;
系统管理--个人设置:
- 再修改用户密码之后,点击修改,会提示修改成功,但是再次点击修改之后,上一次的输入并没有清除,存在密码暴露风险:
- 修改的新密码与就密码相同时,依旧可以修改成功:
- 对密码框也没有特殊字符的限制,密码可以设置为空格
9.2 兼容性异常
兼容性测试:
移动端:
- 在IOS系统下的首页没有便捷导航栏;
- 在IOS系统下无题库中心;
- 在IOS系统下无模板广场;
9.3 接口异常
- 接口测试:
- 模板广场页面的接口请求失败;
10. 测试总结
10.1 项目功能完整性
整体上来说,该项目的核心功能均已完成,但是存在一些细节的问题:比如注册账号的账号以及用户名都可以是空格;开启大小写之后没有提示。
另外存在一些较严重的问题:比如搜索引擎搜索时与输入的关键字不匹配;修改密码时存在安全隐患。
10.2 接口性能数据
性能测试采用的是梯度压测模式,线程数在214秒内总共发起了26115次请求,请求成功率为100%,平均向每个接口发起了1860次请求;
- 登录接口的响应时间最长(829.82ms),组织机构接口响应时间最短(179.00ms);
- 平均吞吐量在121.39次/s,系统登录页面最高(8.82次/s),个人设置最低(8.63次/s);
- 发送数据量在242.45KB/s,用户管理页面最高(129.17KB/s),我的笔记页面最低(3.75KB/s);
附录
注册页面测试用例
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.xmind
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.xmind
登录页面测试用例
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2.xmind
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2.xmind
整体系统测试用例
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F.xmind
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F.xmind
自动化测试用例
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B.xmind
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B.xmind
自动化测试脚本
https://gitee.com/yue-sir-bit/questionnaire-exam/tree/master/Questionnaire_examination_system
https://gitee.com/yue-sir-bit/questionnaire-exam/tree/master/Questionnaire_examination_system
JMeter性能测试文件
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F.jmx
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/%E9%97%AE%E5%8D%B7%E8%80%83%E8%AF%95%E7%B3%BB%E7%BB%9F.jmx
性能测试报告
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/index.html
https://gitee.com/yue-sir-bit/questionnaire-exam/blob/master/index.html