ChatRoom测试报告
1.编写目的
本次测试主要针对ChatRoom项目,目的是对其进行全方位的测试。从功能性来看,它的主要功能包括登录、消息接收发送、搜索联系人、创建会话、以及是否能够正常显示消息的功能。同时,验证对于文件、音乐、视频等格式文件是否能够发送。在性能方面,测试不同用户数量下的响应时间、吞吐率和资源利用率以评估项目的性能。此外对于安全性,在登录时测试了用户输入是否隐藏、SQL注入、多次失败锁定等,保障用户隐私。
2.背景
2.1功能
ChatRoom项目主要分为登录页和聊天页。
(1)登录页:主要提供了用户登录以及用户输入密码隐藏的功能。这里没有设计注册的功能,只有数据库中存在的账号密码可以登录
(2)聊天页:主要提供搜索联系人、新建会话、历史会话以及发送消息的功能。
2.2测试环境
硬件:个人电脑
操作系统:Win11
浏览器:Edge(135.0.3179.54 (正式版本) (64 位))
项目运行环境:maven、JDK1.8
自动化测试环境:Selenium4.0、Python3.11
性能测试工具:Jmeter
3.测试概要
ChatRoom项目测试工作于2025年4月8日启动,2025年4月10日结束历时3天。设计了69条测试用例,自动化执行了40条用例。在测试过程中发现了6个Bug,其中有1个严重级别、3个一般级别、2个轻微级别。同时还有4条扩展建议。
3.1测试计划
功能 | 后端开发 | 前端开发 | 提测日期 | 测试 | 测试日期 | 测试结果 |
登录页面 | *** | *** | 4.8 | 金** | 4.8 | 测试成功 |
聊天页面 | *** | *** | 4.9 | 金** | 4.9 | 测试成功 |
3.2测试用例
4.功能测试
本项目功能测试实现100%自动化覆盖,并且根据测试用例中的安全测试也使用自动化的方式进行测试,根据设计的测试用例编写自动化脚本。
对于不同的页面各自编写脚本,有利于管理。并且使用Python的虚拟环境可以保证脚本的开发是独立的,避免污染并且能够减少文件体积。
4.1脚本文件结构
对于这个自动化脚本需要编写
(1)ChatRoomLoginTest.py测试登录界面
(2)ChatRoomTalkTest.py测试聊天界面
(3)LoginSafeTest,py测试安全性
(4)Utiles.py作为通用类给其他文件提供驱动对象和截图接口等等
(5)RunTest.py同一管理测试的开始
同时对于屏幕截图创建一个images文件夹存放截图,便于管理。
4.2Utiles.py通用工具
import datetime
import os.path
import sys
from selenium import webdriver
from selenium.webdriver.edge.service import Service as EdgeService
from webdriver_manager.microsoft import EdgeChromiumDriverManager
#创建浏览器对象
class Driver:
driver = ""
def __init__(self):
options = webdriver.EdgeOptions()
self.driver = webdriver.Edge(service=EdgeService(EdgeChromiumDriverManager().install()),options=options)
#增加屏幕截图
def GetScreenShoot(self):
#文件命名:调用的方法名称+2025-4-8-13:14'15''.png
#图片路径:../images/2025-4-8/2025-4-8-13:14:15.png
dirname = datetime.datetime.now().strftime("%Y-%m-%d") #格式化年月日
#判断当前文件夹是否存在,如果不存在就创建
if not os.path.exists("../images/"+dirname):
os.mkdir("../images/"+dirname)
#../images/2025-4-8
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)
ChatRoomDrive = Driver() #单例模式
4.3ChatRoomLoginTest.py登录界面
登录成功后会有弹窗提示,涉及到弹窗一般会添加显示等待确保弹窗加载完成。并且这里涉及到输入信息,在输入之前要clear掉输入框内的信息,避免信息不断叠加达不到测试效果。
#登录页面测试
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from Common.Utils import ChatRoomDrive
class ChatRoomLogin:
url = "" #每个类都要有自己的url
driver = ""
def __init__(self):
self.url = "http://127.0.0.1:8080/login.html"
self.driver = ChatRoomDrive.driver
self.driver.get(self.url)
#成功登录的测试用例
def LogSucTest(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("123")
# #检查密码是否隐藏,直接验证密码框的type属性是否为password
# type = self.driver.find_element(By.XPATH,'//*[@id="password"]').get_attribute("type")
# assert type == "password"
# #print(f"type:{type}")
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
#time.sleep(1)
#alert = self.driver.switch_to.alert
wait = WebDriverWait(self.driver,1)
alert = wait.until(EC.alert_is_present())
text_1 = alert.text
# print(f"text:{text}")
assert text_1 == "登录成功!"
alert.accept()
#time.sleep(1)
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,"body > div.client-container > div > div.left > div.user")))
#找到聊天界面的首页说明登录成功
self.driver.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.left > div.user")
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
self.driver.back()
#失败登陆的测试用例
def LogFailTest(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("1234")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
#alert = self.driver.switch_to.alert
wait = WebDriverWait(self.driver,1)
alert = wait.until(EC.alert_is_present())
text_2 = alert.text
assert text_2 == "登录失败!"
alert.accept()
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
#错误的账号和正常的密码
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("jinweixin")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
#alert = self.driver.switch_to.alert
alert = wait.until(EC.alert_is_present())
text_3 = alert.text
assert text_3 == "登录失败!"
alert.accept()
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
#错误的账号和错误的密码
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("jinweixin")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("1234")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
#alert = self.driver.switch_to.alert
alert = wait.until(EC.alert_is_present())
text_3 = alert.text
assert text_3 == "登录失败!"
alert.accept()
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
#空的账号和正确的密码
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("")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
#alert = self.driver.switch_to.alert
alert = wait.until(EC.alert_is_present())
text_4 = alert.text
assert text_4 == "当前输入的用户名或者密码为空!"
alert.accept()
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
#输入正确的账号和空的密码
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("")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
#alert = self.driver.switch_to.alert
alert = wait.until(EC.alert_is_present())
text_5 = alert.text
assert text_5 == "当前输入的用户名或者密码为空!"
alert.accept()
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
#输入空的账号和空的密码
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("")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
#alert = self.driver.switch_to.alert
alert = wait.until(EC.alert_is_present())
text_6 = alert.text
assert text_6 == "当前输入的用户名或者密码为空!"
alert.accept()
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
#输入的账号是中文字符
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("金维鑫")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
#alert = self.driver.switch_to.alert
alert = wait.until(EC.alert_is_present())
text_7 = alert.text
assert text_7 == "登录失败!"
alert.accept()
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
4.4ChatRoomTalkTest.py聊天界面
聊天页面有搜索框,对话框和发送消息框三个大元素,可以直接在这个测试中对这三个元素进行测试。
还有一种情况是用户不登陆直接访问聊天页面,此时会出现弹窗提请用户登录并且返回到登录页面。但是这个功能要在正常功能测试完毕之后再测试,避免测试时发生冲突。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from Common.Utils import ChatRoomDrive
class ChatRoomTalk:
url=""
driver=""
def __init__(self):
self.url="http://127.0.0.1:8080/client.html"
self.driver=ChatRoomDrive.driver
self.driver.get(self.url)
#登录状态下聊天页面
def LogTalkTest(self):
#用户名
#self.driver.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.left > div.user")
text_1 = self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.user").text
print(f"text_1:{text_1}")
assert text_1 == "zhangsan"
#搜索框
#1.输入完整信息
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").send_keys("lisi")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > button").click()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").clear()
#2.输入部分信息
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").send_keys("li")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > button").click()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").clear()
#3.输入含有特殊字符能否进行搜索
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").send_keys("@##$$!!~~%%^^&**")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > button").click()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").clear()
#4.中文格式下是否正常搜索
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").send_keys("李四")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > button").click()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").clear()
#5.不输入内容是否能正常搜索
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").send_keys("")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > button").click()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.search > input[type=text]").clear()
#会话列表
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.tab > div.tab-session")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.tab > div.tab-session").click()
#time.sleep(10)
wait_1 = WebDriverWait(self.driver,10)
wait_1.until(EC.visibility_of_element_located((By.XPATH,'//*[@id="session-list"]/li[1]/h3')))
self.driver.find_element(By.XPATH,'//*[@id="session-list"]/li[1]/h3').click()
#time.sleep(1)
wait_2 = WebDriverWait(self.driver,1)
wait_2.until(EC.visibility_of_element_located((By.XPATH,'//*[@id="session-list"]/li[1]/h3')))
text_2 = self.driver.find_element(By.XPATH,'//*[@id="session-list"]/li[1]/h3').text
#time.sleep(1)
wait_2.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="session-list"]/li[1]/h3')))
text_3 = self.driver.find_element(By.XPATH,'//*[@id="session-list"]/li[1]/h3').text
print(f"text_2:{text_2}")
print(f"text_3:{text_3}")
assert text_2 == text_3
#好友列表,这里验证新建会话
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.left > div.tab > div.tab-friend").click()
self.driver.find_element(By.CSS_SELECTOR,
"#friend-list > li:nth-child(2) > h4").click()
text_4 = self.driver.find_element(By.XPATH,'//*[@id="session-list"]/li[1]/h3').text
text_5 = self.driver.find_element(By.XPATH,'/html/body/div[2]/div/div[2]/div[1]').text
assert text_4 == text_5
print(f"text_4:{text_4}")
print(f"text_5:{text_5}")
ChatRoomDrive.GetScreenShoot()
#发送消息
#1.发送长度不超过200的文本信息是否能正常发送
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").send_keys("i love you")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > div.ctrl > button").click()
#2.英文格式下,发送数字+字母
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").send_keys("i love you123")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > div.ctrl > button").click()
#3.英文格式下,发送数字+特殊字符
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").send_keys("1322134&&&^^^***")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > div.ctrl > button").click()
#4.英文格式下,发送字母+特殊字符
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").send_keys("i love you&&&^^^***")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > div.ctrl > button").click()
#5.中文状态下,发送中文信息
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").send_keys("我爱你")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > div.ctrl > button").click()
#6.中文状态下发送中文+特殊字符
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").send_keys("我爱你,,,&&&^^^***!!!!")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > div.ctrl > button").click()
#7.发送网址链接
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").send_keys("https://www.doubao.com/chat/2705630781366018")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > div.ctrl > button").click()
#8.发送信息中包含换行
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").clear()
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > textarea").send_keys("i love you.\nAnd i miss you.")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.client-container > div > div.right > div.ctrl > button").click()
ChatRoomDrive.GetScreenShoot()
#未登录状态下聊天页面,出现警告弹窗
#确认之后跳转到登录页面
def NoLogTalkTest(self):
alert = self.driver.switch_to.alert
text_7 = alert.text
assert text_7 == "当前用户未登录!"
alert.accept()
ChatRoomDrive.GetScreenShoot()
4.5LoginSafeTest,py安全性
安全性测试主要测试了用户输入密码是否隐藏,是否防止SQL注入和多次密码错误是否锁定这三个安全问题。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from Common.Utils import ChatRoomDrive
class LoginSafe:
url = ""
driver = ""
def __init__(self):
self.url = "http://127.0.0.1:8080/login.html"
self.driver = ChatRoomDrive.driver
self.driver.get(self.url)
def SafeTest(self):
#SQL注入
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("'OR' 1'='1")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123")
#顺带可以检查密码是否隐藏
type = self.driver.find_element(By.XPATH,'//*[@id="password"]').get_attribute("type")
assert type == "password"
#print(f"type:{type}")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
wait = WebDriverWait(self.driver,1)
#alert = self.driver.switch_to.alert
alert = wait.until(EC.alert_is_present())
text_8 = alert.text
assert text_8 == "登录失败!"
alert.accept()
#添加屏幕截图
ChatRoomDrive.GetScreenShoot()
#多次输入错误
for _ in range(5):
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("1234")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#time.sleep(1)
alert = wait.until(EC.alert_is_present())
#alert = self.driver.switch_to.alert
text_3 = alert.text
assert text_3 == "登录失败!"
alert.accept()
ChatRoomDrive.GetScreenShoot()
自动化脚本测试结果展示
ChatRoom自动化测试
5.界面测试、易用性测试
关于这两个测试按照测试用例使用手动测试的方式。
6.测试总结
(1)功能测试覆盖全面,测试用例涉及合理,发现3个Bug。
(2)进行了基础的安全测试,SQL注入、隐藏密码等测试,发现1个Bug。
(3)进行了权限测试,用户无法跳过登录界面直接访问聊天页,测试通过。
(4)进行了界面测试和易用性测试,发现2个Bug。
7.Bug描述
Bug标题 | Bug等级 | 报告人 | 是否修复 |
搜索框无法搜索 | 严重 | 金** | 否 |
在输入信息时回车换行后,发送的信息显示是空格间隔的。 | 严重 | 金** | 否 |
进入聊天页面后,需要较长的时间才能加载出会话列表 | 一般 | 金** | 否 |
连续多次输入账号和密码错误之后不会锁定 | 一般 | 金** | 否 |
登录界面的密码显示和隐藏的按钮设计不合理,用户在输入密码时无法自由切换,只要鼠标切换点击这个按钮就会消失。 | 轻微 | 金** | 否 |
密码框没有大小写提示 | 轻微 | 金** | 否 |
8.测试建议
在优化时可以考虑以下几点建议:
(1)发送消息后可以添加显示发送的时间
(2)目前只能发送文本信息,可以添加发送文件,音乐,视频等文件的功能。
(3)目前没有注册的功能,可以添加注册功能
(4)可以在用户名前加上头像
9.测试工具
(1)功能测试、安全测试:使用Selenium+WebDriver自动化测试核心功能。
(2)API测试:使用Postman+Jmeter对接口进行性能测试
(3)测试用例设计:使用Xmind进行测试用例的设计
(5)脚本开发:使用PyCharm编写自动化脚本