最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端2021:vue3.0 VTU-Jest 之第一个单元测试

    正文概述 掘金(GeekQiaQia)   2021-02-07   1125

    前端2021:vue3.0 VTU-Jest 之第一个单元测试

    github:jest/unit 案例

    让我们直接进入主题,通过构建一个简单的例子 Todo App 并编写测试用例来一步一步学习Vue Test Utils(VTU)

    本小结将会覆盖如下:

    • Mount 挂载组件
    • Find 查找元素
    • Fill 填写表单
    • Trigger 触发事件

    起步

    首先搭建项目环境,并选择Unit Testing,这里我们以vue3.0 Typescript 项目举例: 前端2021:vue3.0 VTU-Jest 之第一个单元测试

    TodoApp.vue
    <template>
      <div>
        <div
          v-for="todo in todos"
          :key="todo.id"
          data-test="todo"
          :class="[ todo.completed ? 'completed' : '' ]"
        >
          {{ todo.text }}
          <input
            type="checkbox"
            v-model="todo.completed"
            data-test="todo-checkbox"
          />
        </div>
    
        <form data-test="form" @submit.prevent="createTodo">
          <input data-test="new-todo" v-model="newTodo" />
        </form>
      </div>
    </template>
    
    <script lang="ts">
    import { Options, Vue } from 'vue-class-component';
    
    @Options({
      props: {
        msg: String
      }
    })
    export default class TodoApp extends Vue {
         newTodo='';
          todos=[
            {
              id: 1,
              text: 'Learn Vue.js 3',
              completed: false
            }
          ]
    
     createTodo() {
          this.todos.push({
            id: 2,
            text: this.newTodo,
            completed: false
          })
        }
    }
    </script>
    

    第一个测试用例

    首先我们编写第一个测试用例,验证 todo App 被渲染了,让我们先看一下测试用例,稍后将讨论每一部分:

    完整 TodoApp.spec.js
    import { mount } from '@vue/test-utils'
    import TodoApp from '@/components/TodoApp.vue'
    test('creates a todo', async () => {
        const wrapper = mount(TodoApp)
        expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(1)
      
        await wrapper.get('[data-test="new-todo"]').setValue('New todo')
        await wrapper.get('[data-test="form"]').trigger('submit')
      
        expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(2)
      })
    
      test('completes a todo', async () => {
        const wrapper = mount(TodoApp)
      
        await wrapper.get('[data-test="todo-checkbox"]').setValue(true)
      
        expect(wrapper.get('[data-test="todo"]').classes()).toContain('completed')
      })
    

    首先我们通过 import的方式 导入 mount -这是在VTU中一个主要的渲染组件component 的方法。

    你可以通过 test 方法申明一个测试用例,并简短的表述当前测试用例。testexpect 函数在大多数测试运行程序中都是全局可用的。如果testexpect 仍然感到困惑不解,在 Jest 文档有更加简单明了的例子,来告诉你如何使用它们。

    接下来,我们调用mount并传入一个组件 component 作为第一个参数-这一步几乎是所有的测试用例都会写到的。按照惯例,我们将结果赋值给一个名为wrapper的变量,因为mount为应用提供了一个简单的"wrapper",并提供了一些方便的测试方法。比如 .find.get等等

    最后,我们使用另外一个对于大多数测试用例都通用的 Jest 方法 - expect.它的主要作用是,让我们断言或期待,在这种测试用例情况下实际输出符合我们期望的结果。在这个测试用例中,我们通过选择器data-test="todo"来查找 DOM 元素,如:<div data-test="todo">...</div>。紧接着我们通过调用 call 方法得到 dom内容,也就是我们期望的结果Learn vue.js 3

    执行测试用例:Pass

    yarn test:unit
    

    前端2021:vue3.0 VTU-Jest 之第一个单元测试

    新增一个新的代办项

    接下来我们需要丰富我们的测试用例,我们需要让用户新增创建一个代办项 new todo item.因此我们需要一个form表单,内嵌一个 input输入框,允许用户来输入待办项。当用户点击提交submit,我们期望的结果是新增待办项内容被渲染。让我们看一下以下测试用例:

    import { mount } from '@vue/test-utils'
    import TodoApp from '@/components/TodoApp.vue'
    test('creates a todo',  () => {
        const wrapper = mount(TodoApp)
        expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(1)
      
        wrapper.get('[data-test="new-todo"]').setValue('New todo')
        wrapper.get('[data-test="form"]').trigger('submit')
      
        expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(2)
      })
    
    • 为了更新<input>,我们使用setValue-该方法将使我们 input 的 value 值。
    • 更新<input>后,我们通过trigger方法,模拟用户操作提交表单的行为。
    • 最后我们期望 todo items 的数量将由 1 增加至 2;

    我们使用v-model来动态绑定<input>的value值,使用@submit来监听表单的提交事件,当用户被提交,createTodo将被调用,todos 数组将被插入一个新的代办对象;

    让我们再次执行当前测试用例,发现如下错误: 前端2021:vue3.0 VTU-Jest 之第一个单元测试

    我们期望的 todos 数组对象没有新增,Received length:1;

    原因:

    • Jest 执行测试用例是同步执行的方式,只要用例的最后一个方法执行完毕,则当前用例结束测试。
    • Vue 更新Dom是异步更新机制。

    方案:

    • 我们需要通过async标记测试用例方法,调用await在那些可能改变Dom的异步方法前。比如triggersetValue

    将测试用例修改如下,将会正确通过:

    import { mount } from '@vue/test-utils'
    import TodoApp from '@/components/TodoApp.vue'
    test('creates a todo', async () => {
        const wrapper = mount(TodoApp)
        expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(1)
      
        await wrapper.get('[data-test="new-todo"]').setValue('New todo')
        await wrapper.get('[data-test="form"]').trigger('submit')
      
        expect(wrapper.findAll('[data-test="todo"]')).toHaveLength(2)
      })
    
    

    完成一个待办项

    我们期望用户能够通过一个 checkbox 标记一个待办项是否已经完成的测试用例:

      test('completes a todo', async () => {
        const wrapper = mount(TodoApp)
      
        await wrapper.get('[data-test="todo-checkbox"]').setValue(true)
      
        expect(wrapper.get('[data-test="todo"]').classes()).toContain('completed')
      })
    

    分析测试用例:

    • 我们通过wrapper.get('[data-test="todo-checkbox")来找到checkbox元素;
    • 因为是input类型我们仍然通过setValue方法赋值;
    • 我们断言/期望我们将通过新增一个class类来标记完成状态的待办项。

    总结:

    • 使用 mount() 方法来挂载一个组件。
    • 使用 get() findAll() 方法去查找 DOM。
    • trigger() setValue() 方法用来模拟用户input操作以及表单事件行为.
    • 更新 DOM 是异步操作,因此记得使用 async await

    起源地下载网 » 前端2021:vue3.0 VTU-Jest 之第一个单元测试

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元