CLOVER🍀

That was when it all began.

JestでTypeScriptのテストを書く

これは、なにをしたくて書いたもの?

TypeScriptを使ったテストコードを書こうと思って、ふと手が止まり。

TypeScriptのテストコードを書く時にも、Jestを使うのかなと。

というわけで、TypeScriptでのJestの使い方について調べてみました。

Jest with TypeScript

Jest自体は、JavaScriptのテスティングフレームワークです。

Jest · 🃏 Delightful JavaScript Testing

Getting Startedのページを見ると、TypeScriptを使う場合の記述があります。

Getting Started / Using TypeScript

方法は以下の3つがあるようです

  • @babel/preset-typescriptを使ってBabel経由で使う
  • ts-jestを使う
  • TypeScriptのコンパイラを直接使って自分で頑張る

ドキュメントを見るとBabel+TypeScriptの場合、テストコード実行時に型チェックを行わないようです。
型チェックを行いたい場合はts-jestを使うようにと書かれていたので、今回はts-jestを使うことにします。

ts-jestとは、TypeScriptでテストコードを書くプロジェクト向けに、JestのSource MapをサポートするJestの
Transformerです。

GitHub - kulshekhar/ts-jest: A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript.

Transformerというのは、Jestのコード変換の仕組みのようです。

Code Transformation · Jest

Code Transformation / Writing custom transformers

ts-jestのWebサイトおよび、ドキュメントはこちら。

A Jest transformer with source map support that lets you use Jest to test projects written in TypeScript. | ts-jest

Introduction | ts-jest

ちなみに、ts-jestとBabel+TypeScriptの違いはこちらにも書かれています。

Babel7 or TypeScript | ts-jest

では、先に進めていきます。

環境

今回の環境はこちら。

$ node --version
v16.13.0


$ npm --version
8.1.0

TypeScriptプロジェクトを作成する

TypeScriptプロジェクトを作成していきます。

ディレクトリの作成。

$ mkdir jest-getting-started
$ cd jest-getting-started

npmプロジェクトとして初期化。

$ npm init -y

TypeScriptとPrettierのインストール。

$ npm i -D typescript
$ npm i -D -E prettier

バージョン。

$ npx tsc --version
Version 4.4.4


$ npx prettier --version
2.4.1

tsconfig.jsonは、こんな感じにしました。

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "commonjs",
    "baseUrl": "./src",
    "outDir": "dist",
    "strict": true,
    "noImplicitAny": true,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,      
    "sourceMap": true,
    "skipLibCheck": true
  },
  "include": [
    "src"
  ]
}

.prettierrc.jsonは、設定なしで。

$ echo {} > .prettierrc.json

あとはソースコード用のディレクトリ(srctestの2つ)を作成。

$ mkdir src test

Jest+ts-jestを導入する

では、プロジェクトにJestとts-jestを導入していきます。

以下のドキュメントに従っていきましょう。

Installation | ts-jest

まずはJest、Jestの型宣言、ts-jestをインストール。

$ npm i -D jest @types/jest ts-jest

package.jsondevDependenciesは、このようになりました。

  "devDependencies": {
    "@types/jest": "^27.0.2",
    "jest": "^27.3.1",
    "prettier": "2.4.1",
    "ts-jest": "^27.0.7",
    "typescript": "^4.4.4"
  }

ts-jest config:initで、Jestの設定ファイルを生成します。

$ npx ts-jest config:init

できあがったjest.config.js

jest.config.js

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

ts-jestというプリセットが入っています。これは、TypeScriptファイル(.ts.tsx)はJavaScriptに変換し、
JavaScriptファイルはそのままにしてCommonJS構文に変換するものです。

TypeScript files (.ts, .tsx) will be transformed by ts-jest to CommonJS syntax, leaving JavaScript files (.js, jsx) as-is.

ts-jest/presets/defaultの省略形みたいです。

その他のプリセットは、こちらを参照。

Presets | ts-jest

jest.config.jsというファイル自体はJestの設定なので、以下の2つを除いた設定については

Jestのドキュメントを参照しましょう。

Configuring Jest · Jest

ソースコードを書く

それでは、ソースコードを書いていきます。
こちらを参考に、srctestディレクトリに作成していきましょう。

Getting Started · Jest

最初はテスト対象のソースコードから。

src/calc.ts

export function plus(a: number, b: number): number {
  return a + b;
}

export function minus(a: number, b: number): number {
  return a - b;
}

続いて、テストコード。

test/calc.test.ts

import { plus, minus } from "../src/calc";

test("plus", () => {
  expect(plus(1, 2)).toBe(3);
});

test("minus", () => {
  expect(minus(5, 1)).toBe(4);
});

テストコードの命名規則は、こちらに従っています。

Configuring Jest / testMatch [array]

では、テストを実行。

$ npx jest
 PASS  test/calc.test.ts
  ✓ plus (2 ms)
  ✓ minus

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.888 s
Ran all test suites.

package.jsontestjestと書いておけば

  "scripts": {
    "build": "tsc",
    "test": "jest",
    "format": "prettier --write src test"
  },

npm tnpm testでもOKです。

$ npm t

> jest-getting-started@1.0.0 test
> jest

 PASS  test/calc.test.ts
  ✓ plus (4 ms)
  ✓ minus

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.751 s, estimated 2 s
Ran all test suites.


$ npm test

> jest-getting-started@1.0.0 test
> jest

 PASS  test/calc.test.ts
  ✓ plus (2 ms)
  ✓ minus

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.789 s, estimated 2 s
Ran all test suites.


$ npm run test

> jest-getting-started@1.0.0 test
> jest

 PASS  test/calc.test.ts
  ✓ plus (2 ms)
  ✓ minus

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.744 s, estimated 2 s
Ran all test suites.

こんなところでしょうか。

ビルドやコードフォーマットも付けていますが、このあたりはお好みで。

$ npx tsc


$ npm run build

> jest-getting-started@1.0.0 build
> tsc


$ npx prettier --write src test
src/calc.ts 30ms
test/calc.test.ts 13ms


$ npm run format

> jest-getting-started@1.0.0 format
> prettier --write src test

src/calc.ts 30ms
test/calc.test.ts 14ms