読者です 読者をやめる 読者になる 読者になる

構造化されたテストスクリプト群の実行ツール

計算機 Python 手慰み

テストコードってどんどん増えていく。だらだらスクリプトを書くのは簡単だが、すぐに収拾が付かなくなり、経済的に耐えられないレベルで混乱してくる。何のテストをしているのかももちろんわからないが、動かし方も分からないし、どうなったらpassなのかも分からないような、テストスイートが乱立して、もう全部すてればと思ってしまうほどになる。

テストの自動化を整備するなら、アーキテクチャが必要だ。ユニットテストは、JUnitやSpockやBatsなどの便利なフレームワークがあるので、散らかりっぷりが抑えられる。フレームワークの良さは、それに従えば勝手に整理されるということだ。

システムテストになってくると、システムによってテストも大きく異なってくるので、テスティングフレームワークと呼べるほどに親切なフレームワークを作るのは難しい。だが、既存のテスティングフレームワークの思想は参考にできることが多い:

  • テストケースで共通化できる処理は、Before / After でまとめる;
  • テストケースは独立である;
  • テストは繰り返し実行可能である。

乱立して増え続けるテスト用のスクリプト群もこれを守るように構造化されれば、経済的なメリットは大きいだろう。

そこで、構造化されたテストスクリプト群を実行するツールを作っている。構造化されていることを期待して実行するので、構造化されていなければテストを実行できず、構造化された状態が保たれるはず――という寸法だ。

test
├── after
│   └── run_destroy.sh
├── before
│   └── run_deploy.sh
├── testsuite1
│   ├── setup_db.sh
│   ├── test1.sh
│   └── test2.sh
└── testsuite2
    ├── post-run.sh
    ├── pre-run.sh
    ├── run1.sh
    └── run2.sh

上のようなディレクトリ構造のテストがあったときに、テストを実行すると以下のようにディレクトリ構造にしたがってスクリプトが実行される。

1..14
ok 1 before/run_deploy.sh # 0.0 sec
ok 2 testsuite1/setup_db.sh # 0.0 sec
ok 3 testsuite1/test1.sh # 0.0 sec
ok 4 testsuite1/setup_db.sh # 0.0 sec
ok 5 testsuite1/test2.sh # 0.0 sec
ok 6 after/run_destroy.sh # 0.0 sec
ok 7 before/run_deploy.sh # 0.0 sec
ok 8 testsuite2/pre-run.sh # 0.0 sec
ok 9 testsuite2/run1.sh # 0.0 sec
ok 10 testsuite2/post-run.sh # 0.0 sec
ok 11 testsuite2/pre-run.sh # 0.0 sec
ok 12 testsuite2/run2.sh # 0.0 sec
ok 13 testsuite2/post-run.sh # 0.0 sec
ok 14 after/run_destroy.sh # 0.0 sec

run, testの前後に同じ階層のbefore/after, pre/post, setup/teardownが実行されていく。

JUnitとちがって、before/afterも1ケースとしている。これはスクリプトファイルを独立して扱いたいという意図である。

それぞれのスクリプトは、シェルスクリプトをベタ書きしても良いし、そこから Ansible や他のテスティングフレームワークなどの別のツールを呼んだりする。

Jenkinsとの組み合わせを意図してTAPで結果を出力するようにしている。おそらく世間では Jenkins のビルドプロジェクトの設定を工夫して、今回したいようなことを実現しているのだろうが、Jenkins と業務が密結合になってしまう。また、Jenkinsを駆使するならば、シェルスクリプトベタ書きと変わらない。間にこういうのをかませたら便利かと思っている。

ある程度できたら公開したい。単純なものは逆に難しかったりする。本当に、JUnit は良く出来ている。


追記 2016-07-24

できた。

TT-Runner: テストスクリプトのディレクトリ構造フレームワーク - 超ウィザード級ハッカーのたのしみ