最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • VUE单元测试--开启测试之旅

    正文概述 掘金(zhangwinwin)   2020-12-15   495

    前言

    作为程序员,没有比临上线前发现之前的更改的代码导致应用崩溃更糟糕的事了。而唯一能够确保应用正常的工作的只有进行程序的测试。所以说对应用进行全面的测试是很重要的一件事了。

    高效的测试方法可以加快开发速度,提高代码质量,尽早发现并去除代码中的BUG。测试驱动开发(TDD)是一种在编写代码先编写测试代码的工作流程,即在编写代码前,得先编写能够确保组件正常运行的测试代码。

    而单元测试是对应用程序最小的单元运行测试的过程。通常是函数,但在VUE中,组件也是单元,因为组件的本质就是函数。

    下面简单的说说如何使用JEST进行VUE的单元测试。如果不熟悉JESTVUE,建议看看官网。

    示例代码在github

    组件的单元测试

    单元是应用中最小的可测试部分。在VUE中,组件与函数都是可测试的单元。

    搭载测试环境

    对于新项目来说,可以使用VUE-CLI工具创建项目(版本如图所示) VUE单元测试--开启测试之旅 VUE单元测试--开启测试之旅

    只需要在选择配置时☑️Unit Testing,并选择JEST作为测试框架即可。

    而对于现有项目而言(针对@vue/cli)想增加jest测试模块。运行以下命令行就会帮我们去安装jest模块。

    vue add unit-jest
    

    如果你是一个动手能力较强的同学,还可以自己去搭建测试环境,可以参考Vue Test Utils

    好了,现在可以进行单元测试了。

    挂载组件

    当导入一个VUE组件时,它只是一个带有渲染函数和一些属性的对象或者函数。要测试组件行为,则首先得启动它并开启渲染过程。按照VUE的说法就是需要挂载组件。

    挂载组件,需要将组件选项转换为一个VUE构造函数。而组件选项对象不是一个有效的的构造函数,它只是一个普通的JavaScript对象。这时可以使用Vue.extend方法从选项中创建一个VUE构造函数:

    import Vue from 'vue';
    import Home from '@/views/Home.vue';
    const Ctor = Vue.extend(Home);
    

    这时,就可以使用new操作符来创建一个实例:

    const vm = new Ctor();
    

    通常,VUE使用el选项在文档中查找添加的被渲染DOM节点。但一般的组件构造函数并没有el选项,因此在创建实例时,它不会自动挂载并生成DOM节点,需要手动调用$mount方法:

    const vm = new Ctor().$mount()
    

    当调用$mount时,VUE将生成一些DOM节点,可以使用实例中$el属性在测试中访问这些节点:

    expect(vm.$el.textContent).toContain('Welcome to Your Vue.js App')
    

    VUE要使用DOM方法创建一个DOM树。这不意味着VUE组件的单元测试必须在浏览器环境中运行。因为在默认情况下,Jest会在jsdom库创建的浏览器环境中运行测试。jsdom是一个DOM实现,它完全是由运行在DOM中的JavaScript编写的。

    import Vue from 'vue';
    import Home from '@/views/Home.vue';
    
    describe('Home.vue', () => {
      it('renders msg when mounted', () => {
        const msg = 'Welcome to Your Vue.js App';
        // 使用Home选项创建一个新的Vue构造函数
        const Ctor = Vue.extend(Home);
        // 创建一个新的Vue实例并挂载该实例
        const vm = new Ctor().$mount();
        // 访问DOM元素,检查文本内容
        expect(vm.$el.textContent).toContain(msg)
      })
    })
    

    运行yarn run test:unit,测试通过 VUE单元测试--开启测试之旅

    使用Vue Test Utils

    挂载组件需要自己去创建构造函数并且手动挂载。与其自己编写这些代码,不如使用Vue Test Utils库来帮忙实现。

    Vue Test Utils库会让Vue组件单元测试变得更加简单。它包含一些辅助方法可以实现组件挂载、与组件交互以及断言组件输出。

    Vue Test Utils会导出一个mount方法,该方法在接收一个组件后,会将其挂载并返回一个包含被挂载组件实例vm的包装器对象。之所以会返回包装器对象而不直接返回vm实例,是因为包装器不仅仅只有实例vm,还包括一些辅助方法。其中一个方法就是text,它返回实例的textContent

    使用Vue Test Utils库改造刚刚的测试

    import { mount } from '@vue/test-utils';
    import Home from '@/views/Home.vue';
    
    describe('Home.vue', () => {
      it('renders msg when mounted', () => {
        const msg = 'Welcome to Your Vue.js App';
        // 使用mount方法挂载组件
        const wrapper = mount(Home);
        // 检查文本内容
        expect(wrapper.text()).toContain(msg)
      })
    })
    

    使用shallowMount

    除了mount方法,Vue Test Utils还包含一个shallowMount方法。shallowMount不会像mount一样渲染整个组件树,它只渲染一层组件树 VUE单元测试--开启测试之旅mount相似,shallowMount挂载一个组件并返回一个包装器。不同之处在于,shallowMount在挂载组件之前对所有子组件进行存根。

    shallowMount可以确保对一个组件进行独立测试,有助于避免测试中因子组件的渲染输出而混乱结果。

    describe('Home.vue', () => {
      it('renders msg when mounted', () => {
        const msg = 'Welcome to Your Vue.js App';
        // 使用shallowMount方法挂载组件
        const wrapper = shallowMount(Home);
        // 检查文本内容
        expect(wrapper.text()).toContain(msg)
      })
    })
    

    输出测试

    测试prop

    为一个组件编写单元测试时,需要为组件提供生成环境中接收到的输入数据。如果组件在生产环境中接收一个prop,需要在组件挂载到测试时为组件提供该prop

    使用Vue Test Utilsprop作为一个选项对象传递给组件:

    import { shallowMount } from '@vue/test-utils';
    import Hello from '@/components/HelloWorld.vue';
    
    describe('HelloWorld.vue', () => {
      it('renders msg when mounted', () => {
        const msg = 'hello, world';
        // 使用shallowMount方法挂载组件
        const wrapper = shallowMount(Hello, {
          propsData: {
            msg
          }
        });
        // 检查文本内容
        expect(wrapper.text()).toContain(msg)
      })
    })
    

    运行yarn run test:unit,测试通过!

    包装器text方法将返回组件渲染的所有文本。toContain匹配器会检查一个值是否包含在它所检查的字符串中的某个位置,它有点像string.prorotype.includes方法。

    而像上面例子,props中的msg变量是渲染在<h1>标签上的,没有必要去匹配组件下的全部文本,需要测试<h1>标签上的文本是否匹配即可。这时可以使用包装器的find方法。

    find方法可以为渲染输出中的每个节点获取包装器,而且find会搜索与选择器匹配的第一个节点的渲染输出,并返回包含给匹配节点的包装器。

    / 检查文本内容
        expect(wrapper.find('h1').text()).toContain(msg)
    

    并不是所有prop都渲染出文本。所以还要检查组件实例是否接收正确的prop。这时可以使用props方法。

    props方法是一个包装器方法。它返回一个对象,其中包含一个包装器组件实例及它们的值prop

    expect(wrapper.props().msg).toBe(msg)
    

    使用toBe匹配器检查组件所有的渲染文本是否违反此原则。

    还可以检查当前组件传值是否正确

    const wrapper = shallowMount(fatherComponent)
    expect(wrapper.find(ChildComponent).props().propA).toBe('example')
    

    这里需要注意的是,如果一个组件未声明要接收一个prop,则prop不会被添加到这个Vue实例中。

    测试DOM属性

    Vue Test Utils包装器中,有一个attribute方法,可以返回组件属性对象。可以使用该对象来测试属性值

    const a = wrapper.find('a');
    expect(a.attributes().href === 'http://cli.vuejs.org').toBa(true)
    

    VUE单元测试--开启测试之旅 错误信息显示:期望是true,返回的是false。这是一个Boolean断言,这样的信息并没有很清晰的了解到测试为什么会失败,所以应该要避免Boolean断言。应该使用值断言代替它 VUE单元测试--开启测试之旅 这样就非常清楚是哪里的问题导致测试失败了。

    测试样式

    Vue Test Utils包装器中,有一个classes方法,返回一个class数组。可以对此进行断言,查看元素是否具有一个class

    expect(a.classes()).toContain('firstA')
    

    toContain匹配器不仅可以检查一个字符串中是否包含另一个字符串,还能比较数组中的值。

    通常来说测试内联样式是没有价值的,但有时候不得不去测试一个内联样式。比如说:进度条组件,动态地添加一个内联样式。这时就需要直接访问包装器元素并获取样式属性值。

    每一个包装器都包含一个element属性,它是对包装器包含的DOM根节点的引用。可以使用它来访问内联元素

    expect(a.element.style.fontSize).toBe('14px')
    

    结尾

    由于篇幅原因,这次测试之旅第一天就结束了,下次再继续。阅读完,如果觉得有帮助的请点点赞,支持一下。

    更多文章请移步楼主github,如果喜欢请点一下star,对作者也是一种鼓励。


    下载网 » VUE单元测试--开启测试之旅

    常见问题FAQ

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

    发表评论

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

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

    联系作者

    请选择支付方式

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