パルカワ2

最近はFlutterをやっています

仕様書は必要か?

ここでいう仕様書とは、仕様(=システムにおける検証可能な振る舞い)が記載されたドキュメントである。

社会人として10年くらいソフトウェアエンジニアをやってきて、今まで関わってきたサービスでいわゆる仕様書を書いたことがない気がする。プロダクトマネージャーやデザイナーたちと顧客からの要求を元に「こういう感じで作りましょう」という話をして実際に作っていくし、そこで話した内容とかは議事録とかに残ってるかもしれないが「はい、これが仕様書です」って渡されたこともない気がする。

仕様書は書いてこなかったが自動テストは書いてきた。ソフトウェアのテストを書けば”システムにおける検証可能な振る舞い”がテストに記載されるわけだし、仕様とはシステムにおける検証可能な振る舞いであるはずで自動テストがあれば仕様を記載する仕様書なるものは不要であると思っていた。

自動テストを仕様書とするのでは不十分?

先に書いた通り、仕様が書かれるのは自動テストで十分であると思っていたのだが品質やソフトウェアテストなどについて学んでいると品質の作り込みのために以下のようなことを満たしたいと思えてきた。

  • 早い段階での仕様の定義とレビューが出来ること
  • すでに実装された仕様がいつでも誰でも把握できること

これらを満たすには、エンジニア以外を含む開発に関わるメンバーが仕様を定義出来て、理解もできる形で記載されている必要があると思った。

つまり、自動テストのようにプログラムで仕様が書かれているとプログラムを書ける人しか書けないしプログラムを理解出来る人にしか理解出来ない*1。実装を理解していないとどこに仕様が記載されているかも把握出来ない。これだと早い段階での定義やレビューもいつでも誰でも仕様を把握することも満たすことは出来ない。

なので、仕様書と自動テストは分離されているべきではないかと考えた。

どのような仕様書がよいのか?

いま必要な仕様書は、開発に関わるメンバーが仕様を定義出来て理解も出来る仕様書である。

これらを満たすのは、ある程度ルールが定まった自然言語で記載された仕様書だと思った。例えば、仕様書を日本語で書くとすると日本語が理解して書ける人間は当然理解出来るし当然書ける。

逆にデメリットは自然言語は自由なので曖昧になりがちだと思う。それを防ぐためにルールを作ると良さそうだと思っているが自分はある程度こうすればいいなというのは見えているもののまだ模索中である。

仕様書と自動テストを分けた場合の課題とは?

仕様書と自動テストを分離すると更新する場所が増えるのが問題になる。仕様書を更新しただけでは自動テストは更新されないし、自動テストを更新しただけでは仕様書は更新されない。

それを防ぐのに仕様書に記載された情報を使って自動テストを実行する仕組みであるGuageやCucumberを使うとよいと思う。個人的には、Markdown-likeなsyntaxで記載出来るGuageがいい。まぁDartのRunnerがないので僕らは自前で頑張る必要があるんですが………。

gauge.org

追記:DartのGherkinパッケージには、Runnerもあるみたいなのでそれを利用するとよさそう。

まとめ

品質を作り込むには仕様書は必要だと思う。しかし仕様書と自動テストを分けると更新する場所が2箇所になってだるい問題が出てくる。なのでGuageなどを使うとよいと思う。

*1:実行すれば理解出来る形にアウトプットされるかもしれないが、実行しないといけない

ソフトウェア要求と仕様: 実践,原理,偏見の辞典 を読んだ

そうだねって内容でありつつも例え話が多くて自分にはあまりシックリ来なかった。

一汁一菜でよいという提案を読んだ

つくりおき.jpというサービスを利用していたのだけど、なんだか一日が楽しくない。味はかなり気に入っていて美味しいのだけど、リモートワークで毎日朝昼夜とすでに決まっているご飯から選んで食べるのがなかなかストレスに感じているのかもしれないと思えてきた。

なので自炊をしようかな〜でもめんどくせ〜という話をしたら一汁一菜でよいという提案を勧められた。

