React测试的那些事(一) 介绍&对比基本方法

153 阅读3分钟

🕐首先了解一下“测试”的过程

                        Arrange   --->   Act  --->  Assert

~Arrange~ 您的APP处于某种原始state

~Act~ 发生了一些事情(比如点击、输入...)

~Assert~ 做出断言,假设state的变化情况,如果符合预期,test通过✅,否则test失败。


🕑测试环境 —— “Jest”

React组件的运行环境是浏览器,而测试的运行环境是Jest

Jest是基于React的测试框架,所以 *.test.js 无需引入 expect describe ,因为已经集成在Jest的全局环境中了。


🕒Jest的简单示例

describe('Testing sum', () => {
    function sum(a, b) {
       return a + b;
    }

    it('should equal 4',()=>{
       expect(sum(2,2)).toBe(4);
      })

    test('also should equal 4', () => {
        expect(sum(2,2)).toBe(4);
      }) 
});

describe 它作为测试中一个分组的概念,里面可以放入 ittest的测试块。

ittest是可以互相替换的,里面的输出能够打印到console中。

toBe() 有匹配功能,用它进行 断言

JEST API


🕓Why test, What to test & What not to test

~Why~

为何写测试呢?经过验证是否结果符合预期的代码更健壮。

写测试也有潜在的缺点:eg: 费事,难写。测试写错了会带来麻烦。

~What~

测试怎么写呢?就模仿实际的用户操作来写。当发布时,你对经过测试的代码更有自信。

~What not~

什么无需写测试呢?eg: 函数名、变量名和第三方库等。这些实现细节,我们不需要测试用户接触不到的逻辑。

如何避免一直更新/修改你的测试呢,后面的文章会介绍更好的方法。


🕔测试哲学的个家之见

~测试方式推荐的占比~

Integration Test >  Unit Test  >   E 2 E Test  >  Snapshot Test

集成测试多一点,单元测试 和 E2E测试来一点,不写快照测试   

Integration Test建议多写一些。尽管它很少使用mock数据。

Unit TestSnapshot Test更容易理解、健壮,但它并不像用户操作APP那样进行测试。可用 shallow render 实现测试的细节。

🕕Shallow VS Mount

~Shallow~

shallow 只会渲染我们执行单测的组件,不会渲染子组件。

~Mount~

Mount 模拟浏览器执行了HTML、 CSS、 JS。它用的headless方式就是不会渲染到UI中而是在后台模拟浏览器的环境执行代码。

一来,test执行的速度快,因为没有实际渲染在UI上。即使如此,mount tests 还是比shallow test 慢一些。

二来,每个mount test结束前我们需要unmount / cleanup 组件,因为mount的过程已经接近于一个运行的app了,test之间可能会相互影响。

~Mount/render & Shallow~

Mount/render 一般用于集成测试,Shallow用于单元测试。


🕖👇父子组件,Shallow vs Mount 测试时渲染对比

import React from 'react';

const App = () => {
  return (
    <div> 
      <ChildComponent /> 
    </div> 
  )
}

const ChildComponent = () => {
  return (
    <div>
     <p> Child components</p>
    </div>
  )
}

shallow 结果:

<App>
  <div> 
    <ChildComponent /> 
  </div>
</App>

mount / render 结果:

<App>
  <div> 
    <ChildComponent> 
      <div>
       <p> Child components</p>
      </div>
    </ChildComponent>
   </div>
</App> 

由上可知,mount/render 更接近于浏览器中的样子。


🕗unit VS integration VS end to end

~unit testing~

对一个独立的组件进行测试,经常搭配shallow rendering,比如:用默认props渲染组件。

~integration testing~

用于几种组件相关的集成测试。经常使用Mount/render,比如:测试父子组件的状态更新。

~end to end testing~

通常是将多个单元和集成测试组合成一个大测试的多步测试。测试在模拟浏览器中完成,测试运行时可能有也可能没有UI。示例:测试整个身份验证流程。



在下一篇文章中写测试的几种方法和例子,未完待续。谢谢