ここでいう仕様書とは、仕様(=システムにおける検証可能な振る舞い)が記載されたドキュメントである。
社会人として10年くらいソフトウェアエンジニアをやってきて、今まで関わってきたサービスでいわゆる仕様書を書いたことがない気がする。プロダクトマネージャーやデザイナーたちと顧客からの要求を元に「こういう感じで作りましょう」という話をして実際に作っていくし、そこで話した内容とかは議事録とかに残ってるかもしれないが「はい、これが仕様書です」って渡されたこともない気がする。
仕様書は書いてこなかったが自動テストは書いてきた。ソフトウェアのテストを書けば”システムにおける検証可能な振る舞い”がテストに記載されるわけだし、仕様とはシステムにおける検証可能な振る舞いであるはずで自動テストがあれば仕様を記載する仕様書なるものは不要であると思っていた。
自動テストを仕様書とするのでは不十分?
先に書いた通り、仕様が書かれるのは自動テストで十分であると思っていたのだが品質やソフトウェアテストなどについて学んでいると品質の作り込みのために以下のようなことを満たしたいと思えてきた。
- 早い段階での仕様の定義とレビューが出来ること
- すでに実装された仕様がいつでも誰でも把握できること
これらを満たすには、エンジニア以外を含む開発に関わるメンバーが仕様を定義出来て、理解もできる形で記載されている必要があると思った。
つまり、自動テストのようにプログラムで仕様が書かれているとプログラムを書ける人しか書けないしプログラムを理解出来る人にしか理解出来ない*1。実装を理解していないとどこに仕様が記載されているかも把握出来ない。これだと早い段階での定義やレビューもいつでも誰でも仕様を把握することも満たすことは出来ない。
なので、仕様書と自動テストは分離されているべきではないかと考えた。
どのような仕様書がよいのか?
いま必要な仕様書は、開発に関わるメンバーが仕様を定義出来て理解も出来る仕様書である。
これらを満たすのは、ある程度ルールが定まった自然言語で記載された仕様書だと思った。例えば、仕様書を日本語で書くとすると日本語が理解して書ける人間は当然理解出来るし当然書ける。
逆にデメリットは自然言語は自由なので曖昧になりがちだと思う。それを防ぐためにルールを作ると良さそうだと思っているが自分はある程度こうすればいいなというのは見えているもののまだ模索中である。
仕様書と自動テストを分けた場合の課題とは?
仕様書と自動テストを分離すると更新する場所が増えるのが問題になる。仕様書を更新しただけでは自動テストは更新されないし、自動テストを更新しただけでは仕様書は更新されない。
それを防ぐのに仕様書に記載された情報を使って自動テストを実行する仕組みであるGuageやCucumberを使うとよいと思う。個人的には、Markdown-likeなsyntaxで記載出来るGuageがいい。まぁDartのRunnerがないので僕らは自前で頑張る必要があるんですが………。
追記:DartのGherkinパッケージには、Runnerもあるみたいなのでそれを利用するとよさそう。
自分はつかったことないけど Gherkin というのもあって、dartで https://t.co/zztcux0oBp があるみたい
— Koichi Ishida (@wapa5pow) 2022年2月27日
Gherkinって記法だからRunnerあるのかなと思ったらDartのライブラリにはRunnerがありそうですね Dartならこれでよさそう
— ひさいち (@hisaichi5518) 2022年2月28日
まとめ
品質を作り込むには仕様書は必要だと思う。しかし仕様書と自動テストを分けると更新する場所が2箇所になってだるい問題が出てくる。なのでGuageなどを使うとよいと思う。
*1:実行すれば理解出来る形にアウトプットされるかもしれないが、実行しないといけない