Русский
Русский
English
Статистика
Реклама

Пишем юнит тесты на TypeScriptе (на примере котиков)

Как писать модульные тесты в проекте с TypeScript'ом? В этой статье я постараюсь ответить на этот вопрос а также покажу как создать среду модульного тестирования под проекты использующие TypeScript.

Юнит тесты, что это?

Unit tests ( модульные тесты) - тесты применяемые в различных слоях приложения, тестирующие наименьшую делимую логику приложения: например модуль, класс или метод.

Суть юнит тестов, в том чтобы писать их к каждому новому классу или методу, проверяя, не привело ли очередное изменение кода к появлению ошибок (багов) в уже протестированных местах программы.

Отсюда следует что юнит тесты должны быть быстрыми. Такие тесты могут выполнятся часто, во время программирования. Т.е разработчик после написания нового класса или метода, пишет пакет тестов к ним, затем запускает их вместе с уже имеющимся тестам остальных частей программы. На выходе получаем код покрытый тестами что позволяет избегать багов уже на старте разработки.

Настройка окружения

Итак теперь ближе к делу. Предположим у нас есть некий проект со следующей структурой:

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 'tests/**/*.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 и получаем примерно такой результат в консоле:

Как видим покрытие у нас не полное, остались не протестированными строчки 11-15. Это как раз методы класса Cat move и say.

Дописываем еще два теста для этих методов и получаем в итоге такой файл с тестами:

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');  }}

Снова запускаем наши тесты и видим что теперь класс Cat имеет полное тестовое покрытие.

Итог

По итогу мы создали тестовую инфраструктуру для нашего приложения и теперь можем покрывать тестами любой новый модуль или класс, проверяя что существующий код не сломался.

PS: Написано по мотивам статьи How setting up unit test with TypeScript.

Источник: habr.com
К списку статей
Опубликовано: 19.04.2021 18:14:05
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Javascript

Typescript

Unit test

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru