はじめに
みなさん、テスト書いてますか?
プロジェクトが大きくなってくると、
今変更しているディレクトリとは全く関係のないテストが実行されるの煩わしいと感じることありませんか?
今まで、Makefileで全部のテストを実行した後pushするようなMakefileは使っていたのですが、
今変更しているディレクトリだけテスト回せないのかなーと思い、試してみた記録を残したいと思います。
よかったら参考にしつつアレンジしてみていただけたらと思います。
この記事の対象者
- vitest使用者
- Makefile使ったことある人
です。
前提条件
以下のようなディレクトリ構造を前提とします
web
├── src
├── Service1
│ ├── components
│ ├── hoge1.test.tsx
│ └── fuga1.test.ts
├── Service2
│ ├── components
│ ├── hoge2.test.tsx
│ └── fuga2.test.ts
├── Service3
略
開発を行なっていて、例えば、Service1
の作業を行っているだけの変更している時にtest
を実行するとして、全く変更を行っていない、Sevice2, 3 のテストを無駄に回して時間を浪費するのは勿体無くね?というところから、Makefileを改良したいと思い立った人の記事になります。
まず結果系
package.jsonのscripts抜粋
{
"scripts": {
"test": "vitest --watch=false",
"test:service1": "vitest --watch=false src/Service1/**",
"test:service2": "vitest --watch=false src/Service2/**",
"test:service3": "vitest --watch=false src/Service3/**"
}
}
webディレクトリ直下のMakefile
.PHONY: test test-service1 test-sevice2 test-service3
test:
npm run test
test-service1:
npm run test:service1
test-service2:
npm run test:service2
test-service3:
npm run test:service3
ルート直下のMakefile
(本来ならバックエンド側のテストなども含まれるが割愛)
.PHONY: submit submit-service1 submit-servic2 submit-service3
CURRENT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
submit:
make -C web test
git push origin $(CURRENT_BRANCH)
submit-service1:
make -C web test-service1
git push origin $(CURRENT_BRANCH)
submit-service2:
make -C web test-service2
git push origin $(CURRENT_BRANCH)
submit-service3:
make -C web test-service3
git push origin $(CURRENT_BRANCH)
ざっくり説明
基本的には、package.jsonに記述しているscriptsのコマンドでどのディレクトリのテストを実行するか定義しています。
package.jsonのscripts再掲
{
"scripts": {
"test": "vitest --watch=false",
"test:service1": "vitest --watch=false src/Service1/**",
"test:service2": "vitest --watch=false src/Service2/**",
"test:service3": "vitest --watch=false src/Service3/**"
}
}
test
コマンドを実行した場合は、全てのテストが実行されます。
test:service1
などのコマンドの場合、src/Service1/**
のように、Service1のディレクトリ内のみのテストを実行するので、Service1のコードを修正している時は関係ないService2, 3のテストは実行されなくなるので時間短縮につながるという寸法です。
あとは、webディレクトリの直下にMakefileを記述し、make
コマンドでそれぞれのscriptを呼び出せばいいので、
.PHONY: test test-service1 test-sevice2 test-service3
test:
npm run test
test-service1:
npm run test:service1
test-service2:
npm run test:service2
test-service3:
npm run test:service3
このような形でMakefileを記述しました。
ルート直下のMakefileでは、テストを実行したあとそのままpushしたいので、
.PHONY: submit submit-service1 submit-servic2 submit-service3
CURRENT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
submit:
make -C web test
git push origin $(CURRENT_BRANCH)
submit-service1:
make -C web test-service1
git push origin $(CURRENT_BRANCH)
submit-service2:
make -C web test-service2
git push origin $(CURRENT_BRANCH)
submit-service3:
make -C web test-service3
git push origin $(CURRENT_BRANCH)
このようにmake submit
で全てのテストを実行しつつpushするのか、make submit-service1
のように、Service1のテストだけ実行してpushするのか?などを選択できるようにしています。
補足
ルート直下のMakefileですが、
git push
する際、どのブランチにpushするべきかを取得してコマンド内に流し込めるよう、
CURRENT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD)
で、現在のブランチ名を取得して
git push origin $(CURRENT_BRANCH)
のコマンドで動的に与えることで、mainブランチ以外で作業していても同様にコマンドを使うことができるという工夫が入っています。
また、make -C web test
でも見慣れない-C
オプションが入っていますが、
-C
の後ろのディレクトリ内に入った状態でどのmakeコマンドを実行するか?という記述をすることができ、
この場合のmake test
はwebディレクトリ内で実行した時の内容と同じコードが実行されることを意味しています。
このオプションを知らないと、
cd web && make test
のようなコマンドを記述することになり、正しくディレクトリが移動された状態でmake test
が実行されるのか保証されないらしい(!?)ので、できる限り-Cオプションを使うようにするのが得策のようです。
まとめ
ディレクトリを絞ってテストを実行する場合は、まずpackage.jsonに対象とするディレクトリのオプションを与えたものを準備し、そのスクリプトをMakefileから実行するとやりたいことができそうです。
Makefileの取り扱い方については自分自身まだまだ初心者の域を出ませんが、上手に使いこなせるようになりたいものです。
それではみなさま良きコードライフを。