快捷搜索:
来自 新京葡娱乐场网址 2019-12-13 21:15 的文章
当前位置: 67677新澳门手机版 > 新京葡娱乐场网址 > 正文

新京葡娱乐场网址的生机勃勃部分建议,组件进

在 2017 年学习 React Redux 的一些建议(下篇)

2017/09/11 · JavaScript · React, Redux

原文出处: 郭永峰   

在这里说一下前端开发的一个特点是更多的会涉及用户界面,当开发规模达到一定程度时,几乎注定了其复杂度会成倍的增长。

新京葡娱乐场网址 1关于测试的一些学习建议

我们可以组合使用一些测试工具来帮助测试 JS 代码,一般使用 Mocha/Chai 或是 Karma/Jasmine 。而如果当你想测试 angular 的代码时,你会发现还有更多的测试工具。不过对于 React 应用的测试,比较推荐使用 Airbnb 团队出品的 anzyme 来进行组件的测试,以保住组件的稳定可靠,目前使用非常广泛;而另一种方式是使用 Facebook 的 jest 来进行测试。

可能很多同学都觉得应该选择以上的某一个测试库来进行测试工作,不过,你也可以将 anzymejest 结合起来一起使用。特别是在进行一些 snapshot 快照测试的时候,两种都是互补的,它们已经是 React 应用测试中大家公认的标准库了。

sinon 也是个非常优秀的测试辅助工具,可以帮助我们在 spy、stub、mock 等测试阶段提供相应的工具辅助测试。如果对这几个概念不太清晰,可以看看这里。

另外,在这里给你隆重的给你推荐一篇 A. Sharif 写的 Some Thoughts On Testing React/Redux Applications,满满的干货分享哦。

无论是在代码的初始搭建过程中,还是之后难以避免的重构和修正bug过程中,常常会陷入逻辑难以梳理、无法掌握全局关联的境地。

多一些组件的单元测试,少一些集成测试

Enzyme 可以帮助我们实现组件的单元测试和集成测试。这里我们可以通过三种方式来渲染组件:

  • shallow()
  • mount()
  • render()

shallow() 只能用来渲染不包含 children 的组件,mount() 则能够渲染所有的子组件。所以单元测试的时候可以使用 shallow()mount() 则一般用于集成测试。集成测试往往是很容易被割裂的,因为他需要测试由一组或是多个组件树组合的场景,所以集成测试一般维护成本是比较高的。所以我们可以多做一些小巧的单元测试,少做一些重要的集成测试。

第三种测试的方式是使用 render() 方法,具有类似 mount()方法的功能,不过 mount() 能够访问到组件的生命周期方法,比如 componentDidUpdate等。

正如这个 issue 中提出的 API differences between render and mount/shallow,可以总结出:

  • 使用 shallow 开始测试用例
  • 如果 componentDidMount or componentDidUpdate 等方法也需要测试,那么使用 mount 方法吧
  • 如果要测试组件生命周期方法、子组件的行为等,使用 mount 方法吧
  • 如果想更高性能的测试子组件,并且对组件的生命周期等方法不怎么关注,那么使用 render 方法吧

新京葡娱乐场网址 2

保证测试用例简单、最小颗粒度

否则的话你需要为此付出很高的维护成本。

确认每个组件是否都有执行过单元测试,确认每个 props 和 callbacks 都在集成测试的时候传递给了对应的子组件。

为了保证组件测试用例的小颗粒度和简单化,你需要熟悉一下 selectorsEnzyme 提供了丰富的 selector 去深入组件树。

另外,建议使用 sinon 来测试 callbacks 回调函数,不要在组件中测试业务逻辑,这真不是个好注意。而是应该将业务逻辑从组件中解耦并对其进行测试。

最后,Facebook 出品的 Jest 也能在初期帮助我们更加轻量的执行测试,你可以非常简单就设置好 snapshot test,这样当组件的输出改变的话测试用例会自动的报出失败的结果,并且能够获取到错误信息。

而单元测试作为一种“提纲挈领、保驾护航”的基础手段,为开发提供了“围墙和脚手架”,可以有效的改善这些问题。

拥抱 TDD(测试驱动开发)

所有的人都可能会对你说:你应该按测试驱动的模式来进行开发。但是,几乎没几个人会这么,项目需求如山的积压,上线的脚本火急火燎,测试驱动?玩呢?!可能大部分小伙伴都是这样的心声。

