💯

実装系問題のためにTypeScriptのテスト環境を構築する

に公開

こんにちは,みーやです!

初夏の候,この季節はエンジニア学生向けサマーインターンの選考が各所で行われているかと思います.
実際に私も複数社の選考を受けている最中でして,特に最初の壁となるのはコーディングテストかと思います.
コーディングテストの中には複雑な仕様が与えられる問題があり,問題の規模や複雑さから,理解に時間がかかったりケアレスミスでコードに間違いがあるなどして,時間がかかるケースがよくあると思います.
そのような場合にローカル PC で効率的にテストするための環境構築の方法をご紹介します!

(背景として,このテスト環境構築に時間がかかったのと,この環境がもたらすメリットがいっぱいあったので共有させていただきます...!)

想定する読者

  • コーディングテスト(特に実装形問題)を受けているエンジニア学生
  • テストにパスするのに苦労していたりなど,ローカルでのテスト環境を必要としている方
  • TypeScript が大好きな方

留意事項

この手法は,「コーディングテストにてローカル環境での作業が許可されている場合のみ」利用できます.選考企業の定めるルールによって違反となることもあるので注意してください.選考企業の提示するルールを詳しく読むことをお勧めします.

また,本記事で記述した内容は,Node や各種パッケージのバージョン,設定ファイルの内容によってはエラーが出て実行できないことがあります.その際はコメントをいただけるとうれしいです.

実行環境

コーディングテストのシステムとして,主な企業ではTrack Job, HackerRankなどが利用されているかと思います.今回の記事ではTrack Jobを一応の対象とします.

  • 想定するテストシステム:Track Job
  • 想定する問題種別:実装系問題

実装系問題とは何か,知りたい方がいたら,以下の記事が参考になると思います!

https://speakerdeck.com/lycorp_recruit_jp/lineyahuxin-zu-cai-yong-kodeingutesutojie-shuo-shi-zhuang-wen-ti-bian

ちなみに,わたしの実行環境は以下の通りです.

item name, version
OS Mac OS Sequoia 15.3.1
Editor Cursor 0.49.6
JS Compiler Node 21.1.0

環境構築の手順

  1. 問題用にディレクトリを作成し移動する.

    $ mkdir 1_hotel-reservation
    $ cd 1_hotel-reservation
    
  2. 各種ファイルを用意する

    1. package.json

      TypeScript の実行に必要なパッケージを記述します.

      {
        "type": "module",
        "devDependencies": {
          "@types/node": "^18.19.86",
          "ts-node": "^10.9.2",
          "typescript": "^5.8.3",
          "undici-types": "^7.8.0"
        }
      }
      
    2. tsconfig.json

      TypeScript のコンパイラオプションを記述します.
      ここでは,NodeNextを指定することで ES モジュールを利用できるようにしています.

      {
        "compilerOptions": {
          "target": "ES2020",
          "module": "NodeNext",
          "moduleResolution": "nodenext",
          "esModuleInterop": true,
          "resolveJsonModule": true,
          "allowJs": true,
          "strict": true,
          "skipLibCheck": true
        }
      }
      
    3. index.ts
      実際に問題を解くためのコード(のメイン関数)を記述します.雛形は以下の通りです.

      function main(lines: string[]) {
        // your code here
        for (const line of lines) {
          console.log(line);
        }
      }
      
      function readFromStdin(): Promise<string[]> {
        return new Promise((resolve) => {
          let data: string = "";
          process.stdin.resume();
          process.stdin.setEncoding("utf8");
      
          process.stdin.on("data", (d) => {
            data += d;
          });
          process.stdin.on("end", () => {
            resolve(data.split("\n"));
          });
        });
      }
      
      readFromStdin().then(main);
      
    4. gitignore
      Git を利用している場合,gitignoreを作成するのがオススメです.以下にファイル内容の一例を示します.

      *
      !*/
      !*.*
      *.exe
      node_modules/
      
  3. 各種パッケージのインストール

    上記のファイルを作成したら,以下のコマンドを実行して必要なパッケージをインストールします.

    $ npm install
    

テストファイルの準備

テスト用の入力ファイルを用意します.Track Jobであれば問題側に複数個提供されているので,それをコピーして手元で利用します.

たとえば,中身が以下のようなファイルtest.inを用意します.

Hello, world!

これは,以下のコマンドを実行することでも達成できます.

$ echo "Hello, world!" > test.in

テストの実行方法

以下のコマンドを実行します.すると,ターミナルに実行結果が出力されます.

$ node --loader ts-node/esm index.ts < test.in

以上でローカルでのテスト環境構築ができました!

理想出力と実際出力の比較

さらなるデバッグのために理想出力と実際出力を比較する場合,以下のような手法が考えられます.

  1. 理想出力をテストシステムから取得しておく(ファイル名をtest.outとします)

  2. 以下のコマンドを実行し,自分の書いたコードによる実行結果をファイル出力します(ファイル名をmy.outとします)

    $ node --loader ts-node/esm main.ts < test.in > my.out
    
  3. エディタの機能やコマンドを利用して,test.outmy.outを比較します.
    たとえば,Cursor であれば以下の方法で比較できます.

    1. 比較元のファイル(たとえばtest.out)をエディタ上に展開した状態でコマンドパレットを開き(Ctrl[cmd] + Shift + P)),メニューからFile: Compare Active File With...を選択します.
    2. 比較先のファイル(たとえばmy.out)を選択します.
    3. 新たなファイルビューが開き,差分が色付きで表示されます.

おわりに

今回は,コーディングテスト(実装系問題)にてローカルで効率的なテスト環境を構築する方法をご紹介しました.

個人的には,いままで実装系問題は Python で解いていたのですが,型がない()ためにデバッグや仕様理解に苦労していました.今回,言語を TypeScript に乗り換えることで,デバッグが楽しくなり,肌がキレイになり,さらには彼女もできました.

本記事の内容によってみなさんのコーディングテストライフがさらにハッピーになり,さらにはサマーインターンで夏休みと就活を無双していただければ幸いです!

ここまでお読みいただきありがとうございました 🌸

Discussion