本の内容は、タイトルそのままで一汁一菜でよいという提案をされる。一汁一菜って言っても一菜(漬物)すらなくてもいいという提案なんだけど、読んでみて自分の中でいろいろな囚われがあったなと気づいた。例えば、一汁三菜とまではいかなくても主菜と副菜1品くらいは用意しなきゃ!とか美味しいものを作らなきゃ!とかレシピ見ないと美味しいものは作れない!とか自分が無意識に決めつけていたなと思った。

失敗してまずくてもいいし、日常的に何品も作るとかそこまで頑張る必要はないなと思った。1週間ほど経ったけど、毎日朝昼夜全部自炊してる。まぁ、朝はトースト焼くくらいだけど。

自分の中で特に衝撃的だったのは、味噌汁って自由なんだ!!!って気づいたことで、何いれてもいいし使うもので結構彩りも綺麗にできる。自分の中で料理は彩りが綺麗に出来ると満足度が高い。

Docusaurusを動かしてみた

docusaurus.io

動機

チームのストック型のレビューが必要なドキュメント(手順書, 仕様書など)をGitHubで管理をするならどういうのがあるのか気になったので、OSSでよく使われてそうなDocusaurusを試してみた。名前かわいい

下調べ

Docusaurusの強みは、MDXが使えたりAlgoliaの検索が使えたり翻訳やバージョニングに対応してたりするのが強み。ただチームのストック型のドキュメントで考えると翻訳やバージョニングは不要かなと思う。OSSだと便利そう。

特にAlgoliaの検索が気になっていて、Docusaurusで作られているJestの日本語ドキュメントで試したところ良さそうだった。ただちょっと補完したときにEnterを押すとドキュメント選択したことになってしまうのでバグってそうだけどいざとなったらOSSなので自分で頑張れる。

ただAlgoliaのDocSearchがオープンなドキュメントを対象としているので、IPでアクセスを制限しているプライベートなドキュメントはOSSになっているdocsearch-scraperを使って自分でindexしてあげる必要がある。しかしログインが必要なプライベートページには対応していないっぽい。例えばGitHub PagesでprivateにしているとGitHubのログインが必要になるはずなのでダメそう。

しかもクローラーOSS自体も2週間ほど前に新しいDocSearchがリリースされたことで非推奨になってしまった。まだ使えるとはいえ新しいDocSearchの仕様が変わったりしたら困るし、自前で頑張ればいいけどまあ…めんどくさいよね…

Migrating from legacy | DocSearch by Algolia

動かした

まあ、一応やってみるかということでやってみた。

以下を実行してprivate repoにpushしてNetlifyにデプロイした。すぐできる。Deploy to Netlifyもあったけどエラーになった。あとNetlifyは認証を使うにはお金がかかるらしいので試していない。

npx @docusaurus/init@latest init website classic

肝心のAlgoliaは、Netlifyと連携していてAlgolia Crawlerがまだ使えない人でもAlgolia Crawlerを使える。しかもpushするたびクロールしてくれる。

Quickstart for Using Algolia on Netlify

ただsitemap.xmlに記載されているURLが、/docs/tutorial-extras/manage-docs-versions/docs/tutorial-extras/manage-docs-versions/ にリダイレクトされてIgnoreされる。

しかし、sitemapに記載されている /docs/tutorial-extras/manage-docs-versions を優先するのでリダイレクトされたあとのURLもignoreされるという悲しいことが起きてしまう。

f:id:hisaichi5518:20220215184234p:plain
ドキュメントの大半がIgnoreされている

これをどうにかしたかったけどsitemap生成するプラグインも設定がないようなので諦めた。

所感

結構期待して調べてたけど、まあサクッとはいかんなという感じだった。OSSには良さそう。

チームが品質を作り込むために必要なこととは

ここ数ヶ月、品質やソフトウェアテストについて学んできた。本を読んだり入社予定のSET(業務委託中)と話したりしていて、学ぶ前の自分は品質保証を間違えて理解していたのだなと思うので共有する。

テストは品質を保証しない

2ヶ月くらい前の自分の中では、品質保証とは以下の図にあるテストの部分が品質保証にあたり、リリース前にテストすることで品質は保証される!と思っていた。

f:id:hisaichi5518:20220213024708p:plain
雑な開発ライフサイクル

しかし、たくさんテストをしてたくさんバグを発見したとしても、バグを修正せずにリリースされれば品質を保証したとは言えないし、見つけたバグをすべて修正したとしてもプロダクトにバグがないことの証明にはならないので完全に品質を保証することは出来ない。

テストは、欠陥*1に気付く手助けをしてくれてそれはリスク軽減にもなるが、根本的に欠陥を防ぐものではないし欠陥がないことを証明するものでもない。

品質保証とはなにか?

品質保証とは、開発チーム*2が「このプロダクトは品質が高い」と言える状態にすることだと思っていた。では、開発チームはどうやって「このプロダクトは品質が高い」と判断するのか?

品質とはを語るとき「品質は誰かにとっての価値である」というワインバーグの言葉がよく引用されている。プロダクトの品質において"誰か"とは顧客*3で"品質とは顧客にとっての価値である"と言える。

つまり、プロダクトの品質が顧客にとって高いかどうかを判断出来るのは顧客だけであって開発チームではない。なので開発チームだけで「このプロダクトは品質が高い!」と主張することは出来ないのではないかと思う。

Agile Testing Condensedを読んでいると「チームで品質を作り込む」「チームで品質に責任を持つ」という言葉が出てくる。品質保証とは、チームが品質を作り込み品質に責任を持つことであると自分の中では理解した。

ちなみにこのチームのメンバーは、エンジニア・デザイナー・PdMだけではない。テスターもCSもビジネスチームもパートナー企業もチームメンバーである。またQAエンジニアは、品質を作り込み責任を持つ人ではなくチームに対して品質を作り込むように促し同様に品質に責任を持つように促す人と僕は認識している。

品質を作り込む開発ライフサイクル

ではチームで品質を作り込むには、チーム全員で実装したものをテストするのがよいのか?といえばそうではない。実装したものをテストするにはテストするまで時間がかかるし、バグを見つけても修正するのに時間がかかる。時間がかかるということは、顧客に価値が届くまで遅くなってしまうし開発チームのリソースも奪い取りアジリティがあるとは言えない。またリリース後にバグの検出が出来ておらずそのまま放置されていたりしたら顧客にとっての価値を作り込めているとは言えない。

なので、リリース前にテストを行うのではなく開発ライフサイクル自体が品質を作り込む形になっている必要がある。

チーム全員が各ステージで"テスト"をする

品質を作り込む開発ライフサイクルは、チーム全員が各ステージ(要件定義・設計・実装・リリース等)でテストを行う。

テストを行うといってもテストケースを作ってテストすることだけがテストではない。そのステージでの成果物たちに対してレビューを行い質問などをすることもテストである。このテストをステージごとに繰り返す事でアジリティを持って品質を作り込む事が出来る。

最近の自分の例で言うと自分が実装する時に与えられた要求を頭の中で整理してそのままコードを書いてテストを書くのではなく、一旦実装しようと思っているものを仕様として箇条書きにしてパートナー企業に共有した*4。それに対してパートナー企業からフィードバックや質問が来るので、それに答えたり参考にすることで仕様のバグを見つけることが出来た。このパートナー企業がしてくれた質問やフィードバックもテストであり、実装前だがテストを行ってチームで品質を作り込んだと言える。

Holistic testing

品質を作り込む開発ライフサイクルについて書いていたが、アジャイル・テスティングを提唱したJanet Gregoryさんはチーム全員が各ステージでテストをすることをHolistic testingと呼んでいる。

f:id:hisaichi5518:20220211194443j:plain
Holistic testing

引用元: Testing from a holistic point of view - DragonFire Inc.

Holistic testingでは、テストが明確にステージとして定義されておらず、各ステージの中でテストが行われる。テストステージがなくなったことで、手動テストが完全になくなるのかと言えばそうではない。Buildステージでテストするだけである。

ちなみにもともとは継続的テストと言っていたっぽい。ただ継続的テストは人によって定義が違いそうでややこしいので個人的にはHolistic testingと呼ぶのがよい気がする。

まとめ

品質保証とはなにか自分の中で整理をしていたら、チームが品質を作り込み品質に責任を持つことが重要であると理解できた。そのためには、チーム全員が各ステージでテストを行う開発ライフサイクルである必要がある。

ちなみにプロセス品質というのもある。ここでは特に対象としてあげていないがプロダクト品質と同様にチームで作り込むことが重要な品質である。

関連

シェア用の画像 f:id:hisaichi5518:20220214093410p:plain

*1:いわゆるシステムのバグだけではなく、仕様バグや仕様の考慮漏れなども含む

*2:QAチームではない

*3:ここではプロダクトのユーザー

*4:共有はパートナー企業とやり取りしてる同僚がいい感じにやってくれたのだがとても助かった

Agile Testing Condensed Japanese Edition を読んだ

日本語版

Agile Testing Condensed… Yuya Kazama 著 et al. [PDF/iPad/Kindle]

買って読んでなかった。チーム全員で品質の作り込みチーム全員が品質に責任を持つことが大事でそれは継続的テストであるみたいな話からそれをどうやるのかが簡単に書かれている。最近仕様書について考えていてもうだめだと思っていたのだが、ここに書かれていたことは大変参考になった。

Notionでのドキュメント管理の何がつらいか

Notionでドキュメントを書いてる。ドキュメントは書く、共有する、読むなどユーザーそれぞれ色々なシナリオがあり、そのシナリオそれぞれでつらみがある。

Notionに限らずすべてのサービスは使っていればつらいところはあると思っていて、つらいとはいえNotionから別のドキュメント管理サービスに乗り換えたいという気持ちは全くなく何がつらいのか考えNotionでなにか出来ることはないか考えたり、つらみを共有することで知見を得たい。

検索がつらい

フロー型とストック型の情報が入り乱れる

検索をする時はストック型の情報を探すことが多い。例えば、リリース作業手順ドキュメントを探したいときに「リリース 作業 手順」で検索するけど日報や議事録などは検索から除外したい。

Notionの検索には、FilterでPageの指定が出来るのでそれを駆使するしかない。Pageの指定をした場合、Pageの配下は検索対象になるので、ストック型の情報を置くPageの配下にはフロー型のドキュメントを置かないのがよい。

Filterを追加するまでの道のりが長い

command + pでQuick Findを立ち上げて検索したい文字を入力、結果が出るまで数秒待ち、結果が出たら右上のAdd Filterをマウスでクリックして、Filterを追加する。

あまりにだるすぎるのでタイトル検索をしたい時はCommand+Eを使っている。自分のアクセスした履歴から高速に検索出来る。ただCommand+Eは今インストールできなくなっているようなので、Raycastなどを使うとよさそう。またこれは自分がアクセスしたページの検索なので、新しい情報を探したい時は歯を食いしばるほかない。

Only match titlesは親のページタイトルも対象となる

これは良いのか悪いのか。僕は嬉しいと思ったことはない。例えば「SWE採用」というページの配下にある「選考内容」というページは「SWE 採用」でタイトル検索すると検索結果に出てくる。

Quick Findを開いても、検索を実行してもURLが変わらない

つまり検索結果のURLが共有出来ない。

シノニム検索が出来ない

例えば採用関連のドキュメントを探したいと思って「SWE 採用」とかでタイトル検索して全然見つからない。実はタイトルには「選考」と書かれていた時には検索結果に出てこない。まぁこれは日本語だししょうがないよねという気持ちはある。

ドキュメントを書く人間たちが利用する単語を共通化していくしかないが、そんなことを考えながらドキュメントを書くのは大変。linterなどで自動化出来れば良いが後述の通りしにくい。

自前で検索サイトを持つのはやりすぎ感ある。

遅い

