目录
一、项目背景
1.1起源
随着互联网的飞速发展,人们的社交需求日益多样化,线上沟通成为了日常交流不可或缺的一部分。
传统的即时通讯工具虽然满足了部分沟通需求,但在特定场景下,如在线学习小组讨论、兴趣社区交流、远程团队协作等,用户渴望拥有一个更加专注、便捷的网页端聊天环境,能够随时随地通过浏览器接入,无需额外安装软件,网页版聊天室项目应运而生。
1.2市场分析
- 市场调研发现,众多上班族在工作之余希望有便捷的途径与同事、同行交流行业资讯、分享工作经验,且他们大部分时间处于办公电脑前,更倾向于使用网页应用;
- 学生群体在进行在线课程学习、课题讨论时,需要一个能快速组织成员、方便老师指导的聊天空间;
- 各类兴趣社团、粉丝群体也期盼有专属的网页交流平台,以便更好地凝聚成员、开展活动。综合来看,一个功能齐全、易用的网页版聊天室有着广阔的市场前景。
1.3项目目标
本项目旨在打造一个安全、高效、易用的网页版聊天平台,满足不同用户群体在多样化场景下的即时通讯需求。
用户登录、搜索联系人、通讯录管理、消息发送等,吸引用户入驻,提升用户粘性,成为互联网社交领域的优质选择。
二、项目功能
2.1用户系统
登录
- 本项目还处在内测阶段,使用该项目的用户,账号和密码均是内部提供,无需注册。
- 输入正确的账号和正确的密码,提示登录成功。
- 不合理的账号和密码填写会提示登录失败。
2.2聊天系统
1.聊天主页
- 聊天主页要显示当前的登录用户
- 聊天主页要显示正在聊天的用户昵称
- 提供消息列表,显示全部历史消息列表,并且可选可跳转。
- 提供通讯录功能,显示当前用户都有哪些好友,好友以昵称的方式显示,可以点击好友昵称跳转到好友聊天界面。
- 消息列表提供搜索功能,可以通过搜索昵称来找到联系人。
2.聊天界面
- 聊天界面上方显示正在聊天的对方昵称。
- 聊天界面显示已经发送的聊天消息,消息以文本框的形式呈现,背景色为绿色。
- 聊天消息显示对方发送过来的消息,消息以文本框的形式呈现,背景色为白色。
- 在聊天界面的下方为文本的消息的回显,可以看到用户即将要发送的消息
- 点击发送,可以看到用户成功发送消息。
三、测试报告
3.1测试目标
通过编写测试用例完成测试,检查项目功能是否完善。
- 登录功能正常。
- 搜索联系人能让用户明显辨识。
- 通讯录功能正常。
- 可以互相发送消息。
3.2测试安排
功能 | 后端 | 前端 | 提测日期 | 测试 | 测试日期 | 测试结果 |
登录 | 李* | 陈* | 4.1 | 罗* | 4.5 | 测试通过 |
发送消息 | 李* | 陈* | 4.1 | 罗* | 4.5 | 测试通过 |
搜索联系人 | 李* | 陈* | 4.2 | 罗* | 4.5 | 测试不通过 |
通讯录 | 李* | 陈* | 4.3 | 罗* | 4.5 | 测试通过 |
3.3编写测试用例
使用思维导图工具Xmind编写全部的测试用例。
3.4功能测试
3.4.1登录功能测试
1.输入正确的用户名和密码
经测试,账号可以复制,密码不可以复制,账号和密码都可以粘贴填入,密码也做了隐藏功能
异常登录要测试多种情况。
2.不输入账号不输入密码,点击登录。
3.输入正确的账号和错误的密码。
4.输入正确的账号,不输入密码,点击登录
5.输入错误的账号和正确的密码
6.输入错误的账号和正确的密码,错误账号由正确的账号和阿拉伯数字组成,点击登录。
7.输入错误的账号和正确的密码,错误的账号由正确的账号和特殊符号组成,点击登录。
8.测试直接输入聊天主页的链接,跳过登录接口,预期结果是无法进入聊天主页。
测试结果符号预期,未登录的用户无法通过主页链接直接进入,弹窗提示用户未登录,点击确定跳回登录页面。
测试总结
经测试,本次登录功能测试,测试覆盖8/8个测试用例,未发现bug。
3.4.2搜索好友
1.输入完整的联系人昵称
经测试发现Bug: 当输入完整的联系人昵称,预期是定位到与之匹配的联系人聊天窗口,结果与预期不符,定义为崩溃级别的bug。
2.输入正确的联系人前半部分昵称
3.不输入昵称,点击搜索
4.输入聊天内容,点击搜索
5.输入正确联系人的后半部分昵称
测试总结
经测试,联系人功能覆盖5/5个测试用例,发现1个崩溃级别的bug。
bug描述:
bug标题 | bug等级 | 报告人 | 是否修复 |
联系人功能异常 | 崩溃级别 | 罗* | 否 |
3.4.3聊天对话测试
1.不指定联系人,直接从键盘输入
预期:没有输入显示
结果:没有输入显示
2.指定联系人,鼠标定位输入框
预期,键盘输入可以显示
结果:键盘输入有显示
3.指定联系人,鼠标不定位输入框
预期:键盘输入没有显示
结果:键盘输入没有显示
4.鼠标光标定位输入框,输入200个字符信息,点击发送
5.鼠标光标定位输入框,发送一个字符
6.鼠标光标定位输入框,输入99个字符信息,点击发送
7. 发送字母+数字格式的内容
8.发送数字+中文格式的内容
9.发送字母+特殊符号的内容
10.发送网址链接
可以发送网址链接,但是不可点击,建议开发人员将消息框添加识别网址链接功能,提供用户可以点击网址链接跳转网页的功能。
11.发送的消息内容中包含换行字符
预期:消息框中显示换行字符。
结果:消息框没有识别到换行字符。
经测试发现Bug,当用户的输入内容中包含换行字符时,发送的消息中不显示换行字符,定义为一般级别的bug。
12.发送内容为空
预期:不发送空消息框
结果:不发送空消息框
测试总结
经测试,聊天对话测试共覆盖12/16个测试用例,发现1个一般级别的bug。
bug描述
bug标题 | bug等级 | 报告人 | 是否修改 |
无法发送换行字符 | 一般 | 罗* | 否 |
3.4.4通讯录测试
1.点击联系人,观察是否会跳转到对应的聊天页面,如果跳转,是否跳转正确。
2.双击联系人
预期:将双击识别为单击,跳转
结果:跳转。
测试总结
经测试,通讯录测试覆盖2/3个测试用例,没有发现bug。
3.5自动化测试
参考测试用例,创建自动化测试项目,编写自动化测试脚本。
自动化测试,需要编写
Login.py测试登录页面
Search.py测试搜索联系人
Chat.py测试聊天页面
Contacts.py测试通讯录
windows.py为后续添加的界面测试
无论哪一个测试脚本,都需要创建浏览器驱动对象,请求url,访问到对应页面,才能执行测试。
于是,需要一个通用文件comman_utils.py作为通用功能文件,给其他文件提供需要的必要配置,比如创建浏览器驱动对象,截图接口。
因此,整个项目要作如下划分:
3.5.1通用工具comman_utils
#创建一个浏览器驱动对象
import datetime
import os.path
import sys
from PIL import ImageGrab
from 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 getscreenshot(self):
#创建屏幕截图,我们希望在上级目录下新建一个图片文件夹,用来保存图片
#此外,所有的图片要按照日期分类,即图片文件夹下有多个不同日期的文件夹
#图片的命名格式"调用方法-2025-4-6-20:15:12.png"
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)
#获取弹窗的截图,由于弹窗不属于页面元素,driver无法驱动,因此要单独一个函数
def alert_screenshot(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"
screenshot = ImageGrab
screenshot.save("../images/" + dirname + "/" + filename)
#外部使用这个创建驱动,单例模式设计
ChatRoomDriver=Driver()
3.5.2登录界面自动化测试
在Web页面定位输入框。
登录成功后会有弹窗提示,一般涉及到弹窗,自动化脚本中都要加上显示等待(条件等待)的代码,防止当代码执行到了弹窗时,而页面还没有加载完成,出现报错。
涉及到输入框的填写,都建议填入前做clear处理,避免多次填写时造成追加字符串而测试异常。
#测试登录页面
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from Comman.comman_utils import ChatRoomDriver
from selenium.webdriver.support import expected_conditions as EC
class Login:
url = ""
driver=""
#构造函数
def __init__(self):
self.url="http://127.0.0.1:8080/login.html"
self.driver=ChatRoomDriver.driver
self.driver.get(self.url)
#成功登录的测试用例
def LoginSuccess(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")
time.sleep(2)
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
#如何判断登录成功,当点击登录按钮后,处理弹窗,如果是成功登录,则聊天页面会出现登录页面不存在的元素
#任选一个判断即可
#添加显示等待(条件等待)
wait = WebDriverWait(self.driver,5)
wait.until(EC.alert_is_present())
alert=self.driver.switch_to.alert
actual = alert.text
#断言弹窗信息与预期结果一致
assert actual == "登录成功"
time.sleep(1)
ChatRoomDriver.alert_screenshot()
alert.accept()
#验证页面是否有昵称
self.driver.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.left > div.user")
time.sleep(3)
ChatRoomDriver.getscreenshot()
#返回到登录页面
#self.driver.back()
def LoginFail(self):
#多次send_keys是追加,故建议任何send_keys之前都做clear操作
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("1234444")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
#检查是否登录失败
wait = WebDriverWait(self.driver, 3)
wait.until(EC.alert_is_present())
alert = self.driver.switch_to.alert
actual = alert.text
assert actual=="登录失败"
time.sleep(1)
ChatRoomDriver.alert_screenshot()
alert.accept()
# 正确的账号、不输入密码
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, "#submit").click()
# 检查是否登录失败
wait = WebDriverWait(self.driver, 3)
wait.until(EC.alert_is_present())
alert = self.driver.switch_to.alert
actual = alert.text
assert actual == "登录失败"
time.sleep(1)
ChatRoomDriver.alert_screenshot()
alert.accept()
#错误账号=正确账号+阿拉伯数字、正确的密码·
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("zhangsan123")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
# 检查是否登录失败
wait = WebDriverWait(self.driver, 3)
wait.until(EC.alert_is_present())
alert = self.driver.switch_to.alert
actual = alert.text
assert actual == "登录失败"
time.sleep(1)
ChatRoomDriver.alert_screenshot()
alert.accept()
#错误的账号=正确账号+特殊符号、正确的密码
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")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
# 检查是否登录失败
wait = WebDriverWait(self.driver, 3)
wait.until(EC.alert_is_present())
alert = self.driver.switch_to.alert
actual = alert.text
assert actual == "登录失败"
time.sleep(1)
ChatRoomDriver.alert_screenshot()
alert.accept()
# test = Login()
# time.sleep(2)
# test.LoginSuccess()
# test.LoginFail()
测试效果
此外,我们还可以添加自动化测试中的截图功能,比如登录异常时断言失败,我们需要知道当时的登录截图。
不仅登录测试会用到,后续各种测试都可能会用到这个功能,因此,截图功能要添加到Utils工具中
def getscreenshot(self):
#创建屏幕截图,我们希望在上级目录下新建一个图片文件夹,用来保存图片
#此外,所有的图片要按照日期分类,即图片文件夹下有多个不同日期的文件夹
#图片的命名格式"调用方法-2025-4-6-20:15:12.png"
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)
注意,执行这段代码之前,一定要提前手动创建好images目录。
3.5.3搜索好友自动化测试
import time
from selenium.webdriver.common.by import By
from Comman.comman_utils import ChatRoomDriver
class Search:
url = ""
drive=""
def __init__(self):
self.url="http://127.0.0.1:8080/client.html"
self.drive=ChatRoomDriver.driver
self.drive.get(self.url)
#登录成功下的搜索功能
def search_on_success(self):
#清空搜索栏
self.drive.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.left > div.search > input[type=text]").clear()
#输入正确的联系人
self.drive.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.left > div.search > input[type=text]").send_keys("zhangsan")
#点击搜索
self.drive.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.left > div.search > button").click()
#在当前页面查找对话框中的昵称提示
actual = self.drive.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.right > div.title").text
ChatRoomDriver.getscreenshot()
assert actual=="zhangsan"
按照预期,先测试正常登录下,能否检索到联系人,如果可以,在点击搜索按钮后,会话窗口会出现与之匹配的联系人昵称。
为了方便测试,我们引入控制顺序的测试文件,像C++语言一样,Python也有了Main函数,即程序的入口,代码从入口处开始执行,方便控制整个测试函数的调用。
import time
from Comman.comman_utils import ChatRoomDriver
from Test import Login
from Test import Search
if __name__ == "__main__":
time.sleep(5)
#测试登录
Login.Login().LoginFail()
Login.Login().LoginSuccess()
#测试正常搜索
Search.Search().search_on_success()
#测试异常搜索
# Login.Login().LoginFail()
# time.sleep(2)
# Search.Search().search_on_fail()
ChatRoomDriver.driver.
程序没有正常退出,而是出现断言错误
说明没有找到与之匹配的联系人昵称,与功能测试阶段发现的bug相符合。
3.5.4聊天对话自动化测试
#测试对话聊天功能
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from Comman.comman_utils import ChatRoomDriver
from selenium.webdriver.support import expected_conditions as EC
class Chat:
driver=""
def __init__(self):
self.driver = ChatRoomDriver.driver
def ChatToSomebody(self):
time.sleep(5)
#在好友列表点击某联系人,发送消息,检查是否有发送弹窗
self.driver.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.left > div.tab > div.tab-session").click()
wait = WebDriverWait(self.driver,10)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#session-list > li:nth-child(1)")))
self.driver.find_element(By.CSS_SELECTOR,"#session-list > li:nth-child(1)").click()
wait = WebDriverWait(self.driver,10)
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"body > div.client-container > div > div.right > div.title")))
#在输入框发送消息
message = "2025/4/8自动化测试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").click()
self.driver.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.right > textarea").send_keys(message)
#点击发送
time.sleep(1)
self.driver.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.right > div.ctrl > button").click()
#验证是否成功发送
time.sleep(5)
ChatRoomDriver.getscreenshot()
3.5.5通讯录自动化测试
class Contacts:
driver=""
def __init__(self):
self.driver=ChatRoomDriver.driver
def contacts(self):
time.sleep(5)
self.driver.find_element(By.XPATH,"/html/body/div[2]/div/div[1]/div[3]/div[2]").click()
time.sleep(2)
self.driver.find_element(By.XPATH,"/html/body/div[2]/div/div[1]/ul[2]/li[2]/h4").click()
self.driver.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.right > div.message-show")
time.sleep(2)
actual = self.driver.find_element(By.CSS_SELECTOR,"body > div.client-container > div > div.right > div.title").text
print(actual)
assert actual == "wangwu"
3.5.6界面测试
在项目复盘阶段,整理自动化测试脚本时,发现对各个功能只测试合理正确的部分,因为异常登录下,这些功能的界面元素无法被定位到, 因此可以将异常登录的情况编写到界面测试的脚本中。
import time
from selenium.webdriver.support.wait import WebDriverWait
from Comman.comman_utils import ChatRoomDriver
from selenium.webdriver.support import expected_conditions as EC
class windows:
driver=""
url = ""
def __init__(self):
self.url = "http://127.0.0.1:8080/client.html"
driver=ChatRoomDriver.driver
self.driver.get(self.url)
def chatroom_nologin(self):
# 出现警告弹窗
alert = WebDriverWait(self.driver, 5).until(EC.alert_is_present())
# 获取弹窗文本
text = alert.text
# 断言弹窗文本与预期是否符合
assert text == ("当前用户未登录!")
time.sleep(1)
# 添加弹窗截图
ChatRoomDriver.get_alert_image()
alert.dismiss()
四、测试环境
PC系统:Windows10:版本19045.5487
浏览器:Chrome:135.0.7049.42(正式版本) (64 位)
测试工具:selenium4.0.0
五、bug描述
1.使用Edge浏览器访问页面时,用户可以选择展示密码
而Chrome浏览器没有,建议开发人员可以在Chrome浏览器添加这个功能。
2.搜索联系人功能无法使用,点击搜索按钮并不展示搜索结果,定义为严重级别的bug。
六、测试总结
1.在功能测试阶段,覆盖了登录功能、搜索好友功能、聊天对话功能、使用通讯录跳转好友等功能其中已发现的问题均已在bug描述中指出。
2.在自动化测试阶段,发现脚本执行代码的结果正确时,而界面却没有与之相应的做变化,推测可能是服务器性能较差,推荐更换高性能的服务器。
3.主要功能为聊天对话功能,测试正常,符合需求文档,评估为可以上线。
4.项目上线后,须及时跟进用户操作日志,评估用户遇到bug的情况水平。
测试心得
1.在本次测试过程中,遇到的一个大问题:自动化测试时编写代码测试聊天对话功能时,发送一条消息的操作是由脚本代码执行,因此测试人员想要在编写脚本代码时从页面上定位到这条消息是不可能的,对于测试人员来说,无法从页面中定位到元素来编写代码,去验证发送消息的正确性。
作为一名测试初学者来说,遇到了较大的挑战,而在我请教有经验的测试人员后,了解到不必只用代码断言这一种方式来验证发送消息的正确性,可以获取页面截图后,观察页面截图是否符合需求,同样可以达到测试的目的。
这启发了我在今后的测试工作中,要发散性的去思考能否借助更多的方式完成目标。
2.自动化测试的脚本代码,由cpu执行,其执行速度远远超过Web页面的渲染速度,造成的局面就是:许多获取页面元素的代码,可能在代码执行完毕了,但是页面还没有渲染完成,因此需要使用等待语句来让代码阻塞等待,而常用的三种等待方式中,多是使用显示等待合强制等待两种方式,尤其是显示等待的各种参数,需要在测试工作的经验中不断的积累。
3.在完成测试报告后,将自己设计的测试用例同专业测试人员的测试用例作对比,总结我的测试用例的设计不够精确,相对笼统,需要将一个个具体的文字、案例,演示都写到测试用例,而不是带着总结的看法编写测试用例。
4.界面测试则可以将异常登录的测试完全覆盖,不用在测试具体功能在异常登录下是何种情况了