ウェブエンジニア珍道中

日々の技術的に関する経験を書いていきます。脱線もしますが助けになれば幸いです。

typescriptでテストを書く環境を作ってみた(mocha, chai)

f:id:te-nu:20180421194833p:plain

typescriptでテストコードを書くための環境作りをしたので、ご紹介兼備忘録です。

使うライブラリ

mocha

Mocha - the fun, simple, flexible JavaScript test framework

Javascriptのテストフレームワークです。上記HP曰く「シンプルで柔軟で楽しい」らしいです。

jsのテストについて検索したら大体一番目にこいつが出てきます。シンプルでよく使われていそうなのでこれにしました。ブラウザでも動くらしいですが、今回はCLI上で動かします。

アサーション(後述)やモック・スタブの機能は持っていないため、別途入れてあげる必要があります。

chai

アサーションライブラリです。これもシンプルでよく使われていそうなので選択しました。

アサーションとは?

「表明」という意味で、「ここはこう動きます、もし動かなかったらバグです」ということを示す行為のようなものです。

プログラム内でアサーション(表明)を行い、もしその通りに動かなかった場合は例外を吐くことでテストを行います。

「値のチェックして違ったらエラーを吐く機能」くらいでOKです、chaiは「チェックしてエラーを吐く人」ですね(適当)

ts-node

typescriptを内部的にjavascriptに変換して実行してくれるライブラリです。mochaは本来javascriptで動作するのですが、これを組み込むことでトランスパイルを内部でさせることができます。

詳しくはこちら(自分の別記事です)

www.te-nu.com

環境構築

必要なライブラリをインストールします。

npm install mocha chai typescript ts-node

型定義もインストールします。

npm install @types/mocha @types/chai

これで動作環境は整いました。

テスト対象のファイルを作る

テスト用の簡単なファイルを作ります。

hoge.ts

export const getName = () => {
  return "taro"
}

taroと返すだけの関数です。

こいつが本当にtaroと返すのかをテストします。

テストを行うファイルを作る

実際にテストをする処理を作成します。

test/test.ts

import { describe, it } from "mocha";
import { getName } from '../hoge';
import { assert } from "chai"

describe('getName関数を見るよ', () => {
    it('本当にtaroって返す?', () => {
        assert.equal(getName(), "taro");
    });
})

describe内で何について見るかを明記し、itでは何をチェックしているかを示します。

it内ではchaiによるアサーションを行いテストを行います。

今回はassert.equal(getName(), "taro");の箇所でgetName()taroと返しているかどうかを見ています。

ディレクトリ構造はこんな感じです。

.
├── hoge.ts
├── node_modules
├── package.json
├── test
│   └── test.ts
└── yarn.lock

実行

実際にテストを動かしてみます

$ TS_NODE_COMPILER_OPTIONS='{"module":"commonjs"}' ./node_modules/.bin/mocha -r ts-node/register "test/**/*.ts"

TS_NODE_COMPILER_OPTIONS='{"module":"commonjs"}'としているのは、moduleを指定しないとimport周りで動かなかったためです。

-r ts-node/registerでts-nodeを読み込んで内部的にトランスパイルするようにしています。

test/**/*.ts"はtestディレクトリ以下を片っ端から読み込むようにしています。ファイルを増やしても大丈夫です。

実行結果

$ TS_NODE_COMPILER_OPTIONS='{"module":"commonjs"}' ./node_modules/.bin/mocha -r ts-node/register "test/**/*.ts"


  getName関数を見るよ
    ✓ 本当にtaroって返すかどうか


  1 passing (10ms)

このように動きます。

コマンド化しておく

package.jsonに入れておきます。

  "scripts": {
    "test": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' mocha -r ts-node/register test/**/*.ts"
  }
yarn run test # これで動くようになる

これで必要最低限のテスト環境が整いました。

開発を進める上ではモック・スタブなど更に必要なものが出て来ると思いますが、ベースはこれで良いかなーと思います。 フロントエンドのテストコードは非同期処理とかもあるのでサーバサイドとはまた違った難しさがありそうですね。では今回はこのへんで。