React Native单元测试--Jest+Enzyme+storybook

React Native的单元测试Jest+Enzyme+storybook

demo

配置

Jest配置

Jest

1. 安装

JestReact Native利用react-native init AwesomeProject创建项目的时候就会默认安装了,这里就不多介绍了。

在你使用 create-react-appreact-native init 创建你的 React 或 React Native 项目时,Jest 都已经被配置好并可以使用了。在 __tests__文件夹下放置你的测试用例,或者使用 .spec.js.test.js 后缀给它们命名。不管你选哪一种方式,Jest 都能找到并且运行它们。

Enzyme配置

Enzyme

1. 安装
yarn add enzyme enzyme-adapter-react-16 --dev

每个适配器可能还有其他的对等体依赖关系,您也需要安装它们。举例来说, enzyme-adapter-react-16对应用同版本的依赖react@16react-dom@16react-test-renderer@16

2. 初始化配置

由于React Native有很多环境依赖性,如果没有主机设备,很难模拟。所以还需要添加react-native-mock,如下

yarn add react-native-mock --dev
3. 初始化配置

做后需要配置enzyme的适配器,一个一般要根据react的版本配置,现在项目中用的是react@16,所以如下配置

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import 'react-native-mock/mock';

Enzyme.configure({ adapter: new Adapter() });

还需要让此配置,在所以test之前执行,进行如下设置

// package.json
// ...
"jest": {
    // ...
    "setupFiles": [
      "<rootDir>/__tests__/Setup"
    ]
  }
// ...

Storybook配置

Storybook

1. 安装

执行下面三条指令就能完成安装

cd my-project-directory
npm i -g @storybook/cli
getstorybook
2. 运行
npm run storybook

运行

Jest 运行

  1. 运行全部测试用例

    npm jest
    
  2. 运行单个测试用例,可以借助webstorm工具,来运行,非常方便

    image

Storybook运行

  1. 在开发组件的时候要把storybook运行起来,并写stories

    npm run storybook
    

用例

Jest 常用api用法实例

中文 英文
匹配器 Matchers
测试异步代码 Asynchronous
模拟器 Mock Functions
全局函数 Global Functions

API集合

全局方法
匹配器

Enzyme 常用api用法实例

enzyme有3种渲染方式:rendermountshallow,先了解下区别。

rendermountshallow的区别

render采用的是第三方库Cheerio的渲染,渲染结果是普通的html结构,对于snapshot使用render比较合适。

shallow和mount对组件的渲染结果不是html的dom树,而是react树,如果你chrome装了react devtool插件,他的渲染结果就是react devtool tab下查看的组件结构,而render函数的结果是element tab下查看的结果。

这些只是渲染结果上的差别,更大的差别是shallow和mount的结果是个被封装的ReactWrapper,可以进行多种操作,譬如find()、parents()、children()等选择器进行元素查找;state()、props()进行数据查找,setState()、setprops()操作数据;simulate()模拟事件触发。

shallow只渲染当前组件,只能能对当前组件做断言;mount会渲染当前组件以及所有子组件,对所有子组件也可以做上述操作。一般交互测试都会关心到子组件,我使用的都是mount。但是mount耗时更长,内存啥的也都占用的更多,如果没必要操作和断言子组件,可以使用shallow。

交互测试

主要利用simulate()接口模拟事件,实际上simulate是通过触发事件绑定函数,来模拟事件的触发。触发事件后,去判断props上特定函数是否被调用,传参是否正确;组件状态是否发生预料之中的修改;某个dom节点是否存在是否符合期望。

官方api

组件测试

  1. 用storybook做组件测试,既可以存储组件快照,也可以快速查看组件样式

    例如:

    // 
    import React from 'react';
    import { storiesOf } from '@storybook/react-native';
    import { action } from '@storybook/addon-actions';
    import { linkTo } from '@storybook/addon-links';
    import * as img from './img';
    
    import ImageButton from './ImageButton';
    
    storiesOf('<ImageButton />', module)
      .add('normal', () =>
        <ImageButton
          title={'确认'}
          imageName={img.ICON_DENE}
          onPress={action('点击')}
        />
      )
      .add('cancel', () =>
        <ImageButton
          title={'取消'}
          imageName={img.ICON_CANCEL}
          onPress={action('点击')}
        />
      )
    ;
    
  2. 效果图如下


    image
    image
    image
    image
  3. 根据组件的需要,进行一些函数的测试,如下

    // imageButton.test.js
    import 'react-native'
    import React from 'react';
    import { mount, shallow } from 'enzyme';
    import ImageButton from '../../src/components/ImageButton';
    
    test('<ImageButton/>', () => {
      let i = 0
      const onPress = () => I++
      const wrapper = shallow(<ImageButton title={'1'} imageName={null} onPress={onPress}/>);
      expect(wrapper.instance().props.title).toBe('1'); // uses the right handler
      expect(wrapper.prop('onPress')).toBe(onPress)
      expect(i).toBe(0);
      wrapper.simulate('press');
      expect(i).toBe(1);
    });
    

API测试

  1. API测试主要进行,返回状态码(200、500、502等)的验证,必要字段的返回,指定参数传入指定数据返回等验证,API测试可以在和后台定义接口的时候就写,等后台接口写好后直接跑一下测试用例就可验证。

    describe('api', () => {
    // ...
      test('/api/config', () => {
        expect.assertions(1); // 异步断言数量
        const param = Object.assign(defaultParam, {});
        const path = '/api/config';
        return api.post(path, param)
          .then(response => response.data)
          .then(response => {
            expect(response.errorCode).toBe(200);
          })
      });
    // ....
    
    });
    

参考文档

Engine单元测试调研文档

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,924评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,902评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,716评论 0 239
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,783评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,166评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,510评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,784评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,476评论 0 196
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,196评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,459评论 2 243
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,978评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,321评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,964评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,046评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,803评论 0 193
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,530评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,420评论 2 265

推荐阅读更多精彩内容