项目课堂模块自动化测试接入

513 阅读4分钟

1. 场景和想法

  1. 场景

    目前在工作业务中,课堂模块的业务逻辑错综复杂,导致了在每次遇到这一模块的需求改造/增加时,都要耗费许多精力。主要表现为:

    • 代码结构不合理:代码里面有不同逻辑之间耦合的部分,改代码需要战战兢兢,检测各处逻辑是否会受到到影响
    • 测试过程漫长:目前基于前端计时器来进行30s一次的学习上报,要测试完上报相关逻辑,至少需要创建一个学习时长为90秒以上的课程,中途手动模拟断网,后台返回异常等操作。每当修改一次代码,整套自测流程下来可能就需要2-3分钟。
  2. 想法

    引入自动化测试,把上述以人为驱动的测试行为转化为机器执行的一种过程。这样的好处是:

    1. 利用测试框架的能力,大大缩短测试时间,降低开发成本。
    2. 业务核心逻辑不变的情况下,后续迭代都能使用前人编写的测试用例,轻松保证主逻辑不受影响。
    3. 测试用例的复杂性反映了代码的复杂性,以此作为反馈,更好地推进自己优化代码结构,简化测试用例。测试用例的存在也能保证代码优化过程中不会出现影响主流程的大问题。

2. 技术栈选择

  1. 测试框架:Jest

    • Vue Test Utils 官方推荐
    • 通过搜索引擎搜索前端单元测试也能搜到一些优秀的前端团队也有基于Jest的相关最佳实践。
    • 开箱即用,API简单,上手成本低
  2. 辅助工具:

    • Vue Test Utils及官方推荐的一系列插件

3. 项目内集成Jest

  1. 详细接入流程及踩坑记录:juejin.cn/post/709010…

  2. 详细API使用指南:jestjs.io/docs/en/api

  3. 编写测试样例并运行

    test('测试文档课堂学习上报-(120秒内应该上报4次)', async (done) => {
      // 浅渲染文档课堂组件
      docWarpper = shallowMount(doc, getDocMountOptions());
      // 初始化后,期望此时的剩余学习时长为 120s
      expect(docWarpper.vm.remainTime).toBe(120);
      // 开始学习倒计时
      docWarpper.vm.countdown();
      // 模拟Axios返回的值,倒计时结束,返回learn_time为 120
      Axios.put.mockResolvedValue(mockLearnTimeReturn(120));
      // 时间快进 120s
      jest.advanceTimersByTime(1000 * 120);
      // 等待所有的promise resolve
      await flushPromises();
      // 期望上报了4次
      expect(docWarpper.vm.report).toHaveBeenCalledTimes(4);
      // 检查倒计时期望被调用了一次
      expect(docWarpper.vm.checkCountDownAccuracy).toHaveBeenCalledTimes(1);
      // 期望检查倒计时结束后,剩余学习时间变为0
      expect(docWarpper.vm.remainTime).toBe(0);
      jest.runOnlyPendingTimers();
      // 学习结束后应该轮询关卡状态
      expect(docWarpper.vm.refreshPointStatus).toHaveBeenCalledTimes(1);
      done();
    });
    
  • 上面是一个简单的测试样例, 通过集成测试的方法,可以在很短的时间内就测试完一个完整学习时长为2min的课程的整个过程。若所有的测试样例都能通过,则执行命令后会提示通过:

1.png

  • 若此时前端的上报逻辑改为了40s上报一次,同样再次执行测试样例,则会提示测试不通过,因为Jest监控到report函数在120秒内仅仅被调用了3次。

2.png

 

4. 探索自动化测试的应用场景

  • 集成测试:如上述遇到的场景,集成测试可以帮助我们模拟一系列的用户行为,稳定整个模块的核心逻辑。
  • 单元测试:对于项目中的一些基础库,全局挂载的插件,公共组件,可以使用jest来保证它们在迭代中的稳定性。
  • Jest提供的snapshot功能: 利用snapshot功能,Jest会把结果值储存在一个档案当中,每次进行测试的时候会把测试值与档案中的结果值进行比较, 如果两个结果值不同,那么开发者可以选择要么检查代码,要么用新代码生成snapshot来替代。
  • 通过搜索业界的最佳实践,可以系统化地组织测试代码,制定测试样例的规范,甚至还可以考虑把自动化测试接入CI流水线,通过质量红线才能走正式发布的流程等等。

5. 总结

本次对于自动化测试的尝试,主要是源于课堂模块的改动测试成本高的思考,选择了在空闲的时间,自己拉分支接入并作一定的尝试。因此,可能在测试代码的组织,以及本身自动化测试是否有必要落地到工业生产中的一环都思考得还不够多,希望能藉着一次小小的尝试满足一下自己想要动手玩玩的欲望,以及开发出除日常业务开发外更多的可能性,希望大家能够相互交流,不吝赐教。