[Node.js][Jest] Jestでテストを行う

# 環境
MacBook Pro (2.3 GHz 8コアIntel Core i9)
macOS 14.0（23A344）
Homebrew 4.3.8
gh 2.52.0

# 目次
- [プロジェクトを作成する](#プロジェクトを作成する)
- [TypeScriptのインストール](#typeScriptのインストール)
- [パッケージ（Jest関連）のインストール](#パッケージ（jest関連）のインストール)
- [Jestの設定ファイルを作成する](#jestの設定ファイルを作成する)
- [Jestが動くかを確認する](#jestが動くかを確認する)
- [テストを実施する](#テストを実施する)
- [ディレクトリ構成](#ディレクトリ構成)

# プロジェクトを作成する
1. プロジェクト（ディレクトリ）を作成する
    ~~~sh
    mkdir jest-tutorial
    ~~~
1. ディレクトリに移動する
    ~~~sh
    cd jest-tutorial
    ~~~
1. [プロジェクトルート※1](※1)にpackage.jsonを作成する
    ~~~sh
    touch package.json
    ~~~
1. package.jsonに下記を記載する
    ~~~json:package.json
    {
      "name": "jest-tutorial",
      "license": "UNLICENSED"
    }
    ~~~
1. package.jsonに下記を記載する
    ~~~json:package.json
    "scripts": {
      "test": "jest"
    }
    ~~~

##### ※1
プロジェクトルートは、すべてのプロジェクトソースの親であるフォルダーです。

# TypeScriptのインストール
1. TypeScriptコンパイラをインストールする[※2](※2)
    ~~~sh
    npm install typescript
    ~~~
    ~~~sh:※2
    npm install -g typescript
    ~~~
    ##### ※2
    `-g`オプションを付けると、グローバルでインストールされる。各PJでバージョンを分けたい場合は`-g`オプションを付けずにインストールを行う


1. `tsc`コマンドが実行できるか確認する[※3](※3)
    ~~~sh
    npx tsc -v
    //出力結果
    Version 5.5.4
    ~~~
    ~~~sh:※3
    tsc -v
    //出力結果
    Version 5.5.4
    ~~~
    ##### ※3
    グローバルでインストールしてる場合は、`npx`コマンドを最初につける必要ながない

# パッケージ（Jest関連）のインストール
1. Jest本体をインストールする。
    ~~~sh
    npm install -D jest
    ~~~      
    **jestはJest本体**：JavaScriptだけのプロジェクトであれば、このパッケージを入れるだけでテストが始められます。
1. 必要なパッケージをインストールする。[※4]()
    ~~~sh
    npm install -D ts-jest
    npm install -D @types/jest
    ~~~
    **ts-jestはJestをTypeScriptに対応させるためのパッケージ**：ts-jestを入れると、TypeScriptで書いたテストコードを、コンパイルの手間なしにそのまま実行できるようになります。
    **@types/jestはJestのAPIの型定義ファイル**：TypeScriptの型情報を付与されるので、テストコードの型チェックが行えるようになります。

##### ※4
下記のように非推奨の`inflight` `glob`パッケージがインストールされている警告が出るが、無視できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/9c881e9c-2c15-6b30-5ba3-83620484dd2e.png)

必要であれば、下記でパッケージの依存関係を調べることができる。
~~~sh
npm ls inflight
~~~


# Jestの設定ファイルを作成する
1. Jestの設定ファイル（jest.config.js）を作成する
    ~~~sh
    npx ts-jest config:init
    ~~~
1. Jestの設定ファイル（jest.config.js）に下記を記載する
    ~~~js:jest.config.js
    module.exports = {
      preset: 'ts-jest',
      testEnviroment: 'node'
    }
    ~~~

# Jestが動くかを確認する
1. 動作確認用テストファイル（check.test.ts）を作成する
    ~~~sh
    touch check.test.ts
    ~~~
1. 動作確認用テストファイル（check.test.ts）に下記を記載する
    ~~~js:check.test.ts
    test("check", () => {
      console.log("OK");
    });
    ~~~
1. package.jsonに下記を記載する（すでに上で記載済みの場合は不要）
    ~~~json:package.json
    "scripts": {
      "test": "jest"
    }
    ~~~
1. `jest`コマンドでテスト実行する
    ~~~sh
    npm run test
    ~~~
    or
    ~~~sh
    npm test
    ~~~
1. 下記の結果となれば問題なく`check.test.ts`ファイルが実行されたことが確認できる
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/293bc892-47ae-144f-4da2-076fc7fb6613.png)

# テストを実施する
1. テストファイル（isZero.ts）を作成する
    ~~~sh
    touch isZero.ts
    ~~~
1. テストファイル（isZero.ts）に下記を記載する
    ~~~js:isZero.ts
    function isZero(value: number): boolean {
      return value === 0;
    }
    ~~~
1. `component`として使用できるよう、関数をエクスポートする
    ~~~js:isZero.ts
    export function isZero(value: number): boolean {
      return value === 0;
    }
    ~~~
1. `isZero.ts`のテストが実行できるように、テストコードを作成する
    ~~~sh
    touch isZero.test.ts
    ~~~

1. テストコードで`isZero.ts`のテストが実行できるように、関数をインポートする
    ~~~js.isZero.test.ts
    import { isZero } from "./isZero";
    ~~~

1. `isZero`関数に`0`を渡したら`true`が返るかをチェックするテストコードを書く
    ~~~js.isZero.test.ts
    import { isZero } from "./isZero";
     
    test("0を渡したらtrueになること", () => {
      const result = isZero(0);
      expect(result).toBe(true);
    });
    ~~~

1. `jest`コマンドでテスト実行する
    ~~~sh
    npm run test
    ~~~

1. テストケースを追加する
    ~~~js.isZero.test.ts
    import { isZero } from "./isZero";
     
    test("0を渡したらtrueになること", () => {
      const result = isZero(0);
      expect(result).toBe(true);
    });
     
    test("1を渡したらfalseになること", () => {
      const result = isZero(1);
      expect(result).toBe(false);
    });
    ~~~

1. `jest`コマンドでテスト実行する
    ~~~sh
    npm run test
    ~~~


# ディレクトリ構成
~~~:directory_structure
drive/ ←ルートディレクトリ
├── Applications/
├── Syetem/
└── Usr/ ←usr/（隠しファイル）とは異なるファイル
│   ├── shared/
│   └── personnel(ex. Jochun)/　←ホームディレクトリ
│       ├── jest-tutorial/
│       │   ├── node_modules/ ←TypeScriptのコンパイラ
│       │   ├── package.json 
│       │   ├── check.test.ts ←Jestが動くかを確認する
│       │   ├── isZero.ts ←
│       │   └── isZero.test.ts ←
│       ├── MyVagrant/
│       ├── Desktop/
│       ├── Downloads/
│       ├── Documents/
│       ├── .config/
│       ├── .ssh/
│       ├── .zshrc/
│       └── .local/
│       │   ├── .bin
│       │   ├── 
~~~



# 参考リンク
### メイン
- [Jestでテストを書こう](https://typescriptbook.jp/tutorials/jest)

### サブ
- [typescript環境にJestを導入する](https://qiita.com/mktu/items/d36416baba155dfecc00)

### プロジェクトルートについて
- [新規プロジェクトの作成: プロジェクトディレクトリの選択 ﻿](https://pleiades.io/help/phpstorm/create-new-project-choose-project-directory.html#:~:text=プロジェクトルートは、すべての,などに関与します%E3%80%82)


### `-g`オプションについて
- [npm installコマンドの-gオプションについて](https://replication.hatenablog.com/entry/20110607/1307458180)
- [npm install パッケージ -g の「-g」について調べた](https://qiita.com/recxu/items/d9cb5e023296733fc89e)

### `-D`オプションについて
- [そろそろ適当に npm install するのを卒業する](https://zenn.dev/ikuraikura/articles/71b917ab11ae690e3cd7)