不过,如果你能够清晰的在 React Redux 的应用中使用对应的测试方案对每个部分都进行测试,你就能够非常轻松的实现 TDD。尽管你会发现 reducer 的测试和组件的测试是很不一样的,但其实每种类型(reducer、component、…. )的测试模式其实都是一样的。

就拿 reducer 的测试为例吧,一般是期望 reducer(state, action) === newState,其实这种方式和 (input) => output 的模式是一样的。如果你要测试 state 的不可变性的话,建议你可以使用 deep-freeze,可以看下以下示例代码:

JavaScript

import deepFreeze from 'deep-freeze' const initialState = { ... }; const action = { type: ..., payload: ... }; const expectedState = { ... }; deepFreeze(initialState); expect(reducer(initialState, action)).to.equal(expectedState);

1
2
3
4
5
6
7
8
9
import deepFreeze from 'deep-freeze'
 
const initialState = { ... };
const action = { type: ..., payload: ... };
const expectedState = { ... };
 
deepFreeze(initialState);
 
expect(reducer(initialState, action)).to.equal(expectedState);

如果你能够很清晰的知道如何测试应用中的每一个部分,那就最好采用 TDD。

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

多组件测试

新京葡娱乐场网址 3

关于资源加载的选择

React 虽然是个 library,但是它的生态圈非常的丰富,会有非常多的可扩展框架或类库可以加入使用,但是千万别太快的加入这些扩展方案。并且每次新加入一个模块的时候,要在团队里面确认每个人都是清楚了解的。特别是对于 Redux 本身的一些生态扩展,会有非常多的一些小模块,比如下面这些:

  • 在大家还没开始写 action creatorsreducers 之前,就不要添加 redux-actions
  • 在大家还没写出第一个自己的 form 表单和表单验证的时候,就不要加入 redux-form
  • 在大家还没开始写自己的 selectors 之前,就不要加入 reselect
  • 在大家还么开始写第一个高阶组件 HOC 之前,就不要加入 recompose
  • …..

同时,关注一些大牛的最佳实践,并且建立你自己的最佳实践。不过得确保团队中其他小伙伴也能理解。定义清晰的命名规则和目录结构,并且在项目做一些升级的时候得把这些约定提前讨论清楚。

本文将按如下顺序进行说明:

保持持续的技术学习热情

  • 关注技术社区的新动向,比如在应用中使用 ramda.js.,看看如何在React中优雅的写代码
  • 学习如何使用 React Native 构建你的移动应用
  • 学习使用 Electron 构建你的桌面应用
  • 也许你可以关注如何使用 Mobx 来进行应用状态管理
  • React 仅仅只是 UI 层的一个 library ,你可以使用PREACT 和 inferno 等类似 React 的库来替代,他们的体积能加轻量,渲染更加高效,也许是个不错的选择。
  • Airbnb 的 React/JSX 规范 我也建议你抽时间看看,对于团队一致化开发非常有帮助。同时,也可以使用 ESLint 来进行代码规则检查。
  • I. 单元测试简介
  • II. React 单元测试中用到的工具
  • III. 用测试驱动 React 组件重构
  • IV. React 单元测试常见案例

结束语

全文完结,感谢你的阅读,希望整个系列的文章对你今后的学习有所帮助。

如果你想系统学习 React Redux 技术栈的所有内容,请点我前往

2 赞 1 收藏 评论

新京葡娱乐场网址 4

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

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

测试框架

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

断言(assertions)

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

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

  • 同等性断言 Equality Asserts

    • expect.toEqual
    • expect.not.toEqual
  • 比较性断言 Comparison Asserts

    • expect.toBeGreaterThan
    • expect.toBeLessThanOrEqual
  • 类型性断言 Type Asserts

    • expect.toBeInstanceOf
  • 条件性测试 Condition Test

    • expect.toBeTruthy()
    • expect.toBeFalsy()
    • expect.toBeDefined()

断言库

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

测试用例 test case

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

一般的形式为:

it('should ...', function() { ... expect.toEqual;

测试套件 test suite

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

一般的形式为:

describe('test ...', function() { it('should ...', function() { ... }); it('should ...', function() { ... }); ...});

spy

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

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

var spy = sinon.spy(MyComp.prototype, 'componentDidMount');...expect(spy.callCount).toEqual;

stub

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

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

var myObj = { prop: function() { return 'foo'; }};sinon.stub(myObj, 'prop').callsFake(function() { return 'bar';});myObj.prop(); // 'bar'

本文由67677新澳门手机版发布于新京葡娱乐场网址,转载请注明出处:新京葡娱乐场网址的生机勃勃部分建议,组件进

关键词: