【连珠云弈】网页五子棋版项目测试报告

ops/2025/3/9 9:55:42/

目录

一、项目背景

1.1、项目起源

1.2、市场需求

1.3、项目目标

二、项目功能

2.1 用户管理功能

2.2 游戏对战功能

三、测试报告

3.1.功能测试

​编辑

3.1.1注册功能测试

解决bug:

测试总结:

3.1.2登录功能测试

测试总结:

3.1.3.匹配和落子测试

3.2.界面测试

bug:

测试总结

3.3.性能测试​编辑

总体测试框架:

3.3.1.利用BeanShell解决乱码问题

3.3.2.添加保存cookie信息

3.3.3.添加CSV格式的用户信息

3.3.4.添加同步定时器

3.3.5.创建梯度压测线程组

3.3.6.生成测试报告

TIP:

3.4.自动化测试

3.4.1.测试框架:

3.4.2.utils工具类的实现

3.4.3.注册界面自动化测试

3.4.4.登录界面自动化测试

3.4.5.游戏大厅界面自动化测试

3.4.6.集成测试:

3.4.7.测试总结:

自动化测试盲点难点解决方法:

1.注意弹窗只能是用强制等待或者是显示等待!、

2.隐式等待为什么要写在utils文件中,不能写在后面的文件里面吗

四.总结:

一、项目背景

1.1、项目起源

随着互联网的飞速发展和普及,网络娱乐方式日益多样化。五子棋作为一种传统而经典的棋类游戏,深受广大棋迷的喜爱。然而,传统的五子棋游戏方式往往受限于地点和时间,无法满足人们随时随地进行游戏的需求。因此,开发一款网页版五子棋项目,旨在打破这种限制,让棋迷们能够随时随地通过网络享受五子棋的乐趣。

1.2、市场需求

  1. 便捷性需求:现代人生活节奏加快,对于娱乐方式的需求也更加注重便捷性。网页版五子棋无需下载和安装,只需打开浏览器即可进行游戏,极大地方便了用户。

  2. 社交性需求:网络游戏的社交属性日益凸显,玩家们不仅追求游戏本身的乐趣,还希望在游戏中结交新朋友。网页版五子棋可以提供在线对战功能,满足玩家的社交需求。

  3. 普及性需求:五子棋作为一种传统文化,其普及和传承具有重要意义。网页版五子棋项目的开发,有助于将这一传统文化以更现代化的方式呈现给更多人,推动五子棋的普及和发展。

1.3、项目目标

  1. 开发一款易用的网页版五子棋游戏:游戏界面简洁明了,操作方便快捷,让玩家能够轻松上手并享受游戏乐趣。

  2. 实现在线对战功能:支持玩家在线匹配对手,进行实时对战,增强游戏的互动性和趣味性。

  3. 优化游戏性能和用户体验:通过不断优化游戏算法和界面设计,提高游戏的运行速度和稳定性,为玩家提供更加流畅、舒适的游戏体验。

二、项目功能

2.1 用户管理功能

用户注册与登录:用户可以通过注册页面注册账号,填写用户名、密码等信息进行注册,注册成功后可在登录页面输入账号密码登录。

用户信息管理:系统能够记录用户的相关信息,如用户id、用户名、密码、天梯分数、排位总场次和胜场总场次等,并提供修改密码、查看个人信息等功能。

用户状态管理:通过session管理模块实现用户登录状态的维护,使用户在游戏过程中保持登录状态,直到用户主动退出或超时自动退出。

2.2 游戏对战功能

匹配对战:系统根据用户的天梯分数等信息进行匹配,为玩家找到合适的对手,进入游戏房间进行对战。

实时对战:在游戏房间内,玩家可以进行实时的五子棋对战,双方轮流落子,通过点击棋盘上的空位放置棋子。

胜负判断:系统能够实时检测当前落子位置在横、纵、斜四个方向是否有连续五个相同的棋子,以判断胜负。

三、测试报告

全部的测试用例

3.1.功能测试

3.1.1注册功能测试

注册已经存在的用户:

与预期结果一致,注册失败!并显示用户名以及被占用。

输入的账号或密码超出规定的长度范围:

drop database if exists gobang;
create database if not exists gobang;
use gobang;
create table if not exists user(id int primary key auto_increment,username varchar(32) unique key not null,password varchar(128) not null,score int,total_count int,win_count int
);

