Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >实例入门 Vue.js 单元测试

实例入门 Vue.js 单元测试

作者头像
江米小枣
发布于 2020-06-15 13:50:47
发布于 2020-06-15 13:50:47
3K00
代码可运行
举报
文章被收录于专栏:云前端云前端
运行总次数:0
代码可运行

作为一个以 文档丰富 而广为人知的前端开发框架, Vue.js 的官方文档中分别在《教程-工具-单元测试》、《Cookbook-Vue组件的单元测试》里对 Vue 组件的单元测试方法做出了介绍,并提供了官方的单元测试实用工具库 Vue Test Utils;甚至在状态管理工具 Vuex 的文档里也不忘留出《测试》一章。

那是什么原因让 Vue.js 的开发团队如此重视单元测试,要在这个同样以 易于上手 为卖点的框架中大力科普呢?

官方文档中给出了非常清楚的说法:

组件的单元测试有很多好处:- 提供描述组件行为的文档 - 节省手动测试的时间 - 减少研发新特性时产生的 bug - 改进设计 - 促进重构自动化测试使得大团队中的开发者可以维护复杂的基础代码。

本文作为《对 React 组件进行单元测试》一文的姊妹篇,将照猫画虎式的尝试面对初学和向中级进阶的开发者,对单元测试在 Vue.js 技术栈 中的应用做出入门介绍。

I. 单元测试简介

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。

简单来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

对于开发活动中的各种测试,上图是一种最常见的划分方法:从下至上依次为 单元测试->集成测试->端到端测试 ,随着其集成度的递增,对应的自动化程度递减。

端到端(在浏览器等真实场景中走通功能而把程序当成黑盒子的测试)与集成测试(集合多个测试过的单元一起测试)的反馈与修复的周期比较长、运行速度慢,测试运行不稳定,由于很多时候还要靠人工手动进行,维护成本也很高。而单元测试只针对具体一个方法或API,定位准确,采用 mock 机制,运行速度非常快(毫秒级),又是开发人员在本地执行,反馈修复及时,成本较低。

我们把绝大部分能在单元测试里覆盖的用例都放在单元测试覆盖,只有单元测试测不了的,才会通过端到端与集成测试来覆盖。

讲解单元测试的具体概念之前,先 咀个栗子 直观了解下:

比如我们有这样一个模块,暴露两个方法用以对菜单路径进行一些处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// src/menuChecker.jsexport function getRoutePath(str) {
 let to = ""
 //...
 return to;
}export function getHighlight(str) {
 let hl = "";
 //...
 return hl;
}

编写对应的测试文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import {
 getRoutePath,
 getHighlight
} from "@/menuChecker";describe("检查菜单路径相关函数", ()=>{ it("应该获得正确高亮值", ()=>{
   expect( getHighlight("/myworksheet/(.*)") ).toBe("myTickets");
 }); it("应该为未知路径取得默认的高亮值", ()=>{
   expect( getHighlight("/myworksheet/ccc/aaa") ).toBe("mydefaulthl111");
 }); it("应该补齐开头的斜杠", ()=>{
   expect( getRoutePath("/worksheet/list") ).toBe('/worksheet/list');
 }); it("应该能修正非法的路径", ()=>{
   expect( getRoutePath("/myworksheet/(.*)") ).toBe("/myworksheet/list");
 });
});

运行该测试文件,得到如下输出:

运行结果可以说非常友好了,虽然醒目的提示了 FAIL,但是哪条判断错了、错在哪一行、实际的返回值与预期的区别,甚至代码覆盖率的表格,都分别展示了出来;尤其是最重要的对错结果,分别用绿色红色加以展示。

真相只有一个,要么是目标模块写的有问题,要么是测试条件写错了 -- 总之我们对其修正后重新运行:

由此,我们对一次单元测试的过程有了基本的了解。

首先,对所谓“单元”的定义是灵活的,可以是一个函数,可以是一个模块,也可以是一个 Vue Component。

其次,由于测试结果中,成功的用例会用绿色表示,而失败的部分会显示为红色,所以单元测试也常常被称为 “Red/Green Testing” 或 “Red/Green Refactoring”,其一般步骤可以归纳为:

  1. 添加一个测试
  2. 运行所有测试,看看新加的这个测试是不是失败了;如果能成功则重复步骤1
  3. 根据失败报错,有针对性的编写或改写代码;这一步的唯一目的就是通过测试,先不必纠结细节
  4. 再次运行测试;如果能成功则跳到步骤5,否则重复步骤3
  5. 重构已经通过测试的代码,使其更可读、更易维护,且不影响通过测试
  6. 重复步骤1,直到所有功能测试完毕

1.1 测试框架

测试框架的作用是提供一些方便的语法来描述测试用例,以及对用例进行分组。

1.2 断言(assertions)

断言是单元测试框架中核心的部分,断言失败会导致测试不通过,或报告错误信息。

对于常见的断言,举一些例子如下:

  • 同等性断言 Equality Asserts
    • expect(sth).toEqual(value)
    • expect(sth).not.toEqual(value)
  • 比较性断言 Comparison Asserts
    • expect(sth).toBeGreaterThan(number)
    • expect(sth).toBeLessThanOrEqual(number)
  • 类型性断言 Type Asserts
    • expect(sth).toBeInstanceOf(Class)
  • 条件性测试 Condition Test
    • expect(sth).toBeTruthy()
    • expect(sth).toBeFalsy()
    • expect(sth).toBeDefined()

1.3 断言库

断言库主要提供上述断言的语义化方法,用于对参与测试的值做各种各样的判断。这些语义化方法会返回测试的结果,要么成功、要么失败。常见的断言库有 Should.js, Chai.js 等。

1.4 测试用例 test case

为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。

一般的形式为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
it('should ...', function() {
   ...
       
   expect(sth).toEqual(sth);
});

1.5 测试套件 test suite

通常把一组相关的测试称为一个测试套件

一般的形式为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
describe('test ...', function() {
   
   it('should ...', function() { ... });
   
   it('should ...', function() { ... });
   
   ...
   
});

1.6 spy

正如 spy 字面的意思一样,我们用这种“间谍”来“监视”函数的调用情况

通过对监视的函数进行包装,可以通过它清楚的知道该函数被调用过几次、传入什么参数、返回什么结果,甚至是抛出的异常情况。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var spy = sinon.spy(MyComp.prototype, 'someMethod');

...

expect(spy.callCount).toEqual(1);

1.7 stub

有时候会使用stub来嵌入或者直接替换掉一些代码,来达到隔离的目的

一个stub可以使用最少的依赖方法来模拟该单元测试。比如一个方法可能依赖另一个方法的执行,而后者对我们来说是透明的。好的做法是使用stub 对它进行隔离替换。这样就实现了更准确的单元测试。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var myObj = {
    prop: function() {
        return 'foo';
    }
};

sinon.stub(myObj, 'prop').callsFake(function() {
    return 'bar';
});

myObj.prop(); // 'bar'

1.8 mock

mock一般指在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法

广义的讲,以上的 spy 和 stub 等,以及一些对模块的模拟,对 ajax 返回值的模拟、对 timer 的模拟,都叫做 mock 。

1.9 测试覆盖率(code coverage)

用于统计测试用例对代码的测试情况,生成相应的报表,比如 istanbul 是常见的测试覆盖率统计工具。

istanbul 也就是土耳其首都 “伊斯坦布尔”,这样命名是因为土耳其地毯世界闻名,而地毯是用来"覆盖"的?。

回顾一下上面的图:

