[Beta阶段]测试报告
测试方法及过程
在正式发布前,为检验后端各接口功能的正确性,后端服务器对压力的耐受程度,以及前端各页面、功能的运行情况,我们对我们的服务器及小程序进行了多种测试。除去随开发进行的基本正确性测试外,针对上述三种情形,我们分别进行了单元测试、压力测试以及功能测试。
单元测试
单元测试的主要目的,是测试后端所有接口的工作是否正常。其内容主要包含两方面:
- 接口在正常情况下是否能发挥预期功能
- 接口在异常情况下是否能返回预期错误信息
Beta阶段的所有单元测试与Alpha阶段相同,在pycharm下使用Coverage工具进行测试。经过修改后已经通过了所有单元测试。所进行的一些测试如下图:
为保证测试的全面性,我们针对每一个接口都设计了相应的单元测试。单元测试的总数高达140个。
在运行完所有单元测试后,单元测试的代码覆盖率高达96%,切实确保了所有接口的正确性。
单元测试中发现的bug如下:
后端单元测试Bug汇总
接口 | 现象 | 原因 | 是否解决 |
---|---|---|---|
p/<int:post_id>/modify/ |
发送正确信息时会返回错误3,但发送携带错误label的信息时会正常返回 | 对label的合法性判断条件反了 | 是 |
f/processing/<str:label>/ |
发送错误label是仍能正常返回 | 检验label时调用相应检验函数时未将label分隔成数组传入 | 是 |
my/<int:user_id>/apply/ |
无论发送什么信息都会报错 | 错误的调用了推荐算法 | 是 |
f/processing/ |
无法获取发布信息 | 通过后台管理界面增加数据时没有指定发帖人,导致获取信息时崩溃 | 是 |
f/processing/ |
history参数为空时报错 | 对空字符串调用split方法并不会得到一个空列表 | 是 |
login/wechat/ |
微信登录接口无法获取openid | 腾讯提供的auth.code2Session接口返回值与文档不一致 | 是 |
login/wechat/ |
改用mysql数据库后含有特殊字符的微信昵称无法登陆 | MySQL数据库的默认编码问题,需要将编码改为utf8mb4 | 是 |
p/<int:post_id>/delete/ |
删除post后与该post相关的apply并未删除 | 相关的apply需要手动删除或者将对应的外键参数on_delete设置为models.CASCADE | 是 |
c/post/ |
post_title字段超过20个字符时无法创建post | 前后端约定不一致,后端限制最大长度为20,而前端为50 | 是 |
服务器端设置的默认图片路径无法访问 | 在Windows系统上可以将默认图片路径设为绝对路径,但在ubuntu系统上似乎只能用相路径 | 是 | |
微信机器人无法正常登陆 | 没有将之前运行生成的wxpy.pkl删除 | 是 |
可以看见,大部分bug产生的原因还是参数的合法性问题。上述问题现已全部解决。
压力测试
对服务器来说,压力负载能力是评价其表现的重要指标之一。因此,我们针对服务器进行了压力测试。
压力测试使用基于Python的压力测试工具locust进行。压力测试的一些基本参数如下:
- 并发用户数:500
- 总请求数 :5412
进行压力测试后的结果如下:
可以看到,对于上述参数下的压力测试,总请求数量为5412个的情况下,失败请求数为3,表现良好。
平均响应时间为1.539s,作为高峰期的响应时间,仍可以接受。
吞吐率为17.4req/s。
在压力测试结束时,针对云服务器端的监控如下:
在途中可以看到,在压力测试期间,CPU的占用率峰值约在62%左右,仍有一定资源剩余。但是,在监控图的第一行外网出带宽
中可以看到,压力测试期间的对外带宽达到了最大限制1Mbps,因此,可以发现性能的瓶颈主要在于云服务器的带宽限制(1Mbps)。
前端功能测试
对于前端的功能测试,仍采用与Alpha阶段相同的方式,即在不同的机型、不同的操作系统下,对每个页面的每个功能进行一一测试,以检测其功能的正确性。前端功能测试的测试矩阵如下:
测试矩阵 | 功能测试 | 页面显示 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
测试机型 | 测试环境 | 登录 | 搜索 | 查看分类标签 | 首页智能推荐 | 修改个人信息 | 修改简历 | 查看招募 | 发布招募 | 查看我的发布 | 采纳申请 | 申请招募 | 查看我的申请 | 页面排版 |
Mi5 | android 8.0 wifi | 无问题 | 无问题 | 无问题 | 无推荐效果 | 后端问题导致无法修改 | 无问题 | 无问题 | 无问题 | 无问题 | 无法查看申请者 | 无问题 | 查看我的简历无法显示 | 无问题 |
Mi6 | Android 9.0 wifi | 无问题 | 无问题 | 无问题 | 无推荐效果 | 后端问题导致无法修改 | 无问题 | 无问题 | 无问题 | 无问题 | 无法查看申请者 | 无问题 | 查看我的简历无法显示 | 无问题 |
Mi9 | Android 9.0 wifi | 无问题 | 无问题 | 无问题 | 无推荐效果 | 后端问题导致无法修改 | 无问题 | 无问题 | 无问题 | 无问题 | 无法查看申请者 | 无问题 | 查看我的简历无法显示 | 无问题 |
iphonoe xr | ios12 | 第一次需要退出重进 | 无问题 | 无问题 | 无推荐效果 | 后端问题导致无法修改 | 无问题 | 无问题 | 无问题 | 无问题 | 无法查看申请者 | 无问题 | 查看我的简历无法显示 | 无问题 |
iphonoe 8 | ios12 | 第一次需要退出重进 | 无问题 | 无问题 | 无推荐效果 | 后端问题导致无法修改 | 无问题 | 无问题 | 无问题 | 标签选择时偶然产生失去焦点问题 | 无问题 | 无问题 | 查看我的简历无法显示 | 无问题 |
华为荣耀 | 安卓 8.0 | 第一次需要退出重进 | 无问题 | 无问题 | 无推荐效果 | 后端问题导致无法修改 | 无问题 | 无问题 | 无问题 | 标签选择时偶然产生失去焦点问题 | 无问题 | 无问题 | 无问题 | 无问题 |
前端Bug汇总
BUG | 现象 | 原因 | 是否解决 |
---|---|---|---|
标签页下拉菜单显示异常 | 输入刚一结束,还未选择标签,下拉菜单页消失 | 控件绑定函数的触发事件有问题 | 是 |
当用户没有标签时,修改发布页面崩溃 | 页面无法正常显示信息 | 当没有标签的时候,标签之前无分隔符,调用分割函数时报错 | 是 |
个人中心我的简历页面退出登陆有误 | 退出到了一个不用的界面 | 上个版本遗漏的bug,现已经解决 | 是 |
待审核简历数有误 | 一直显示同一个数字 | 前端设计页面时设置的默认变量未更换 | 是 |
申请招募时,对简历合法性检测出问题 | 输入合法的简历信息但是无法提交申请 | 判断简历信息是否合法的信息出了问题 | 是 |
获取头像后无法立即登录 | 点击获取头像以后无反应然后无法登陆 | 获取用户信息与登陆功能交叉 | 否 |
无推荐效果 | 主页页面不会随用户点击而变 | 推荐算法不完善,帖子数目太少 | 否 |
后端问题,无法修改个人信息 | 后端检查格式问题 | 后端检查错误 | 否 |
无法查看申请者 | 点击查看申请者无反馈结果 | 原因未知 | 否 |
查看我的简历无法显示 | IOS上无法显示简历 | 安卓和ios 数据不互通 | 否 |
主页有时候加载不出来 | 加载提示结束时未显示主页面 | 原因未知 | 否 |
无法查看申请者简历 | 点击申请者无法显示简历 | 原因未知 | 否 |
场景测试
场景测试1
-
典型用户:冰哥
-
用户需求
冰哥是计算机系的大三学生。临近毕业,冰哥想在学校的实验室中寻找实习机会,以增加自己的实践经验。冰哥对计算机视觉方面尤其感兴趣,因此希望能寻找到与计算机视觉相关的招募。 -
场景描述1
- 冰哥打开微信,进入小小易校园小程序,并通过微信登录
- 进入首页,点击屏幕正上方的搜索框,在搜索框中输入“计算机视觉”,点击搜索
- 浏览全部含有关键词“计算机视觉”的招募,找到符合冰哥心中预期的实习
- 进入相应招募详情,点击申请,并修改自己的简历,等待申请结果。
-
场景描述2
- 冰哥打开微信,进入小小易校园小程序,并通过微信登录
- 进入首页,浏览发布列表,找到了一个含有“计算机类“标签的招募
- 点击招募,进入招募详情,点击标签“计算机类”,浏览所有含有“计算机类”标签的发布
- 在这些发布中,找到符合冰哥心中预期的实习
- 进入相应招募详情,点击申请,并修改自己的简历,等待申请结果。
场景测试2
- 典型用户:航哥
- 用户需求
航哥是一名大三的学生,本科专业是计算机专业,但是对经济学又特别感兴趣。因此,航哥想趁着大三开始学业任务轻松下来的机会,寻找计算机与经济学交叉的实习。 - 场景描述
- 航哥打开微信,进入小小易校园小程序,并通过微信登录
- 进入首页,在所有发布中寻找与计算机、经济学都有关的招募
- 找到符合要求的招募,进入招募详情,可惜时间与上课时间冲突
- 返回首页,发现包含计算机类、经济学类标签的招募优先显示在了最上方,航哥因此迅速找到了符合自己要求的招募
- 进入招募详情申请招募并等待结果。
回归测试
对于前端的回归测试,我们在测试前端功能时,对所有新旧页面都进行了一一测试,确保了原有功能的正确性(详情见测试矩阵)。
对于后端的回归测试,我们随着开发,更新了上一阶段的单元测试,对于有改动的接口,修改了其相应的单元测试使其满足最新功能。下面给出一个原有接口的单元测试用例代码:
class GetApplyTest(TestCase):
def setUp(self): # 测试所用数据库为空,需手动插入数据
user = User.objects.create(account=\'bsh_test\', password=gen_md5(\'admin_admin\', SECRET_KEY)) # 数据库中插入用户
self.post2 = Post.objects.create(title="test_apply", post_detail="test_test2", request_num=4, accept_num=1,
deadline="2019-5-20", if_end=False, poster=user)
resume = Resume.objects.create(name=\'asd\', sex=\'s\', age=10, degree=\'dasd\', phone=\'1234\', email=\'1@2\', city=\'32\',
edu_exp=\'bei\', awards=\'das\', english_skill=\'dasd\', project_exp=\'dasda\',
self_review=\'dasd\')
self.apply_exp = Apply.objects.create(resume=resume, post=self.post2, applicant=user)
self.token = create_token(user.id).decode()
self.url = \'/apply/\' + str(self.apply_exp.id) + \'/\'
self.post_ID = self.post2.id
def test_get_apply(self):
\'\'\'
成功获取
\'\'\'
response = self.client.get(self.url, HTTP_AUTHORIZATION=self.token)
ret_data = response.json()
self.assertTrue(ret_data[\'ret\'])
# self.assertEqual(ret_data[\'error_code\'], 3)
def test_get_apply_err1(self):
\'\'\'
不是 get 方法
\'\'\'
response = self.client.post(self.url, HTTP_AUTHORIZATION=self.token, content_type=\'application/json\')
ret_data = response.json()
self.assertFalse(ret_data[\'ret\'])
self.assertEqual(ret_data[\'error_code\'], 1)
def test_get_apply_err2(self):
\'\'\'
用户登陆已过期
\'\'\'
response = self.client.get(self.url, HTTP_AUTHORIZATION=\'\')
ret_data = response.json()
self.assertFalse(ret_data[\'ret\'])
self.assertEqual(ret_data[\'error_code\'], 5)
def test_get_apply_err3(self):
\'\'\'
该申请不存在
\'\'\'
uuu = \'/apply/666/\'
response = self.client.get(uuu, HTTP_AUTHORIZATION=self.token)
ret_data = response.json()
self.assertFalse(ret_data[\'ret\'])
self.assertEqual(ret_data[\'error_code\'], 2)
def test_get_apply_err4(self):
\'\'\'
当前登陆的用户 既不是申请者 也不是发布者
\'\'\'
user_a = User.objects.create(account=\'bsh_adsad\', password=gen_md5(\'admin_admin\', SECRET_KEY))
tt = create_token(user_a.id).decode()
response = self.client.get(self.url, HTTP_AUTHORIZATION=tt)
ret_data = response.json()
self.assertFalse(ret_data[\'ret\'])
self.assertEqual(ret_data[\'error_code\'], 3)
该单元测试类GetApplyTest
对应的接口设计规格如下:
-
setUp
方法:
setUp
方法用于填充用于测试的数据。测试所用数据库与实际后台服务器数据库是分离的,每次运行测试时,测试数据库都为空,因此需要先向测试数据库中填充测试所需要的数据。此方法中还用于初始化一些其他测试常用的变量,如用户token
,访问的后端url
等。 -
test_get_apply
方法:
test_get_apply
方法用于测试正常获取到该申请的情况。在这种情况下,返回值ret_data
的值应为true
。 -
test_get_apply_error1
方法:
test_get_apply_error1
方法测试的是error_code
为1,即前端访问该url时,请求类型不是get
的情况。判断返回的ret_data
是否为false
,返回的错误代码error_code
是否为1,作为测试的正确性判断。 -
test_get_apply_error2
方法:
test_get_apply_error2
方法测试的是error_code
为5,即前端访问该url时,用户登录已过期,未能获取到token
的情况。同样判断返回的ret_data
是否为false
,返回的错误代码error_code
是否为5。 -
test_get_apply_error3
方法:
test_get_apply_error3
方法测试的是error_code
为2,即前端访问该url时,给出的apply_id
不存在的情况。这种情况返回的错误代码error_code
应为2。 -
test_get_apply_error4
方法:
test_get_apply_error4
方法测试的是error_code
为3,即前端访问该url时,当前用户既不是该申请的发布者或接受者,即用户没有权限查看该申请的情况。返回错误代码error_code
应为3。
出口条件
Beta版本主要进行的工作是页面的重新设计以及实现,因此,出口条件设定如下:
-
完成主要页面的重新绘制
包含主页、导航栏、发布详情页面、新建发布页面、我的发布页面、我的申请页面、发布的申请页面、个人中心页面的重新绘制。重新绘制的主要目的是,修改页面配色,添加更多图标与图片,解决Alpha版本中页面过于重复的问题。 -
完成搜索功能
搜索功能主要包括两种。- 主页中的搜索功能
这一功能使用户可以根据自己的需求,按照关键词搜索发布标题,以寻找特定的发布。 - 点击发布详情中的标签查看该分类下的发布
这一功能使用户在浏览发布时,可以根据感兴趣的标签筛选发布。
- 主页中的搜索功能
-
完成推荐功能
推荐功能也分为两类:- 根据浏览历史,推荐相关招募信息
根据用户最近浏览历史中发布的标签,进行统计与分析,并在主页中重新排序,将用户可能更感兴趣的发布类型优先显示,提高用户寻找招募的效率。 - 智能排序申请者简历
在“发布的申请者”页面,对每一份简历,根据其获奖记录、实习记录等信息进行评价,并根据其专业与发布的类型进行匹配,将更可能满足用户需求的申请者优先显示。
- 根据浏览历史,推荐相关招募信息