検索するたびに1,2秒くらい待ってて、そのくらい待てという話だけどGoogleなどで早い検索に慣れてしまっているのでつらい

構造の管理がつらい

最高でイケてる構造がわからない

ドキュメントって会社によって内容は違うだろうしベスト・オブ・構造が存在するのかは謎ではある。会社だけではなく職種によっても違うかも。会社もフェーズによって別の会社のようになるので定期的なリファクタリングは必要そう。プログラムと一緒ですね。

ドキュメントをどこに置けばいいのかわからない

AでもあるしBでもあるみたいなドキュメントが生まれたりする。Aの配下に置くかBの配下に置くか悩む。とりあえずAの配下に置いてBのページを参照したりするけど、別の人はAとの関連性をわかっておらず、Bにあると思って探して見つからない…となる。Notionにはbacklinksというのがあって、対象のドキュメントを参照しているドキュメントを確認出来るので、Bのbacklinksを見れば発見することは出来るが、クリックしないと見れないしBにあると思ってるのでわざわざ見ない。

どこに置くべきかわからなかったらまずは「メモ」というDatabaseにページを作って書くようにしてる。でも結局書き終えたら移動する必要がありそこで困って結局メモに置きっぱなしになってしまいストックできない。

こうなるとやはり構造を見直すしかない気がする。

ドキュメントを構造化するのであれば参照関係が複雑になると大変な気がする。プログラムの設計で単一方向のデータフローがどうこうみたいな話に似てると思った。子ページは自分より上のページを参照するべきじゃないみたいな。しかし、ドキュメントって参照関係生まれがちだよなぁ

書くのがつらい

更新に意味を持たせられない

更新履歴はあるけどcommitという概念はないので変更を意味のあるひとまとまりに出来ないしcommit logが書けない。commit logがあればなぜその行を追加したのかの理由を書けるけど書けない。あとから見た時に、はて?となる時がある。

その行を追加する理由をドキュメント自体に書けばいいのかもしれないけどドキュメント自体にそれは不要で冗長になる印象

gitに慣れているからというのはありそう。

ドキュメントに対してエラーを出しにくい

GitHub Actionsみたいなのがないので変更があったらlintを実行してダメならエラーを出すみたいなのがしにくい。例えば、仕様書で特定の曖昧な言葉があった時に警告を出すみたいなの。もしかしたらNotion APIで出来るのかもしれないのでしにくいと言ってる。試していない。逆にZapierと連携出来たりするのは楽でいい

ドキュメントのステータスがわからない

タイトルにWIPをつける人もいればつけない人もいる。tagでステータスの管理をすればいいけど必須には出来ないし、ドキュメントのDatabaseによって管理されたりされなかったりするので困る。

ドキュメントのステータス管理を統一するのがいいのかもしれない。

更新しやす過ぎる

更新しやすいのでレビューを通らずに更新できたりもする。

また更新しやすいゆえに間違えて更新/削除してるときもある。こういうのは大体更新履歴を見ればわかるけど更新履歴が積み上がってわからないとき困る。

レビューがつらい

レビュープロセスが必須ではない

権限があれば誰でもどこにでもドキュメントを置ける。ドキュメントの中身のレビューもしたいが、ドキュメントをどこに置くかという観点でのレビューも当然出来ないのでカオスになりやすい。

どこが変更されたのかわからない

更新履歴はあるにはあるけど、意味があるまとまりではないし、Diffは出ないので自分の目で確認するしかない。

どこが変更されたのかわかりやすいように新たにドキュメントを書いたりするが、新しいドキュメントを書いてる途中はどっちが正しいのかわからなくなる。

変更に意味を持たせられないのでどういう意図の変更なのかわからない

書いてる通り

レビューのStatus管理などレビューの仕組み自体を自分たちで考える必要がある

書いてる通り

文章につけたコメントは文章を削除すると一緒に削除される

コメントで議論したり変更した理由を文章を引用してコメントに残しても文章を消すとコメントは消える。

まとめ

後半、つらいところだけになってしまったがいい感じになりたいのでいい感じになる方法があったら教えてください。