表格中的第2列至第5列,分别对应了四个衡量维度:

  • 语句覆盖率(statement coverage):是否每个语句都执行了
  • 分支覆盖率(branch coverage):是否每个if代码块都执行了
  • 函数覆盖率(function coverage):是否每个函数都调用了
  • 行覆盖率(line coverage):是否每一行都执行了

测试结果根据覆盖率被分为“绿色、黄色、红色”三种,应该关注这些指标,测试越全面,就能提供更高的保证。

同时也没有必要一味追求行覆盖率,因为它会导致我们过分关注组件的内部实现细节,从而导致琐碎的测试。

II. Vue.js 中的单元测试工具

2.1 Jest

不同于"传统的"(其实也没出现几年)的 jasmine / Mocha / Chai 等前端测试框架;Jest的使用更简单(也许就是这个单词的本意“俏皮话、玩笑话”的意思),并且提供了更高的集成度、更丰富的功能。

Jest 是一个由 Facebook 开发的测试运行器,相对其他测试框架,其特点就是就是内置了常用的测试工具,比如自带断言、测试覆盖率工具,实现了开箱即用。

此外, Jest 的测试用例是并行执行的,而且只执行发生改变的文件所对应的测试,提升了测试速度。

配置

Jest 号称自己是一个 “Zero configuration testing platform”,只需在 npm scripts里面配置了test: jest,即可运行npm test,自动识别并测试符合其规则的( Vue.js 项目中一般是 __tests__ 目录下的)用例文件。

实际使用中,适当的在 package.json 的 jest 字段或独立的 jest.config.js 里自定义配置一下,会得到更适合我们的测试场景。

参考文档 https://vue-test-utils.vuejs.org/zh/guides/testing-single-file-components-with-jest.html ,可以很快在 Vue.js 项目中配置好 Jest 测试环境。

四个基础单词

编写单元测试的语法通常非常简单;对于jest来说,由于其内部使用了 Jasmine 2 来进行测试,故其用例语法与 Jasmine 相同。

实际上,只要先记这住四个单词,就足以应付大多数测试情况了:

  • describe: 定义一个测试套件
  • it:定义一个测试用例
  • expect:断言的判断条件
  • toEqual:断言的比较结果
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
describe('test ...', function() {
   it('should ...', function() {
       expect(sth).toEqual(sth);
       expect(sth.length).toEqual(1);
       expect(sth > oth).toEqual(true);
   });
});

2.2 sinon

图中这位“我牵着马”的并不是卷帘大将沙悟净...其实图中的故事正是人所皆知的“特洛伊木马”;大概意思就是希腊人围困了特洛伊人十多年,久攻不下,心生一计,把营盘都撤了,只留下一个巨大的木马(里面装着士兵),以及这位被扒光还被打得够呛的人,也就是此处要谈的主角 sinon,由他欺骗特洛伊人 --- 后面的剧情大家就都熟悉了。

所以这个命名的测试工具呢,也正是各种伪装渗透方法的合集,为单元测试提供了独立而丰富的 spy, stub 和 mock 方法,兼容各种测试框架。

虽然 Jest 本身也有一些实现 spy 等的手段,但 sinon 使用起来更加方便。

2.3 Vue Test Utils

Vue Test Utils 是 Vue.js 官方的单元测试实用工具库;该工具库使用起来和用以测试 React 组件的 Enzyme 工具库非常相似

它模拟了一部分类似 jQuery 的 API,非常直观并且易于使用和学习,提供了一些接口和几个方法来减少测试的样板代码,方便判断、操纵和遍历 Vue Component 的输出,并且减少了测试代码和实现代码之间的耦合。

一般使用其 mount()shallowMount() 方法,将目标组件转化为一个 Wrapper 对象,并在测试中调用其各种方法,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { mount } from '@vue/test-utils'
import Foo from './Foo.vue'

describe('Foo', () => {
  it('renders a div', () => {
    const wrapper = mount(Foo)
    expect(wrapper.contains('div')).toBe(true)
  })
})

III. 一个 Vue.js 的单元测试实例