根据MySQL定义的数据表中账号的最多长度是32位,而密码是128位,当我输入的账号超出32位时,系统就会报错,与预期结果一致!

异常注册的情况:

账号为空时:

跟预期结果一致,注册失败!

密码为空时:

我们发现当密码为空时居然注册成功了!这明显跟我们预期不符合的,并且我们之前在定义数据表的时候,password明显是有not null属性的,这是为什么呢?!

账号密码都为空时

我勒个豆,竟然也注册成功了!但是我们已经注册账号为空的时候,下一次再注册账号为空会有用户名已经存在的现象。

解决bug:


问题是在于前端给后端传的数据是 空字符串, jsonvalue的 isNull函数判断有点问题。目前是把条件修改了,判断前端传递过来的是不是一个空串。  这个是后端在处理的时候,提前就要判断处理掉的。

有一个疑问是密码为什么是空,数据库还能插入成功。  

是因为前端给后端的是一个空字符串, 并且密码经过md5加密后,并不为空,所以插入是没问题的。  
其次是name为何不写,也能注册成功。是因为不写,向后端传的是空字符串,而不是null

所以,第一个要解决的是,我们用户不写用户名和密码的时候,后端要及时能够检测出来。所以修改了判断条件,得以解决。  第二个疑问是为何不写,sql语句还能执行成功,是由于 空字符串 和 null是有区别的!

当我们在数据库中插入空字符串的账号和密码的时候,插入成功!这也就验证了空字符串和null的区别,也解释了之前账号和密码为空的时候能注册成功的原因。

当我们更改判断条件之后,再来用空账号,密码注册一下(此时已经将数据库中的空账号的用户删除了)

此时,就不能用空账号进行注册了!bug解决完毕!

正常注册:

发现成功跳转到登录页面

与预期结果一致!

测试总结:

通过对注册页面的界面测试和功能测试,得出以下结论:

注册页面的背景图片显示正常,页面中的文字样式,和注册框均能正常显示。除此之外,注册框中的字样、输入框和“提交”按钮也能够正常显示。

正常注册情况,在注册一个并没有注册过的用户名时,可以正常注册成功,并且页面会提示用户“注册成功!
当注册已经注册过的用户时,页面会显示用户名被占用,让用户重新注册!

但是当密码为空时,用户也注册成功了!发现了这个bug。

3.1.2登录功能测试

正确的用户名和密码登录:

登录成功,与预期结果一致!并且账号和密码都能复制粘贴,密码也是隐藏了

异常的用户名和密码登录:

界面会显示用户名密码错误,与预期结果一致!

当跳过登录界面,直接进入游戏房间

预期:找不到用户信息,请重新登录,并跳转到登录界面

测试总结:

通过对登录页面的界面测试和功能测试,得出以下结论:

登录页面的背景图片显示正常,页面中的文字样式,和登录框均能正常显示。

建议:

但当登录失败时,可以具体向用户展示到底是账号错误还是密码错误,便于用户修改

3.1.3.匹配和落子测试

这里匹配和落子测试和界面一起测试

3.2.界面测试

bug:

当用户名字很长的时候 界面就会出现这种重回覆盖的情况

解决措施:
用户名过长最少有两种方式,第一种就是直接截取,比如你的用户名有19位,我只展示10位就行了。剩下的不展示
第二种就是,19位,只展示一部分,当鼠标放上去之后,展示完整的用户名

这里实现了第二种
 

测试总结

通过测试游戏大厅页面的界面显示和匹配功能,得出以下结论:

游戏大厅页面的左上角“五子棋对战”字样正常显示,背景图片正常显示

玩家信息(用户名、分数、比赛场次、获胜场次)正常显示,

匹配功能正常,两个同级别玩家点击匹配按钮后,会匹配在一起。

并且当有一方五星连珠时,界面会显示游戏胜利/失败

通过对游戏大厅页面的界面测试和功能测试,并未在游戏大厅页面发现bug。

3.3.性能测试

下面我来使用 JMeter 对五子棋项目的登录接口和获取用户信息接口进行简单的性能测试,下面就来介绍五子棋项目性能测试的一个测试流程。

总体测试框架:

3.3.1.利用BeanShell解决乱码问题

3.3.2.添加保存cookie信息

因为用户在登录之后,我们需要从info接口读取消息,所以需要自动保存用户登录的cookie信息

这里直接选择standard即可

3.3.3.添加CSV格式的用户信息

我们为了更加真实的模拟用户登录场景,我们在CSV文件中添加了用户信息以供模拟真实的用户登录场景。

下面的是配置,用username和password表示账号密码,后续直接在body中引用即可。

如下面的登录接口就调用了CSV文件中的账号和密码。

3.3.4.添加同步定时器

我们为了保证线程是并发执行的,我们添加了同步定时器。

3.3.5.创建梯度压测线程组

这里我们创建一个梯度压测线程组(Stepping Thread Group),来慢慢增大我们对这两个接口的并发请求的数量,以达到性能测试的目的。

3.3.6.生成测试报告

我们发现有一小部分测试用例出现的bug,进行具体分析:

发现都是网络超时,这跟网络情况相关,或者我的服务器稳定性比较差~

TIP:

JMeter从CSV读取数据并不只适用于数据存放在URL参数里面。

  1. 不仅限于URL参数:虽然CSV数据常用于URL参数化,但JMeter也支持将CSV中的数据用于其他类型的请求参数,如POST请求的body、请求头等。

我们现在做的就是将数据存放在body中。

3.4.自动化测试

3.4.1.测试框架:

在common这个软件包中主要存放的是utils这个工具类,这个工具类里面具体实现了创建浏览器对象和截图工具,避免每次测试都需要写一份工具,避免了代码的冗余。

在images这个文件夹中存放的是每次截图生成的图片,并且以天为单位生成小的文件夹,每份文件夹又有用时间进行格式化和生成该图片的类名。

在tests这个软件包中存放的是各个页面的自动化测试代码,并且RunTest文件进行总体的一个测试。

3.4.2.utils工具类的实现

import os
import sys
import datetimefrom selenium import webdriver
from selenium.webdriver.ie.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)def getScreeShot(self):# 创建屏幕截图# 图片文件名称:./2024-05-08-173456.pngdirname = datetime.datetime.now().strftime("%Y-%m-%d")# 判断dirname文件夹是否已经存在,若不存在则创建文件夹# ../images/2024-05-08if not os.path.exists("../images/" + dirname):os.mkdir("../images/" + dirname)# 2024-05-08-173456.png# 图片路径:../images/调用方法-2024-05-08/2024-05-08-173456.png# 图片路径:../images/LoginSucTest-2024-05-08/2024-05-08-173456.png# 图片路径:../images/LoginFailTest-2024-05-08/2024-05-08-173456.pngfilename = 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()

其中截图的工具类别出心裁:

  1. sys._getframe().f_back.f_code.co_name
    通过调用栈获取调用该代码的函数名,作为文件名的一部分。这样可以动态地根据函数名为截图命名。

  2. datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S")
    获取当前时间,并将其格式化为“年-月-日-时分秒”的形式,作为文件名中的时间戳部分。

  3. filename
    将函数名和时间戳拼接成一个完整的文件名,后缀为“.png”。

  4. self.driver.save_screenshot("../images/" + dirname + "/" + filename)
    使用 Selenium 的 save_screenshot 方法,将当前浏览器窗口的截图保存到指定路径中。路径由 ../images/dirname(某个子目录名)以及生成的文件名组成。

3.4.3.注册界面自动化测试

代码:

#测试注册界面
import time
from distutils.command.register import registerfrom selenium.webdriver.common.by import Byfrom common.Utils import BlogDriverclass GobangRegister:url = ""driver = ""def __init__(self):self.url = "http://123.249.125.60:8085/register.html"self.driver = BlogDriver.driverself.driver.get(self.url)#成功注册的测试用例def RegisterSucTest(self):self.driver.find_element(By.CSS_SELECTOR,"#user_name").send_keys("lisi9")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()#强制等待time.sleep(3)#此时需要点击弹窗里面的确定,才能跳转页面alert = self.driver.switch_to.alertalert.accept()#能够找到登录界面中的登录二字,说明注册成功,否则注册失败self.driver.find_element(By.CSS_SELECTOR,"body > div.login-container > div > h3")#异常注册的测试用例def RegisterFailTest(self):#若连续多次的send_keys会出现关键词的拼接,而不是替换。若要替换需要先clearself.driver.find_element(By.CSS_SELECTOR,"#user_name").clear()self.driver.find_element(By.CSS_SELECTOR,"#password").clear()self.driver.find_element(By.CSS_SELECTOR,"#user_name").send_keys("lisi")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(3)#self.driver.quit()_register = GobangRegister()
_register.RegisterSucTest()
#_register.RegisterFailTest()

3.4.4.登录界面自动化测试

#测试登录页面
import timefrom common.Utils import BlogDriver
from selenium.webdriver.common.by import Byclass GobangLogin:url = ''driver = ''def __init__(self):self.url = "http://123.249.125.60:8085/login.html"self.driver = BlogDriver.driverself.driver.get(self.url)#登录失败的测试用例def LoginFailTest(self):#隐式等待#self.driver.implicitly_wait(3)self.driver.find_element(By.CSS_SELECTOR,'#user_name').send_keys('lisi8')self.driver.find_element(By.CSS_SELECTOR,'#password').send_keys('123456')self.driver.find_element(By.CSS_SELECTOR,'#submit').click()time.sleep(3)#此时需要点击弹窗里面的确定,才能跳转页面alert = self.driver.switch_to.alertalert.accept()time.sleep(3)#成功登录的测试用例def LoginSucTest(self):self.driver.find_element(By.CSS_SELECTOR,'#user_name').send_keys('lisi')self.driver.find_element(By.CSS_SELECTOR,'#password').send_keys('123456')self.driver.find_element(By.CSS_SELECTOR,'#submit').click()time.sleep(3)#此时需要点击弹窗里面的确定,才能跳转页面alert = self.driver.switch_to.alertalert.accept()time.sleep(3)# self.driver.find_element(By.CSS_SELECTOR,'#match-button')# #截图# BlogDriver.getScreeShot()# #self.driver.quit()# #强制等待# time.sleep(3)# #此时需要点击弹窗里面的确定,才能跳转页面# alert = self.driver.switch_to.alert# alert.accept()# time.sleep(3)#time.sleep(3)#此时需要点击弹窗里面的确定,才能跳转页面alert = self.driver.switch_to.alertalert.accept()time.sleep(3)# _login = GobangLogin()
# # _login.LoginFailTest()
# _login.LoginSucTest()

3.4.5.游戏大厅界面自动化测试

#测试游戏大厅页面
import timefrom common.Utils import BlogDriver
from selenium.webdriver.common.by import Byclass GobangHall:url = ' 'driver = ' 'def __init__(self):self.url = "http://123.249.125.60:8085/game_hall.html"self.driver = BlogDriver.driverself.driver.get(self.url)#测试游戏大厅匹配和停止匹配按钮def HallTest(self):time.sleep(3)#此时需要点击弹窗里面的确定,才能跳转页面alert = self.driver.switch_to.alertalert.accept()#点击开始匹配self.driver.find_element(By.CSS_SELECTOR,'#match-button').click()#点击停止匹配self.driver.find_element(By.CSS_SELECTOR,'#match-button').click()time.sleep(3)#重新匹配self.driver.find_element(By.CSS_SELECTOR,'#match-button').click()#截图BlogDriver.getScreeShot()

3.4.6.集成测试:

#from tests import GobangRegister
from tests import GobangLogin
from tests import GobangHall
from common.Utils import BlogDriverif __name__ == "__main__":#游戏注册页面#GobangRegister.GobangRegister().RegisterSucTest()#GobangLogin.GobangLogin().LoginFailTest()#登陆成功之后就可以调用博客首页测试首页的用例(登陆状态)#最终一定是登录状态GobangLogin.GobangLogin().LoginSucTest()#游戏大厅界面GobangHall.GobangHall().HallTest()#指定浏览器的退出BlogDriver.driver.quit()

3.4.7.测试总结:

 

如上图运行过程所示,我们的自动化测试用例全部通过,当我们执行失败的时候需要截图进行纠错。

自动化测试盲点难点解决方法:

1.注意弹窗只能是用强制等待或者是显示等待!、

为什么?

在Selenium自动化测试中,当遇到弹窗时,通常使用的等待方式主要是显式等待。这是因为弹窗的出现往往是由某些用户操作或页面事件触发的,而这些事件可能不是立即发生的,因此需要等待弹窗确实出现后再进行相应的操作。

