[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版本中页面过于重复的问题。

  • 完成搜索功能

    搜索功能主要包括两种。

    • 主页中的搜索功能

      这一功能使用户可以根据自己的需求,按照关键词搜索发布标题,以寻找特定的发布。
    • 点击发布详情中的标签查看该分类下的发布

      这一功能使用户在浏览发布时,可以根据感兴趣的标签筛选发布。
  • 完成推荐功能

    推荐功能也分为两类:

    • 根据浏览历史,推荐相关招募信息

      根据用户最近浏览历史中发布的标签,进行统计与分析,并在主页中重新排序,将用户可能更感兴趣的发布类型优先显示,提高用户寻找招募的效率。
    • 智能排序申请者简历

      在“发布的申请者”页面,对每一份简历,根据其获奖记录、实习记录等信息进行评价,并根据其专业与发布的类型进行匹配,将更可能满足用户需求的申请者优先显示。

最新文章

  1. wordpress优化之结合prism.js为编辑器自定义按钮转化代码
  2. Android Notification通知详解
  3. Nodejs&amp;express+mongodb完成简单用户登录(即Nodejs入门)
  4. mysql中常用的控制流函数
  5. C++STL算法速查
  6. PowerDesigner 12.5 反向工程sql server
  7. PHP单元测试工具PHPUnit初体验
  8. Tomcat - 持久化 Session
  9. Null Pointer --设计模式
  10. 浅谈jquery关于select框的取值和赋值
  11. 如何让对象只在堆或者栈中分配空间ANDC++禁止一个类被继承
  12. 在 Android 中 Intent 的概念及应用
  13. WCF技术剖析之十二:数据契约(Data Contract)和数据契约序列化器(DataContractSerializer)
  14. IDEA第二章----配置git、tomcat(热部署)、database,让你的项目跑起来
  15. SQL 四种连接查询(内连接、左连接、右连接、全连接)
  16. UVA315 Network 连通图割点
  17. vue学习之用 Vue.js + Vue Router 创建单页应用的几个步骤
  18. mySql单列索引与联合索引的区别
  19. idea 自动导入包和自动将没用的包去除
  20. Java并发-volatile的原理及用法

热门文章

  1. English--并列句
  2. FreePascal - CodeTyphon 如何调整代码编辑器背景色?
  3. iview引用自定义的图标
  4. 如何提交多个具有相同name属性的表单
  5. 【前端_js】array.forEach和$.each()及$().each()的用法与区别
  6. 大数据:Hadoop(HDFS 读写数据流程及优缺点)
  7. 详解Apache服务与高级配置,(主配置文件每行都有描述)
  8. dapi 基于Django的轻量级测试平台一 设计思想
  9. 【转载】jmeter-命令行执行脚本
  10. lxml获取结点属性整并转换为字典参数