React组件测试,尝试一下

前言:为什么要有进行自动化测试?

经过测试的组件是可靠的,可测试的组件架构是合理的,如果一个组件难以编写测试用例,只能证明组件的设计是糟糕的;编写组件用例的同时,可以帮助组件开发者发现问题,调整代码使架构更加合理。

  1. 测试可以确保得到预期的结果
  2. 作为现有代码行为的描述
  3. 促使开发者写可测试的代码,一般可测试的代码可读性也会高一点
  4. 如果依赖的组件有修改,受影响的组件能在测试中发现错误

为什么React特别适合组件测试?

1.React是组件化的

2.Functional Component:纯函数是最好写测试的 固定的输入有固定的输出

3.单向数据流:组件不会随便修改外面传入的数据

测试类型

  • 单元测试:指的是以原件的单元为单位,对软件进行测试。“单元”的定义取决于自己。如果你正在使用函数式编程,一个单元最有可能指的是一个函数。你的单元测试将使用不同的参数调用这个函数,并断言它返回了期待的结果;在面向对象语言里,下至一个方法,上至一个类都可以是一个单元(从一个单一的方法到一整个的类都可以是一个单元)。 即 单元可以是一个函数,也可以是一个模块或一个组件,基本特征就是只要输入不变,必定返回同样的输出。一个软件越容易些单元测试,就表明它的模块化结构越好,给模块之间的耦合越弱。React的组件化和函数式编程,天生适合进行单元测试。
  • 功能测试:相当于是黑盒测试,测试者不了解程序的内部情况,不需要具备编程语言的专门知识,只知道程序的输入、输出和功能,从用户的角度针对软件界面、功能和外部结构进行测试,不考虑内部的逻辑
  • 集成测试:在单元测试的基础上,将所有模块按照设计要求组装成子系统或者系统,进行测试
  • 冒烟测试:在正式全面的测试之前,对主要功能进行的与测试,确认主要功能是否满足需要,软件是否能正常运行

详解

我们的单元测试,既可以针对一个函数写case,也可以按照函数的调用关系串起来写case。 金字塔模型

在金字塔模型之前,流行的是冰淇淋模型。包含了大量的手工测试、端到端的自动化测试及少量的单元测试。造成的后果是,随着产品壮大,手工回归测试时间越来越长,质量很难把控;自动化case频频失败,每一个失败对应着一个长长的函数调用,到底哪里出了问题?单元测试少的可怜,基本没作用。

Mike Cohn 在他的着作《Succeeding with Agile》一书中提出了**“测试金字塔”**这个概念。这个比喻非常形象,它让你一眼就知道测试是需要分层的。它还告诉你每一层需要写多少测试。 测试金字塔本身是一条很好的经验法则,我们最好记住Cohn在金字塔模型中提到的两件事:

  • 编写不同粒度的测试
  • 层次越高,你写的测试应该越少

同时,我们对金字塔的理解绝不能止步于此,要进一步理解: 我把金字塔模型理解为——冰激凌融化了。就是指,最顶部的“手工测试”理论上全部要自动化,向下融化,优先全部考虑融化成单元测试,单元测试覆盖不了的 放在中间层(分层测试),再覆盖不了的才会放到UI层。因此,UI层的case,能没有就不要有,跑的慢还不稳定。按照乔帮主的说法,我不分单元测试还是分层测试,统一都叫自动化测试,那就应该把所有的自动化case看做一个整体,case不要冗余,单元测试能覆盖,就要把这个case从分层或ui中去掉。 越是底层的测试,牵扯到相关内容越少,而高层测试则涉及面更广。比如单元测试,它的关注点只有一个单元,而没有其它任何东西。所以,只要一个单元写好了,测试就是可以通过的;而集成测试则要把好几个单元组装到一起才能测试,测试通过的前提条件是,所有这些单元都写好了,这个周期就明显比单元测试要长;系统测试则要把整个系统的各个模块都连在一起,各种数据都准备好,才可能通过。 另外,因为涉及到的模块过多,任何一个模块做了调整,都有可能破坏高层测试,所以,高层测试通常是相对比较脆弱的,在实际的工作中,有些高层测试会牵扯到外部系统,这样一来,复杂度又在不断地提升。 

为什么做单测

  • 单元测试对我们的产品质量是非常重要的。
  • 单元测试是所有测试中最底层的一类测试,是第一个环节,也是最重要的一个环节,是唯一一次有保证能够代码覆盖率达到100%的测试,是整个软件测试过程的基础和前提,单元测试防止了开发的后期因bug过多而失控,单元测试的性价比是最好的。
  • 据统计,大约有80%的错误是在软件设计阶段引入的,并且修正一个软件错误所需的费用将随着软件生命期的进展而上升。错误发现的越晚,修复它的费用就越高,而且呈指数增长的趋势。作为编码人员,也是单元测试的主要执行者,是唯一能够做到生产出无缺陷程序这一点的人,其他任何人都无法做到这一点
  • 代码规范、优化,可测试性的代码
  • 放心重构
  • 自动化执行three-thousand times

技术选型之Jest——通用测试框架

一、特点

Jest是Facebook开源的一个前端测试框架,主要用于React和React Native的单元测试,已被集成在create-react-app中。Jest特点:

  1. 易用性:基于Jasmine,提供断言库,支持多种测试风格
  2. 适应性:Jest是模块化、可扩展和可配置的
  3. 沙箱和快照:Jest内置了JSDOM,能够模拟浏览器环境,并且并行执行
  4. 快照测试:Jest能够对React组件树进行序列化,生成对应的字符串快照,通过比较字符串提供高性能的UI检测
  5. Mock系统:Jest实现了一个强大的Mock系统,支持自动和手动mock
  6. 支持异步代码测试:支持Promise和async/await
  7. 自动生成静态分析结果:内置Istanbul,测试代码覆盖率,并生成对应的报告

二、断言库

1、判断一个值是否对应相应的结果

2、jestjs.io/docs/en/usi…

3、其他断言库:chai等等

三、使用实例

四、Jest Api

globals API

  • describe(name, fn):描述块,讲一组功能相关的测试用例组合在一起
  • it(name, fn, timeout):别名test,用来放测试用例
  • afterAll(fn, timeout):所有测试用例跑完以后执行的方法
  • beforeAll(fn, timeout):所有测试用例执行之前执行的方法
  • afterEach(fn):在每个测试用例执行完后执行的方法
  • beforeEach(fn):在每个测试用例执行之前需要执行的方法

全局和describe都可以有上面四个周期函数,describe的after函数优先级要高于全局的after函数,describe的before函数优先级要低于全局的before函数

beforeAll(() => {
  console.log('global before all');
});

afterAll(() => {
  console.log('global after all');
});

beforeEach(() =>{
  console.log('global before each');
});

afterEach(() => {
  console.log('global after each');
});

describe('test1', () => {
  beforeAll(() => {
    console.log('test1 before all');
  });
  
  afterAll(() => {
    console.log('test1 after all');
  });
  
  beforeEach(() => {
    console.log('test1 before each');
  });
  
  afterEach(() => {
    console.log('test1 after each');
  });
  
  it('test sum', () => {
    expect(sum(2, 3)).toEqual(5);
  });
  
  it('test mutil', () => {
    expect(sum(2, 3)).toEqual(7);
  });
  
});
复制代码
复制代码

常见断言

  • expect(value):要测试一个值进行断言的时候,要使用expect对值进行包裹

  • toBe(value):使用Object.is来进行比较,如果进行浮点数的比较,要使用toBeCloseTo

  • not:用来取反

  • toEqual(value):用于对象的深比较

  • toMatch(regexpOrString):用来检查字符串是否匹配,可以是正则表达式或者字符串

  • toContain(item):用来判断item是否在一个数组中,也可以用于字符串的判断

  • toBeNull(value):只匹配null

  • toBeUndefined(value):只匹配undefined

  • toBeDefined(value):与toBeUndefined相反

  • toBeTruthy(value):匹配任何使if语句为真的值

  • toBeFalsy(value):匹配任何使if语句为假的值

  • toBeGreaterThan(number): 大于

  • toBeGreaterThanOrEqual(number):大于等于

  • toBeLessThan(number):小于

  • toBeLessThanOrEqual(number):小于等于

  • toBeInstanceOf(class):判断是不是class的实例

  • anything(value):匹配除了null和undefined以外的所有值

  • resolves:用来取出promise为fulfilled时包裹的值,支持链式调用

  • rejects:用来取出promise为rejected时包裹的值,支持链式调用

  • toHaveBeenCalled():用来判断mock function是否被调用过

  • toHaveBeenCalledTimes(number):用来判断mock function被调用的次数

  • assertions(number):验证在一个测试用例中有number个断言被调用

  • extend(matchers):自定义一些断言

技术选型之Enzyme——通用测试框架

React测试工具
1.React官方测试工具——ReactTestUtils
2.Airbnb基于官方的封装——Enzyme

Enzyme是Airbnb开源的React测试工具库库,它功能过对官方的测试工具库ReactTestUtils的二次封装,提供了一套简洁强大的 API,并内置Cheerio,

实现了jQuery风格的方式进行DOM 处理,开发体验十分友好。在开源社区有超高人气,同时也获得了React 官方的推荐。

一、Enzyme优点

1.简单易懂

2.类似Jquery链式写法

二、两种测试方法

1.Shallow Rendering

2.DOM Rendering

三、安装

yarn add enzyme --save-dev

yarn add enzyme-adapter-react-16 --save-dev

四、使用实例

五、Enzyme API

三种渲染方法

  1. shallow:浅渲染,是对官方的Shallow Renderer的封装。将组件渲染成虚拟DOM对象,只会渲染第一层,子组件将不会被渲染出来,使得效率非常高。不需要DOM环境, 并可以使用jQuery的方式访问组件的信息
  2. render:静态渲染,它将React组件渲染成静态的HTML字符串,然后使用Cheerio这个库解析这段字符串,并返回一个Cheerio的实例对象,可以用来分析组件的html结构
  3. mount:完全渲染,它将组件渲染加载成一个真实的DOM节点,用来测试DOM API的交互和组件的生命周期。用到了jsdom来模拟浏览器环境

    三种方法中,shallow和mount因为返回的是DOM对象,可以用simulate进行交互模拟,而render方法不可以。一般shallow方法就可以满足需求,如果需要对子组件进行判断,需要使用render,如果需要测试组件的生命周期,需要使用mount方法。

常用方法

  1. simulate(event, mock):模拟事件,用来触发事件,event为事件名称,mock为一个event object
  2. instance():返回组件的实例
  3. find(selector):根据选择器查找节点,selector可以是CSS中的选择器,或者是组件的构造函数,组件的display name等
  4. at(index):返回一个渲染过的对象
  5. get(index):返回一个react node,要测试它,需要重新渲染
  6. contains(nodeOrNodes):当前对象是否包含参数重点 node,参数类型为react对象或对象数组
  7. text():返回当前组件的文本内容
  8. html(): 返回当前组件的HTML代码形式
  9. props():返回根组件的所有属性
  10. prop(key):返回根组件的指定属性
  11. state():返回根组件的状态
  12. setState(nextState):设置根组件的状态
  13. setProps(nextProps):设置根组件的属性
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享