浅谈前端测试

发表于:2019-5-07 11:57

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:orangexc    来源:掘金

   vue 环境
  在 vue 使用场景下,无非就是组件库和业务逻辑,组件库偏向于 unit 测试,业务逻辑偏向于 e2e 测试,当然两者并不冲突
  unit 测试
  推荐神器:vue-test-utils
  README 给了多个测试库配置的例子,这里还是推荐使用 jest,给个例子
   export default {
  props: ['value'],
  data () {
  return {
  currentValue: 0
  }
  },
  watch: {
  value (val) {
  this.currentValue = val
  }
  }
  }
  测试如下
   import { mount } from '@vue/test-utils'
  import Test from './Test.vue'
  test('props value', () => {
  const options = { propsData: { value: 3 } }
  const wrapper = mount(Test)
  expect(wrapper.vm.currentValue).toBe(3)
  })
  十分简单的例子,亮点在测试文件的 wrapper 上,通过 mount 方法创建了一个组件实例,创建过程中允许加入一些配置信息,甚至是 mock 组件中的 method 方法
  vue 单元测试的范围仅限于数据流动是否正确,逻辑渲染是否正确(v-if v-show v-for),style 和 class 是否正确,我们并不需要关系这个组件在浏览器渲染中的位置,也不需要关系对其它组件会造成什么影响,只要保证组件本身正确即可,前面说的断言,vue-test-utils 都能提供对应的方案,总体上节约很多测试成本
  e2e 测试
  也是推荐尤大基于最新脚手架的 @vue/cli-plugin-e2e-nightwatch
  e2e 测试的重点在于判断真实 DOM 是否满足预期要求,甚至很少出现 mock 场景,不可或缺的是一个浏览器运行环境,具体细节不赘述,可以看官方文档。
  nuxt 服务端渲染环境
  nuxt 官方推荐 ava,顺势带出 ava 的方案
  unit 测试
  麻烦在配置上面,先给出需要安装的依赖
   "@vue/test-utils",
  "ava",
  "browser-env",
  "require-extension-hooks",
  "require-extension-hooks-babel",
  "require-extension-hooks-vue",
  "sinon"
  在 package.json 里加几行 ava 配置
   "ava": {
  "require": [
  "./tests/helpers/setup.js"
  ]
  }
  下面来写 ./tests/helpers/setup.js
   const hooks = require('require-extension-hooks')
  // Setup browser environment
  require('browser-env')()
  // Setup vue files to be processed by `require-extension-hooks-vue`
  hooks('vue').plugin('vue').push()
  // Setup vue and js files to be processed by `require-extension-hooks-babel`
  hooks(['vue', 'js']).plugin('babel').push()
  上面的代码唯独没看到 sinon 这个库,说到 ava 是没有 mock 功能的,这就给单元测试的 mock 带来巨大困难,不过我们可以通过引入 sinon 来解决 mock 数据的问题,在 mock 方面上 sinon 做的比 jest 还要优秀,支持沙箱模式,不影响外部数据
  给个简单点的例子
   <template>
  <el-card v-for="item in topicList" :key="item.id">
  <div class="card-content">
  <span class="link" @click="toMember(item.member.username)">{{ item.member.username }}</span>
  </div>
  </el-card>
  </template>
  <script>
  export default {
  props: {
  topicList: {
  type: Array,
  required: true
  }
  },
  methods: {
  toMember (name) {
  this.$router.push(`/member/${name}`)
  }
  }
  }
  </script>
  对应的测试代码如下
    import { shallowMount } from '@vue/test-utils'
  import test from 'ava'
  import sinon from 'sinon'
  test('methods: toMember', t => {
  const { topicList } = t.context
  const $router = {
  push: () => {}
  }
  const spy = sinon.spy($router, 'push')
  const wrapper = shallowMount(TopicListChalk, {
  propsData: { topicList },
  mocks: {
  $router
  }
  })
  topicList.forEach((item, index) => {
  const toMemberText = wrapper.findAll('.card-content').at(index).find('.link')
  toMemberText.trigger('click')
  t.true(spy.withArgs(`/member/${item.member.username}`).calledOnce)
  })
  })
  这里直接将 $router mock 掉,并且使用 sinon.spy 监听执行,至于 this.$router.push 后浏览器有没有跳转并不是单元测试需要关心的,这里的写法也比较特别,test 方法在回调里默认参数为 t,对应的方法都挂载在 t 对象上,上下文可通过 t.context 传递
  nuxt 单元测试相关就聊这么多
  e2e 测试
  这里有个歧义点,nuxt 官网只给出了 e2e 的测试案例 end-to-end-testing
  当使用默认脚手架构建的项目,也就是没有 server 端入口文件的项目,这个方案确实可行
  但是涉及到其它框架(express|koa)的时候就显得不够用了,很有可能在自定义 server 入口是加入了大量中间件,这对于官网给出的例子是个巨大考验,不可能在每个测试文件里实现一遍 new Nuxt,所以需要更高层的封装,也就是忽略 server 启动流程的差异性,直接在浏览器中抓取页面
  推荐:https://github.com/alidcastano/nuxt-jest-puppeteer
  react 环境
  unit 测试
  这一波没得可选,jest 完胜,人家官网就有 React,RN 的支持文档https://jestjs.io/docs/en/tutorial-react.html
  文档的案例也是十分全面,没得讲,不赘述
  e2e 测试
  其实上面讲了两个 e2e 的方案选择,大同小异,需要一个能在 node 跑的无头浏览器,官方没有推荐,这里站 vue 一票选择 nightwatchjs http://nightwatchjs.org/
  next 服务端渲染环境
  unit 测试
  主要讲一下如何配置,先是依赖包
   "babel-core",
  "babel-jest",
  "enzyme",
  "enzyme-adapter-react-16",
  "jest",
  "react-addons-test-utils",
  "react-test-renderer"
  在 package.json 里面加 script "test": "NODE_ENV=test jest"
  在跟路径下加 jest.config.js
   module.exports = {
  setupFiles: ['<rootDir>/jest.setup.js'],
  testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/']
  }
    在跟路径下加 jest.setup.js
   import { configure } from 'enzyme'
  import Adapter from 'enzyme-adapter-react-16'
  configure({
  adapter: new Adapter()
  })
   接下来就可以愉快的写测试了
  e2e 测试
  跳过了~~~
  angular 环境
  之所以加了这一节,还是因为多少写过一些 angular,angular 作为框架本身就是全面的,cli 新建的项目自身就带有 unit 测试和 e2e 测试
  unit 测试默认是 karma + jasmine
  e2e 测试默认是 protractor
  也没什么可争辩的,这就是官方解决方案,用起来也方便顺手
  总结
  聊了好多个环境,其实行文目的主要有两方面
  测试思想,如何写好单元测试,主要集中在前半文
  测试工具推荐和相应配置
  测试本身并不复杂,但是想写出高效测试并不容易,千万不要形成为了测试而测试的想法
  用谎言去验证谎言得到的还是谎言。。。
  大多数情况下都是项目在赶进度没空写测试,抽空把测试补上真的是一件值得去做的事情
  
      上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号