这个博客的粉丝不需要深信良好维护的测试套件(针对karma+jasmine?)的价值。幸运的是Jest使得测试React应用变得非常轻松,即使使用了Typescript,也是如此。让我们深入研究开发纯净的、测试安全的代码所涉及的各个层面。
Linting
在vanilla Javascript中,linters是按一种风格来验证语法,这也是防止运行时错误的第一道防线。在Typescript中,静态类型检查具有类似的用途,但对原始语法的上下文有更复杂的理解。但是,linters仍然为维护者增加了价值:即使使用类型系统处理繁重的静态分析,我们仍然可以从清晰,一致的风格中受益。
tslint是非常好的 Typescript linter,与Javascript工具jshint/eslint提供相同的功能。
npm i -g tslint
tslint --init
安装tslint并初始化默认配置,我们就可以对新项目或现有项目进行lint:
rslint -c tslint.json '/src/**/*.{ts,tsx}'
// tslint.json 我进行了扩展
{
"defaultSeverity": "error",
"extends": [
"tslint:recommended"
],
"jsRules": {
"max-line-length": {
"options": [120]
}
},
"rules": {
"max-line-length": {
"options": [120]
},
"new-parens": true,
"no-arg": true,
"no-bitwise": true,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": false,
"no-console": {
"severity": "warning",
"options": ["debug", "info", "log", "time", "timeEnd", "trace"]
},
"quotemark": [true, "single", "avoid-escape", "avoid-template"],
"member-access": false,
"interface-name": false
},
"rulesDirectory": []
}
使用Jest进行单元测试
Jest是一种在React应用程序中很流程的测试工具,可以进行简单的配置,就可以工作–低配置化工具。 【and for good reason: in vanilla JavaScript, it mostly Just Works™.】
将Jest与Typescript一起使用需要更多的工作。Facebook的Jest/TypeScript示例概述了该策略:设置一个预处理器,如ts-jest处理编译和源映射,然后将处理过的文件提供给Jest。
npm i --save-dev ts-jest
要配置Jest,让我们”jest”在项目中添加一个新配置,package.json并使用它来预处理源文件。
{
"...": "...",
"jest": {
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "/__tests__/.*\\.(ts|tsx|js)$"
}
}
package.json是开放的,我们可以添加lint和test脚本.
{
"...": "...",
"scripts": {
"lint": "tslint -c tslint.json 'src/**/*.{ts,tsx}'",
"pretest": "npm run lint",
"test": "jest"
}
}
添加一些测试
此时,我们可以编写一个简短的示范来获取<Counter />组件的显示结果,和Jest快照
// src/components/__tests__/counter_spec.tsx
import * as React from 'react'
import * as TestUtils from 'react-dom/test-utils'
import * as ReactShallowRenderer from 'react-test-renderer/shallow'
import { createStore } from 'redux'
import { Counter } from '../counter'
import { reducers } from '../../reducers'
describe('<Counter />', () => {
it('renders', () => {
const store = createStore(reducers)
const renderer = new ReactShallowRenderer()
expect(renderer.render(
<Counter label='a counter!' store={store} />
)).toMatchSnapshot()
})
});
虽然我们将ReactShallowRenderer开始使用,但可以使用相同的设置来使用Enzyme测试组件。无论我们使用哪种渲染器,我们都可以像在Javascript中一样比较快照。
剩下就是看测试变成绿色。
npm test
测试 reducers
Redux reducers 应该易于测试。使用与组件相同的工具,我们可以通过重放一系列操作并比较结果状态来验证reducer行为:
// src/reducers/__tests__/index_spec.tsx
import reducers, {
initialState,
} from '../index'
import {
incrementCounter
} from '../../actions'
const resultOf = actions =>
actions.reduce(reducers, initialState)
describe('reducers/counter', () => {
it('starts at 0', () =>
expect(resultOf([])).toMatchSnapshot())
it('increments to 6', () =>
expect(resultOf([
incrementCounter(1),
incrementCounter(2),
incrementCounter(3),
])).toMatchSnapshot())
})
结论
你有它:基本的工具,配置和脚本,使测试成为TypeScript应用程序的核心部分。我们不必在这里停下来!虽然这是另一天的练习,但我们用于验证代码和编写单元测试的相同技术也可以轻松应用于端到端测试。
完成的计数器项目可供github,测试和所有参考。有评论,建议或改进吗?问题队列是开放的业务。我期待着您在twitter上的建议,经验和反馈。
和以往一样,快乐的测试!