3.1 又一个栗子

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { shallowMount } from "@vue/test-utils";
import Vue from 'vue';
import VueI18n from 'vue-i18n';
import i18nMessage from '@/i18n';
import Comp from "@/components/Device.vue";

const fakeData = { //假数据
  deviceNo: "abcdefg",
  deviceSpace: 45,
  deviceStatus: 2,
  devices: [
    {
      id: "test001",
      location: "12",
      status: 1
    },
    {
      id: "test002",
      location: "58",
      status: 3
    },
    {
      id: "test003",
      location: "199",
      status: 4
    }
  ]
};


Vue.use(VueI18n); //重现必要的依赖
const i18n = new VueI18n({
  locale: 'zh-CN',
  silentTranslationWarn: true,
  missing: (locale, key, vm) => key,
  messages: i18nMessage
});

let wrapper = null;
const makeWrapper = ()=>{
  wrapper = shallowMount( Comp, {
    i18n, //看这里
    propsData: { //还有这里
      unitHeight: 5,
      data: fakeData
    }
  } );
};

afterEach(()=>{ //也很常见的用法
    if (!wrapper) return;
    wrapper = null;
});

describe("test Device.vue", ()=>{

  it("should be a VUE instance", ()=>{
    makeWrapper();
    expect( wrapper.isVueInstance() ).toBeTruthy();
  });

  it("应该有正常的总高度", ()=>{
    makeWrapper();
    expect( wrapper.vm.totalHeight ).toBe( 1230 );
  });

  it("应该渲染正确的设备数量", ()=>{
    makeWrapper();
    expect( wrapper.findAll('.deviceitem').length ).toBe( 3 );
  });

  it("指定的设备应该在正确的位置", ()=>{
    makeWrapper();
    const sty = wrapper.findAll('.deviceitem').at(1).attributes('style');
    expect( sty ).toMatch( /height\:\s*20px/ );
    expect( sty ).toMatch( /bottom\:\s*20px/ );
  });

  it("应该渲染正确的tooltip", ()=>{
    makeWrapper();

    //这里的用法值得注意
    const popper_ref = wrapper.find({ref: 'device_tooltip_test002'});
    expect( popper_ref.exists() ).toBeTruthy();

    const cont = popper_ref.find('.tooltip_cont');
    expect( cont.html() ).toMatch(/所在位置\:\s58/);
  });
  
  it("应该渲染正确的设备分类", ()=>{
    makeWrapper();

    const badge = wrapper.find('.badge');
    expect( badge.exists() ).toBeTruthy();

    expect( badge.findAll('li').length ).toBe(4);
    expect( badge.findAll('li').at(2).text() ).toBe('喷雾设备');
    });
    
  it("当点击了关闭按钮,应该不再显示", (done)=>{ //异步的用例
    makeWrapper();
    wrapper.vm.$nextTick(()=>{ //再看这里
      expect( 
        wrapper.find('.devices_container').exists()
      ).toBeFalsy();
      done();
    });
  });

});

这里无需逐条的解释,主要的 API 在 JestVue Test Utils 的文档里都能找到。

其中值得注意的小经验,一是一些异步更新(比如代码中有延时)后正确使用 wrapper.vm.$nextTick;二是对于一些挂载到 document.body 等外部位置的组件元素,要靠 wrapper.find({ref: xxx}) 取得其引用。

3.2 整合到工作流中

写好的单元测试,如果仅仅要靠每次 npm test 手动执行,必然会有日久忘记、逐渐过时,最后甚至无法执行的情况。

有多个时间点可以作为选择,插入自动执行单元测试 -- 例如每次保存文件、每次执行 build 等;此处我们选择了一种很简单的配置办法:

首先在项目中安装 pre-commit 依赖包;然后在 package.json 中配置 npm scripts :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"scripts": {
 ...
 "test": "jest"
},
"pre-commit": [
 "test"
],

这样在每次 git commit 之前,项目中存在的单元测试就会自动执行一次,往往就避免了 “改一个 bug,送十个新 bug” 的窘况。

IV. 用单元测试改善 Vue.js 组件

单元测试除了减少错误,另一个显著的好处是能让我们组件化的思路越来越清晰,养成日益良好的习惯。

一个被验证过针对给定的输入会渲染出符合期望的输出的组件,称为 测试通过的 组件; 一个 可测试的(testable) 组件意味着其易于测试

如何确保一个组件如期望的工作呢?

我们可能习惯于依靠双手和眼睛,一次次的验证我们写过的组件;但如果你打算对每个组件的每个改动都手动验证的话,或早或晚就会因为疲惫或懈怠,导致瑕疵留在代码中。

这就是自动化的单元测试为何重要的原因。单元测试保证了每次对组件做出的更改后,组件都能正确工作。

单元测试并不只与早期发现 bug 有关。另一个重要的方面是用其检验组件架构化水平优劣的能力。

一个 无法测试难以测试 的组件,基本上就等同于 设计得很拙劣 的组件.

组件之所以难以测试,是因为其有太多的 props、依赖、引用的模型和对全局变量的访问 -- 这都是不良设计的标志。

一个设计不佳的组件,就会变成无法测试的,进而你就会简单的跳过单元测试,又导致了其保持未测试状态,变成一个恶性循环。

4.1 希望是最后一个栗子

假设要对 NumStepper.vue 组件进行测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//NumStepper.vue

<template>
  <div>
    <button class="plus" v-on:click="updateNumber(+1)"></button>
    <button class="minus" v-on:click="updateNumber(-1)"></button>
    <button class="zero" v-on:click="clear"></button>
  </div>
</template>

<script>
export default {
  props: {
    targetData: Object,
    clear: Function
  },
  methods: {
    updateNumber: function(n) {
      this.targetData.num += n;
    }
  }
}
</script>

该组件又依赖一个外层组件给其提供数据和方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//NumberDisplay.vue

<template>
  <div>
    <p>{{somedata.num}}</p>
    <NumStepper :targetData="somedata" :clear="clear" />
  </div>
</template>

<script>
import NumStepper from "./NumStepper"

export default {
  components: {
    NumStepper
  },
  data() {
    return {
      somedata: {
        num: 999
      },
      tgt: this
    }
  },
  methods: {
    clear: function() {
      this.somedata.num = 0;
    }
  }
}
</script>

这样一来,我们的测试就得这样写:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { shallowMount } from "@vue/test-utils";
import Vue from 'vue';
import NumStepper from '@/components/NumStepper';
import NumberDisplay from '@/components/NumberDisplay';

describe("测试 NumStepper 组件", ()=>{
  it("应该能够影响外层组件的数据", ()=>{

    const display = shallowMount(NumberDisplay);

    const wrapper = shallowMount(NumStepper, {
      propsData: {
        targetData: display.vm.somedata,
        clear: display.vm.clear
      }
    });

    expect(display.vm.somedata.num).toBe(999);

    wrapper.find('.plus').trigger('click');
    wrapper.find('.plus').trigger('click');
    expect(display.vm.somedata.num).toBe(1001);

    wrapper.find('.minus').trigger('click');
    expect(display.vm.somedata.num).toBe(1000);

    wrapper.find('.zero').trigger('click');
    expect(display.vm.somedata.num).toBe(0);
  })
});

<NumStepper> 测试起来非常复杂,因为它关联了外部组件的实现细节。

测试场景中需要一个额外的 <NumberDisplay> 组件,用来重现外部组件、向目标组件传递数据和方法,并检验目标组件是否正确修改了外部组件的状态。

不难想象,假如 <NumberDisplay> 组件再依赖其他组件或环境变量、全局方法等,事情将变得更糟糕,可能需要单独实现若干测试专用组件,甚至根本无法测试。

4.2 真正的最后一个栗子

<NumStepper> 独立于外部组件的细节时,测试就简单了。让我们实现并测试一下合理封装版本的 <NumStepper> 组件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//NumStepper2.vue

<template>
  <div>
    <button class="plus" v-on:click="updateFunc(+1)"></button>
    <button class="minus" v-on:click="updateFunc(-1)"></button>
    <button class="zero" v-on:click="clearFunc"></button>
  </div>
</template>

<script>
export default {
  props: {
    updateFunc: Function,
    clearFunc: Function
  }
}
</script>

在测试中,就不用引入额外的组件了:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { shallowMount } from "@vue/test-utils";
import Vue from 'vue';
import NumStepper from '@/components/NumStepper2';

describe("测试 NumStepper 组件", ()=>{
  it("应该能够影响外层组件的数据", ()=>{

    const obj = {
      func1: function(){},
      func2: function(){}
    };

    const spy1 = jest.spyOn(obj, "func1");
    const spy2 = jest.spyOn(obj, "func2");

    const wrapper = shallowMount(NumStepper, {
      propsData: {
        updateFunc: spy1,
        clearFunc: spy2
      }
    });

    wrapper.find('.plus').trigger('click');
    expect(spy1).toHaveBeenCalled();

    wrapper.find('.minus').trigger('click');
    expect(spy1).toHaveBeenCalled();

    wrapper.find('.zero').trigger('click');
    expect(spy2).toHaveBeenCalled();
  })
});

注:该示例中只是检验了是否被点击,还可以引入 sinon 的相关方法检验传入的参数等,写出更完备的测试。

V. 总结

单元测试作为一种经典的开发和重构手段,在软件开发领域被广泛认可和采用;前端领域也逐渐积累起了丰富的测试框架和方法。

单元测试可以为我们的开发和维护提供基础保障,使我们在思路清晰、心中有底的情况下完成对代码的搭建和重构。

封装好则测试易,反之不恰当的封装让测试变得困难。

可测试性是一个检验组件结构良好程度的实践标准。

