Skip to content

Instantly share code, notes, and snippets.

@zonuexe
Last active December 31, 2025 05:31
Show Gist options
  • Select an option

  • Save zonuexe/b4c69cacd98479c3be721128bc55117c to your computer and use it in GitHub Desktop.

Select an option

Save zonuexe/b4c69cacd98479c3be721128bc55117c to your computer and use it in GitHub Desktop.
Web開発 vs 忍者式テスト 🥷

先に私(tadsan)の理解

  • テスト技法としての忍者式テストは生きたテストを継続的に成長させるものだと整理できる
  • 品質保証目的というより、チームがプロジェクトに当事者意識を持ち続けられるように、絶えずプロダクトに接する営みである

前提: エクストリーム・プログラミング (XP)

2000年前後に整理されたソフトウェア開発のプラクティス体系。

Extremeは文字通り「過激」とか「極端」という意味だが、登場から20年も経つと一般化して「ふつうのプログラミング」になっている感もある。これが一般攻撃魔法ゾルトラークか…

image

(エクストリーム・プログラミング - Wikipedia2023-09-10T05:14:46版より引用)

前提: Web開発 vs GitHub Flow (トランクベース開発)

私が仕事で携わっているプロジェクト(自社開発のWebサービス)は、基本的にGitHub Flowあるいはトランクベース開発と呼ばれるワークフローに従って開発される。

これはmasterブランチとトピックブランチだけを利用する軽量なワークフローである。

  • 作業者は、必ず最新のmasterからブランチ(feature, hotfixなど)を作成して作業する
  • レビューされたブランチはmasterにマージされ、直ちにデプロイされる
    • フィーチャーフラグを活用することで、コードの有効化を遅延できる

開発者は小さい単位でブランチを作成してチーム内でのコードレビューを経て細かくマージすることが求められる。これはコードの共同所有という考えと、高速かつ信頼性の高いCI(ユニットテスト・静的解析)およびデプロイに支えられている。

忍者式テストとは何か njslyr

image

(忍者式テストを用いた 開発事例の報告より引用)

小さな間隔で反復開発を行なうという点においてはXPを忠実に実行しているとも言えるが、自動テストよりも手動の受け入れテストを重んじている点と、高度な信頼性が求められる医療機器の開発現場で実践しているという点が「忍者式」を特徴付けている。

「どう作るのか?」ではなく、「どう試すのか」を起点に、問い続ける営み。

Note

以下、引用画像は断りない限りソフトウェア・シンポジウム 2023 in 仙台で発表された「「テストからはじめよ」 ~忍者式テスト20年の実践から~」からの引用。

同名の論文と再演のYouTube動画もあるので、参照されたい。

image image

(「テストからはじめよ」 ~忍者式テスト20年の実践から~より引用)

忍者式」とはとても変な名前だが、忍者式テストとはなにか - 忍者式テスト🥷🏻では以下のように説明されている。

UnitTestあるよね?

自動でいいようなことは計算機に任せ、空いた時間で製品を触ろう。

毎日?全部?手で?

毎日、全部、手で。

毎日ストーリー増えるよ?

そう!今日全部確かめることができたのなら、ちょっと増えたって明日も確かめることができるよ!

この様子が忍者のジャンプの訓練を連想させたため、「忍者式テスト」となった。

忍者が毎日若木の上を飛び越える訓練を絶えず行なえば、木が伸びるのと同時に忍者も成長するので、いつしか大木の上もジャンプして飛び越えられずはずだという故事(?)与太話に由来している。

image image

イテレーションを回していくごとにストーリー(≒ 受け入れテスト)は増えていくが、基本はこのテストを古いものからすべて実行していく。そうすると早晩にテスト量が一日で実行できる量を越えてしまうが、そうならないように工夫するところに忍者の極意がある。

image

「毎日」の考え方を変えて量に適応

量が増えすぎたときには、頻度をちょっと工夫するとよい。

毎日一回テストをする、ということは、一度やったテストは24時間やらない、と言い換えることができる。 最後にテストしてから24時間以上経ったテストケースだけを集めたリストが、いまから確かめたいテストケースといえる。

「最後のテストからN時間非表示にする」というのが頻度の調整のアイデアの大元である。

各テストケースごとに非表示にする期間を設定するのはどうだろうか。 直近の成績や開発状況から、このNを計算することで、製品の弱い・脆い部分、実装の若い部分、ユーザーの興味のある部分の頻度を高く、安定している部分の頻度を低くするといった調整が可能になる。

image

プロジェクトの状況によって次世代製品のテスト頻度を密にしたり、古いストーリーのテストを疎にしたり、一段落ついたらまた徐々にテストを再開するということもできる。

image

GitHub Flow vs 忍者式テスト