注意在前面文件中不需要我们自己退出,我们只用在最后的RunTest一次退出即可,不然前面程序已经退出,将会运行失败

 

2.隐式等待为什么要写在utils文件中,不能写在后面的文件里面吗

解答:

#点击完成之后出现页面的跳转,页面跳转需要加载时间,可能会出现代码执行的速度比页面渲染的速度要快,导致元素查找不到,因此可以添加等待

#添加隐式等待和显示等待都可以,任选择一个

#隐式等待:创建浏览器对象之后就可以加上,因为隐式等待的作用域在driver整个生命周期

#显示等待:可以作用在当前代码中

四.总结:

我们一共进行了功能测试、自动化测试以及性能测试这三种测试方式,在功能测试阶段,我们着重点是测试玩家双方进行五子棋对弈时的过程;在自动化测试阶段,我们主要测试各个页面的相关信息,着重测试了登录与注册的功能;在性能测试阶段,我们着重测试了用户登录与获取用户信息的接口性能,并生成了性能测试报告。

在这期间,发现了不少bug,例如用户注册时,没有账号和密码也能注册成功;当用户的名称过长时,会对前端界面按钮造成覆盖等等。但最终都解决了,不得不说,测试真的很有意思~~~


http://www.ppmy.cn/ops/164338.html

相关文章

夏门大学DeepSeek 手册:从社会大众到高校及企业的全面应用实践研究(附 PDF 下载)

这 3 份手册分别从 DeepSeek 大模型概念、技术与应用实践、DeepSeek 大模型赋能高校教学和科研、DeepSeek 大模型及其企业应用实践-企业人员的大模型宝典几个角度进行全面分析,可以结合着清华、北大系列相互对照着学习。 清华北大推出的 DeepSeek 教程(…

【AI赋能】AI 工具生成视频教材:从创意到成品的全流程指南

AI 工具生成视频教材:从创意到成品的全流程指南 目标 通过本教材,您将学会如何利用 AI 工具(Grok、Sora、Speechify 和 CapCut)生成一个完整的视频,包括脚本生成、视频片段制作、字幕添加、音频生成以及最终剪辑合成…

syncthing多节点文件同步

服务安装 在官方地址 https://syncthing.net/downloads/ 下载对应平台的版本进行安装 文件同步至少要部署两个节点,然后在这两台设备上启动 syncthing 服务 在 ubuntu 下,生成的配置是在用户的 .local 目录下 /root/.local/state/syncthing 在 win10…

说一下redis事务底层原理

Redis事务 1. 事务的基本流程 Redis 事务通过 MULTI、EXEC、WATCH 等命令实现,底层原理可以分为以下几个步骤: (1) MULTI 命令 当客户端发送 MULTI 命令时,Redis 会将客户端标记为“事务模式”。在事务模式下,客户端发送的所有…

MySQL进阶-关联查询优化

采用左外连接 下面开始 EXPLAIN 分析 EXPLAIN SELECT SQL_NO_CACHE * FROM type LEFT JOIN book ON type.card book.card; 结论:type 有All ,代表着全表扫描,效率较差 添加索引优化 ALTER TABLE book ADD INDEX Y ( card); #【被驱动表】&#xff0…

【机械臂】Windows11下配置KINOVA GEN3机械臂的Python环境并运行

Windows11下配置KINOVA GEN3机械臂的Python环境并运行 一、开机前的准备 检查电源连接 确保机械臂的电源适配器已正确连接到机械臂的电源接口,并且另一端已连接到电源插座。将红色按钮按起来,而不是按下去,按下去是紧急停止。 检查安全事项…

(最新教程)Cursor Pro订阅升级开通教程,使用支付宝订阅Cursor Pro Plus

一、如何使用Cursor ? 目前要使用Cursor - The AI Code Editor,直接去下载安装就可以了,不过基础版只能用两周,如果需要继续使用,就要订阅pro plus或者企业版了。 二、如何订阅Cursor Pro Plus ? 因为基础…

淘宝母婴购物数据可视化分析(基于脱敏公开数据集)

一、前言 以下是“阿里天池”上的比赛介绍,数据集也是源自于那里的公开数据集,数据经过脱敏处理,避免了用户隐私问题。下面是数据集和任务的介绍: 二、数据导入与数据预处理 import pandas as pd # 导入交易信息表 trade_inf p…