VI. 参考资料

  • https://mp.weixin.qq.com/s/9wLF5bmj_xDijq00GjDsvw
  • https://blog.csdn.net/xqtesting/article/details/38113153
  • https://www.jianshu.com/p/ec40734c872a
  • https://www.jianshu.com/p/ffd6d319f05b
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Vue-Test-Utils + Jest 单元测试入门与实践
vs code打开项目你会发现根目录下有一目录test/unit,里面就有一个已经生成的测试用例。
用户6094182
2020/03/20
2.7K0
你不知道的 Vue 单元测试(6000字实战单元测试)
Vue-Test-Utils 是 Vue.js 官方的单元测试实用工具库,它提供了一系列的 API 来使得我们可以很便捷的去写 Vue 应用中的单元测试。
一只图雀
2020/10/26
11.7K0
你不知道的 Vue 单元测试(6000字实战单元测试)
前端单元测试那些事
Jest 是 Facebook 开源的一款 JS 单元测试框架,它也是 React 目前使用的单元测试框架,目前vue官方也把它当作为单元测试框架官方推荐 。 目前除了 Facebook 外,Twitter、Airbnb 也在使用 Jest。Jest 除了基本的断言和 Mock 功能外,还有快照测试、实时监控模式、覆盖度报告等实用功能。 同时 Jest 几乎不需要做任何配置便可使用。
树酱
2020/07/03
4.6K0
前端单元测试那些事
[译] Vue 3 Composition API 之单元测试
原文:https://itnext.io/testing-the-composition-api-fae3bae3f592
江米小枣
2020/06/15
1.7K0
Vue 应用单元测试的策略与实践 04 - Vuex 单元测试
2.2 在 Vue 应用的单元测试中,对 Vuex store 该如何测试?如何测试与 Vue 组件之间的交互?
JimmyLv_吕靖
2019/09/10
1.7K0
Vue 应用单元测试的策略与实践 04 - Vuex 单元测试
原创干货:前端单元测试Jest零基础入门教学
其实单元测试,就是先编写单元测试代码,然后使用单元测试框架,去模拟环境(例如浏览器),然后运行你的代码,看代码是否按预期运行
Peter谭金杰
2020/05/09
1.2K0
原创干货:前端单元测试Jest零基础入门教学
Vue 应用单元测试的策略与实践 03 - Vue 组件单元测试
2.1 在 Vue 应用的单元测试中,对不同 UI 组件的单元测试有何不同?颗粒度该细到什么样的程度?
JimmyLv_吕靖
2019/09/10
1.3K0
Vue 应用单元测试的策略与实践 03 - Vue 组件单元测试
也来扯扯 Vue 单元测试
从使用 Vue 写出第一个 Hello world 到现在已经有近两年时间了,期间利用业余时间折腾了一套组件 we-vue,起初是出于实践学到的新知识,更多的是玩的意思,不过后来维护的过程中渐渐积累了一些经验,并开始享受这种过程。 在 we-vue 更新到 v2.0 的时候,开始全面地编写单元测试。起先使用 karma + mocha + chrome-headless 这种组合完成的行级覆盖率达到 96% 的测试。但最近,我又放弃了这种组合,转而使用 Jest。在这连番的折腾中,入过不少坑(当然,很多时
overtrue
2018/07/05
1.9K0
[译] Vuex 之单元测试
原文:https://lmiller1990.github.io/vue-testing-handbook/testing-vuex.html
江米小枣
2020/06/15
3.4K0
Vue 测试速成班
在你快要完成一个项目时,突然工程里的很多地方都出现了 bug,你修完一个又冒出新的一个,就像在玩打地鼠游戏一样……几轮下来,你会感到一团糟。
WecTeam
2020/02/11
2.9K0
Vue 测试速成班
[译] Vue Router 之单元测试
原文:https://github.com/tonylua/vue-testing-handbook/blob/master/src/zh-CN/vue-router.md
江米小枣
2020/06/15
2K0
【Web技术】639- Web前端单元测试到底要怎么写?
随着 Web 应用的复杂程度越来越高,很多公司越来越重视前端单元测试。我们看到的大多数教程都会讲单元测试的重要性、一些有代表性的测试框架 api 怎么使用,但在实际项目中单元测试要怎么下手?测试用例应该包含哪些具体内容呢?
coder_koala
2020/07/15
3.2K0
【Web技术】639- Web前端单元测试到底要怎么写?
如何自动化测试 React Native 项目 (下篇) - 单元测试
接着上篇的内容, 这篇文章会详细的介绍在 Glow 我们如何写单元测试, 以及在 React Native 中各个模块单元测试的详细实现方式。
Java帮帮
2019/05/17
3.4K0
如何自动化测试 React Native 项目 (下篇) - 单元测试
React + Redux Testing Library 单元测试
谈任何东西都一定要有个上下文。你的论述不能是「因为单元测试有这些好处,所以我们要做单元测试」,而应该是「不做单元测试我们会遇到什么问题」,这样才能回答「为什么要写单元测试」的问题。那么我们谈论单元测试的上下文是什么呢?不做单元测试我们会遇到什么问题呢?上图为一个产品从 idea 分析、设计、开发、测试到交付并获取市场反馈的过程。
JimmyLv_吕靖
2021/03/03
2.5K0
React + Redux Testing Library 单元测试
【架构师(第二十九篇)】Vue-Test-Utils 触发事件和异步请求
---- 知识点 将 mock 对象断言为特定类型 使用 jest.Mocked<T> 使用 it.only 来指定测试的 case 使用 skip 跳过指定测试的 case 测试内容 触发事件 trigger 方法 测试界面是否更新 特别注意 DOM 更新是个异步的过程 使用 async await 更新表单 setValue 方法 验证事件是否发送 emitted 方法 测试异步请求 模拟第三方库实现 测试准备和结束 可以使用内置的一些钩子来简化一些通用的逻辑,以下钩子用于一次性完成测试准备。 b
一尾流莺
2022/12/10
9550
【架构师(第二十九篇)】Vue-Test-Utils 触发事件和异步请求
全面掌握 Vue.js 测试体系:单元测试与端到端测试全攻略
测试是软件开发中不可或缺的一部分。在 Vue.js 项目中,通过合理的测试体系可以提升代码的可靠性与可维护性。本文将介绍如何使用 Jest 和 Cypress 在 Vue.js 项目中构建全面的单元测试和端到端测试体系,结合可运行的代码示例,帮助开发者快速上手并应用于实际项目。
Swift社区
2025/01/09
2840
全面掌握 Vue.js 测试体系:单元测试与端到端测试全攻略
vue中关于测试的介绍
Vue-Cli 推荐两种测试分别是:端到端的测试(E2E) 和 单元测试(Unit Test) 一、端到端(E2E): 端(消费端)到端(产品端)的测试(E2E (End-to-End)), 它用来测试一个应用从头到尾的流程是否和设计时候所想的一样。简而言之,它从一个用户的角度出发,认为整个系统都是黑箱,只有UI会暴露给用户 二、单元测试(Unit Test): 测试驱动开发(TDD: Test-Driven Development), 单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。 Vue中的单元测试中有( Jest +Karma+ Mocha(Chai) ) Karma: Karma是一 个基于Node.js的JavaScript测试执行过程管理工具( Test Runner)。该工具在Vue中的主要作用是将项目运行在各种主流Web浏览器进行测试。 换句话说,它是一个测试工具,能让你的代码在浏览器环境下测试。需要它的原因在于,你的代码可能是设计在浏览器端执行的,在node环境下测试可能有些bug暴露不出来;另外,浏览器有兼容问题, karma提供了手段让你的代码自动在多个浏览器( chrome,firefox ,ie等)环境下运行。 如果你的代码只会运行在node端,那么你不需要用karma。 Mocha mocha(摩卡)是一个测试框架,在vue-cli中配合。mocha本身不带断言卡,所以必须先引入断言库,Chai断言库实现单元测试。 Mocha的常用命令和用法不算太多,而Chai断言库可以看Chai.js断言库API中文文档,很简单,多查多用就能很快掌 握。 断言库 所谓“断言” ,就是判断源码的实际执行结果与预期结果是否-致,如果不一致就抛出一个错误。下面这句断言的意思是,调用add(1, 1) ,结果应该等于2. 复制代码
用户9914333
2022/07/21
1K0
vue中关于测试的介绍
提高代码质量——使用Jest和Sinon给已有的代码添加单元测试
在日常的功能开发中,我们的代码测试都依赖于自己或者QA进行测试。这些操作不仅费时费力,而且还依赖开发者自身的驱动。在开发一些第三方依赖的库时,我们也没有办法给第三方提供完整的代码质量报告。
黄Java
2018/09/18
4K0
87.HarmonyOS NEXT 单元测试与自动化测试指南:构建可靠的测试体系
通过建立完善的测试体系,可以有效保证应用的质量和稳定性。在实际开发中,要根据项目特点选择合适的测试策略,并持续优化测试流程。
全栈若城
2025/03/16
820
用 jest 单元测试改善老旧的 Backbone.js 项目
对于早期的前端 SPA 项目,Backbone.js + Require.js 是一种常见的技术组合,分别提供了基础的 MVC 框架和模块化能力。
江米小枣
2020/06/16
3.7K0
用 jest 单元测试改善老旧的 Backbone.js 项目
推荐阅读
相关推荐
Vue-Test-Utils + Jest 单元测试入门与实践
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验