Como faço para escrever testes de unidade em um projeto TypeScript? Neste artigo, tentarei responder a essa pergunta e também mostrarei como criar um ambiente de teste de unidade para projetos usando TypeScript.
O que são testes de unidade?
Testes de unidade - testes aplicados em diferentes camadas de um aplicativo que testam a menor lógica divisível em um aplicativo: por exemplo, um módulo, classe ou método.
, , , () .
. , . . , , . .
. :
project
| node_modules
| src
| package.json
| tsconfig.json
./src
cat.module.ts
Cat.
export class Cat {
public name: string;
public color: string;
constructor(name: string, color: string) {
this.name = name;
this.color = color;
}
public move(distanceMeter: number) : string {
return `${this.name} moved ${distanceMeter}m.`;
}
public say() : string {
return `Cat ${this.name} says meow`;
}
}
, . (SUT - system under test).
, test, .
npm :
npm install --save-dev ts-node mocha @testdeck/mocha nyc chai @types/chai
:
ts-node
- TypeScript REPL node.js.
mocha
- , , . . @testdeck/mocha
- testdeck , .
nyc
- CLI Istanbul, .
chai
- (assertions), . . @types/chai
typescript'
, test
, tsconfig.json
, TS .
{
"extends": "../tsconfig.json",
"compilerOptions": {
"baseUrl": "./",
"module": "commonjs",
"experimentalDecorators": true,
"strictPropertyInitialization": false,
"isolatedModules": false,
"strict": false,
"noImplicitAny": false,
"typeRoots" : [
"../node_modules/@types"
]
},
"exclude": [
"../node_modules"
],
"include": [
"./**/*.ts"
]
}
include test .ts
, register.js
ts-node, .
const tsNode = require('ts-node');
const testTSConfig = require('./test/tsconfig.json');
tsNode.register({
files: true,
transpileOnly: true,
project: './test/tsconfig.json'
});
, .mocharc.json
, :
{
"require": "./register.js",
"reporter": "list"
}
.nyrc.json
.
{
"extends": "@istanbuljs/nyc-config-typescript",
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules/"
],
"extension": [
".ts"
],
"reporter": [
"text-summary",
"html"
],
"report-dir": "./coverage"
}
, :
project
| node_modules
| src
| test
| --- tsconfig.json
| .mocharc.json
| .nyrc.json
| package.json
| register.js
| tsconfig.json
package.json
"test": "nyc ./node_modules/.bin/_mocha 'test/**/*.test.ts'"
,
./test
cat.unit.test.ts
:
import { Cat } from '../src/cat.module';
import { suite, test } from '@testdeck/mocha';
import * as _chai from 'chai';
import { expect } from 'chai';
_chai.should();
_chai.expect;
@suite class CatModuleTest {
private SUT: Cat;
private name: string;
private color: string;
before() {
this.name = 'Tom';
this.color = 'black';
this.SUT = new Cat(this.name, this.color);
}
}
Cat cat.module.ts
, , .
before Cat, .
, .
import { Cat } from '../src/cat.module';
import { suite, test } from '@testdeck/mocha';
import * as _chai from 'chai';
import { expect } from 'chai';
_chai.should();
_chai.expect;
@suite class CatModuleTest {
private SUT: Cat;
private name: string;
private color: string;
before() {
this.name = 'Tom';
this.color = 'black';
this.SUT = new Cat(this.name, this.color);
}
@test 'Cat is created' () {
this.SUT.name.should.to.not.be.undefined.and.have.property('name').equal('Tom');
}
}
npm test :
Como você pode ver, nossa cobertura não está completa, as linhas 11-15 permaneceram sem teste. Esses são apenas os métodos da classe Cat move
esay.
Adicionamos mais dois testes para esses métodos e terminamos com um arquivo com testes:
import { Cat } from '../src/cat.module';
import { suite, test } from '@testdeck/mocha';
import * as _chai from 'chai';
import { expect } from 'chai';
_chai.should();
_chai.expect;
@suite class CatModuleTest {
private SUT: Cat;
private name: string;
private color: string;
before() {
this.name = 'Tom';
this.color = 'black';
this.SUT = new Cat(this.name, this.color);
}
@test 'Cat is created' () {
this.SUT.name.should.to.not.be.undefined.and.have.property('name').equal('Tom');
}
@test 'Cat move 10m' () {
let catMove = this.SUT.move(10);
expect(catMove).to.be.equal('Tom moved 10m.');
}
@test 'Cat say meow' () {
expect(this.SUT.say()).to.be.equal('Cat Tom says meow');
}
}
Execute nossos testes novamente e veja se a classe Cat agora tem cobertura total de teste.
Resultado
Como resultado, criamos uma infraestrutura de teste para nosso aplicativo e agora podemos cobrir qualquer novo módulo ou classe com testes, verificando se o código existente não foi quebrado.
PS: Baseado no artigo Como configurar o teste de unidade com TypeScript .