私が仕事で関わっているプロジェクトはテストカバレッジが高いとまではいえないものの、コードベースの重要な部分に対して必要十分な量のテストが用意されていて、問題のある変更は静的解析かユニットテストで捕捉できるという前提のもと、開発者はコードの変更箇所に直接関連があると見込まれるページのみを手動テストを実施することで迅速なデリバリーを担保している。

一方で忍者式テストはWebアプリケーションとは大幅に異なる医療機器の開発現場で「開発者が対象の製品がストーリーの要件を期待通り満たし続けているか」を確認するためのフローなので、継続的インテグレーションでユニットテストによってリグレッションをチェックするのとはモチベーションが似ているようでかなり違うと感じた。

そもそも起点が「開発者の認識しているストーリー」であって、製品としての品質保証プロセスはまた別にあるはずだ。「テスト駆動開発」は品質保証技法ではないのと同じく、忍者式テストも「エクストリームプログラミングのプラクティス」であって、開発技法だ。

忍者式テストでは「じわじわ開発」を問題視している。これはV字の底の作業(ソフトウェア設計、実装・デバッグ)をずっとやって、複数イテレーションの後にようやくテスト担当が受け入れテストできるようになるという状況だ。

image

これはGitHub Flow(トランクベース開発)で打破したい問題設定と、とてもよく似ている。

image image

おそらく本質的にはストーリーの依存関係のようなものが生じることは多々あるだろうとは思うが、依存をすべて待ち受けてから結合するのではなく、小さなストーリーによって完成した小さなモジュールはどんどんmasterにマージして、絶えず結合していくことができる。

この点においてmasterにあるものは全てリリースされるGitHub FlowのWebアプリと、まったく異なる製品出荷サイクルを持つ医療機器においてギャップがあると感じられるかもしれない。しかし実際にはトランクベース開発であっても、フィーチャーフラグを活用することによってデプロイとユーザーへのリリースを切り離し、独立したサイクルでテストに取り組むことが可能になる。

そして、忍者式テストはその効果を次のように語る。

image image

ここはまさに忍者式テストの真髄なのではないか。つまり、忍者式テストは新入社員を含めた開発チーム全体がストーリーを起点に製品と向きあい続けていくためのプラクティスである。


ここで自分の体験を思い返してみる。pixivでは2016年頃から静的解析に取り組みはじめている(Phan静的解析がもたらす大PHP型検査時代 - pixiv inside [archive])。この頃のtadsanはPHPのあまりの開発しにくさに半ば絶望していて、あわよくばScalaにでもリプレースできればいいと考えていた。型をつけるというのは当時の自分にとって、そのための足がかりだったといえる。

歴史ある大規模アプリケーションの難しさというのは (対象となる技術課題そのものの困難を除けば)仕様の欠如とストーリーの失伝、開発者の無意識による未定義挙動の積み重ねにほかならない

型システムがあれば、すくなくとも関数の振る舞いをデータ型の種類によって統制し続けることができる。


ここで忍者式テストを背景に自分たちに向き直ってみよう。tadsanは継続的にpixiv.gitをリファクタして型を付け続けているが、折に触れて関数のあるべき姿が見えなくなり考古学調査に赴かざるを得なくなることがある。

ユニットテストや型システム、エラーログによって観測できる事実は、プログラムの性質の一部分以外を捨象したものだと言える。

ある日突然外部要因によって機能追加・変更を要求されたコード、あるいは本番環境やユニットテストで突然failしはじめたコードに対して、すぐに自分が書いたコードと同じ当事者意識を持って向き合うことはできるだろうか。

image

一方で忍者式テストは「手触り」といったコード化しがたいアナログな感覚を含めて、製品に積み重なったストーリーの歴史とチーム全体で「テスト」の形をとって継続的に向き合い続けることで当事者意識を根付かせる営みだと言える。

Web開発 vs 忍者式テスト

では、Web開発の全ての現場で忍者式テストがフィットするのだろうか。……答えはYesとも言えるしNoとも言えそうだ。

既に長大な歴史の活断層があるようなプロジェクトで後追いでストーリーのカバレッジを上げるようなことは、おそらく徒労のように思う。また、ユニットテストがしにくい性質のプロジェクトで品質保証の手段として忍者式テストを導入しようということも、現実的には副次的な効果としてそのような性能を発揮できるかもしれないが、忍者式テストの主眼からは外れているかもしれない。

また、一つの大きなプロダクトの開発においても、ユーザー体験を求めるチームと、技術的な課題解決がミッションである場合では、きっと「ストーリー」は相似形にはならないだろう。私のように開発者体験を向上させることに主眼があれば、そこにフォーカスした忍者式テストに取り組むことができると思う。

キミだけの忍道を見つけだせ!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment