Upload
kyon-mm
View
19.795
Download
7
Embed Size (px)
DESCRIPTION
2014/02/12の楽天Tech Talkに登壇させてもらったときの発表スライドです。 2013年に発表したいくつかの内容をまとめました。 基本的に、ソフトウェアテストの絶望を聞きたい人向けです。
Citation preview
Automate Testing Anti-pattern
自動テストの誤解とアンチパターン
by kyon_mmin Rakuten Tech Talk 12/02/2014
Self Introduction
きょん(@kyon_mm)
テストアーキテクト
Groovy, C#, F#, Scala
SCMBootCamp, Nagoya.Testing, TDDBootCamp
Agenda
自動統合テスト
誤解と効果
TDD/BDDについて
歴史
TDDの自殺
失敗するTDD
Agenda
自動統合テスト
誤解と効果
TDD/BDDについて
歴史
TDDの自殺
失敗するTDD
Test Level
単体テスト/コンポーネントテスト 「それらではアプリケーションとして成立しないファイル群に対するテスト」
統合テスト「デプロイされている状態でのアプリケーションに対するテスト」
システムテスト「デプロイされていて、シナリオも含めたテスト」
Attention
テストは手動/自動に関わらずコスト意識が大切です。
自動化しても見合わないこともあるし、手動で続けるのが見合わないこともあります。
見合う見合わずではなくとも、どれくらいのコストであるかを見積もる、計測する事は大切な事が多いです。(開発規模が大きくなるほど。)
Test ROI
テストの自動化は何度も実行しなければもとが取れないとかいう話があります。
よく3回以上と言われています。
Test ROI
自動化は3回やらないと元がとれない?
目を覚ませ。建前はいらないのだよ。
Test ROI
テストの自動化は何度も実行しなければもとが取れないとかいう話がありますが、そういうのは建前です。嘘です。いい訳です。
「統合テスト自動化で得られる最大のメリットはテスト実装者が得る幅広いプログラミングスキルとアーキテクチャ知識である」
「手動では不可能なテストの実装、コストの大幅低減」を実現するのは多くはシステムテストレベルである事が(比較的)多い。
Test ROI
「統合テスト自動化で得られる最大のメリットはテスト実装者が得る幅広いプログラミングスキルとアーキテクチャ知識である」
統合テストレベルの自動化をしなくていいと言っているのは、上のメリットを「(優先順位を考慮して)必要ない」と言っているのと同義だと捉えていることを忘れてはいけない。
Test ROI
自動テストを誰かが勝手にやってくれるものとして保証する
自動テストを自分の手足のように使う(理解する)ものとして保証する
自動テストなしで保証する
どの立場でテストを行うかはあなた次第
Test ROI
例えば。。。
誰かが品質に対して警鐘を鳴らしてくれればよい。というのは、かなり手慣れた領域での話である。
初めての「ドメイン」「大規模化」「複雑化」「汎用化」などにおいては、知識の不足が露呈しやすく、効率よく知識を得る必要がある。
Integration Test
統合テストの自動化のROIで実行回数に目がいくのか?
統合テストの自動化で意味があるものは?
Integration Test
統合テストの自動化がうまくいっているとはどういうことか
保守性?
属個人性?
Integration Test
自動統合テストが「うまくいっている」と思い込んでしまうパターンがある。
「無駄なテストを大量に増やせる事」
「効果がありそうなんだけど無駄なテスト」をいかに減らせるかが鍵になってくる。
Integration Test
効果的な自動統合テストとはどうすればつくれるのか?
Reduction
統合テストを減らすには、統合テストより前の段階でどうやって減らすかにかかっている。
テストで減らす : 統合テストより下のテストと「網羅対象や度合い」をテスト設計する
設計で減らす:統合テストでの因子水準を減らせるようなプロダクト設計する
Integration Test
プロダクトコードをレビューできるスキルがないなら、効果的な自動統合テストは不可能に近い。
Test ROI
効果的な自動テストはなにかを考えないと、「自動化対象外と協調したテスト設計をおろそかにする」
自動化対象のテストのみに着目するので「ROI=予想実行回数」のような発想になる。
Agenda
自動統合テスト
誤解と効果
TDD/BDDについて
歴史
TDDの自殺
失敗するTDD
TDD/BDD
TDD=Test Driven Development
BDD=Behavior Driven Development
History of TDD/BDD
TDDというものはSmalltalk界隈の人達の習慣を洗練させ形式化したものでした。
それをしたのがKentBeckです。
彼を中心にMartin Fowler, Uncle Bob, Ron JeffriesなどがTDDとリファクタリングを洗練させていきます。
Kent Beck says...
自動テストが失敗した場合だけ、 新しいコードを書く。 重複を取り除く。2つの規則はプログラミングのタスクにおける順番を意味する。
レッド ‐ 動作しないテストを少しだけ作成する。 おそらく最初はコンパイルできない。
グリーン ‐ テストをすぐに動作させる。 そのためには、 どのようなコードでもよい。
リファクタリング ‐ テストを動作させるためだけに作成された重複をすべて取り除く。
Uncle Bob says...
3つの原則を守りながら実装をすすめる。
失敗するテストができるまでプロダクトを書いてはいけない
失敗するテストがある場合にはそれ以上テストを追加してはいけない
テストを成功させるプロダクトがある場合にはそれ以上プロダクトを追加してはいけない
t_wada says...
プログラマーを含めた開発の健康をたもつプラクティス
RED - GREEN - REFACTORの黄金の回転を回す
動くけど汚ないコード - 動いて美しいコード - 動かないコードの状態遷移
kyon_mm says
ソフトウェア開発者支援フレームワークである
RED - GREEN - REFACTOR のスパイラルモデルが根幹にある
「開発者の意図を確認すること」「開発者が心地よいコードを書き始める事」を支援する。
Descended from origin
TDD By Example[テスト駆動開発入門] By KentBeck
Refactoring[リファクタリング] By Martin Fowler
[アジャイル開発の奥義-オブジェクト指向開発の原則-] By Uncle Bob
Clean Code By Uncle Bob
JUnit By Kent Beck
NUnit By Ron Jeffries
XP
アジャイルの一形態であるeXtreme Programming(XP)では 様々なプラクティスが提案されました。 その中にも「受け入れテストの自動化」は存在します。 これによって常にプロダクトに対して要求に近い検査を行うことが可能になりました。
XPが直接ではないですが、この頃からATDDという概念が生まれはじめます。 このときのATDDはまさに「オンサイト顧客」などのいわゆる 「ユーザーのための受け入れテスト」でTDDするというものでした。
FIT
Framework for Integrated Test(FIT) TDDやXPが広まるなかでより言語に依存しない形でのテスト(特にIntegration Test)に 注目されるようになった。
ノンプログラマーにフレンドリーであり、実行でき、実装すべきモノがみえるテスト
Fit/FitNesseFITの有名な実装としてFit/FitNesseが存在する。
Ward CunninghamによるFit. Uncle BobによるFitNesse.
次のような要素からなる。
Wiki上でテストケースを表で記述
Wikiからテストを実行できる
各プログラミング言語とのアダプタ
各プログラミング言語でのテストケース実装
BDD
Kentは「常に(その時における)ユーザーの立場でテストを実装するんだ。」といいました。 現実には多くのTDDビギナーはそうはせず、 UnitTestに集中しすぎ、時には実装をテストしてしまうことに注力したのです。
BDDは様々な思惑があったとは言え、 現実的な理由としてはTDDの誤解される使い方を是正するための考え方として生まれました。
Scenario BDD
より自然言語らしさを目指した結果、 テストコードと自然言語を記述するファイルを分断するという選択をした流れがあり、 それらをScenarioBDDとよぶことがおおいです。 現在のCucumber系がそれらにあたります。
Spec BDD
テストコードと自然言語をできるだけ同一ファイル内におさめながら、 可読性の向上を目指すという選択をした流れがあります。 それらをSpecBDDとよぶことがおおいです。 現在のRSpec系がそれらにあたります。
STDD
アジャイルの一形態であるScrumは今や世界中で認識されている手法になりました。 Scrumは実現すべき事に「Readyの定義」「Doneの定義」を決めることが多いです。 実現すべき事はProduct BackLog Itemとよばれ、 ユーザーストーリーで書かれることが多いです。
このDoneの定義をユーザーストーリーを取り組むときに、 テストとして実装してしまうことで開発をするSTDDがうまれました。 StoryTestDrivenDevelopmentです。
Specification By Example
幾年かを経て、Specification By Exampleという概念がうまれます。 これは今迄のBDDやATDDをうまく包括するような概念として生まれました。 主張は「Specification By Exampleとして書かれたテストはLive Documentなんだ」 (「例示による仕様としてのテストは生きたドキュメントだ!」)ということです。
Agenda
自動統合テスト
誤解と効果
TDD/BDDについて
歴史
TDDの自殺
失敗するTDD
Domain
ドメインの分け方として2分別する方法がある
アプリケーションドメイン
ソリューションドメイン
Application Domain
ソフトウェアシステムの導入によって変化させたい領域のこと。
問題ドメインと呼ばれる事が多いが、必ずしも一致しない。
Application Domain
端的な例だと、要求レベルで表現できるユーザーが達成しようとしている内容
Solution Domain
ソフトウェアシステムの個々の技術や組み合わせ方。
解決ドメイン、解決領域と翻訳されることもある。
Solution Domain
個々の言語、ライブラリ、ミドルウェアなど。
実際のコードや設定やインフラなどによる実装技術。
Best Production Code
Application DomainとSolution Domainが同一表現になること。
「やりたいことを書いた」=「実装した」
Example
MDA系
一部では概念図からプロダクトコードを自動生成することに注力している
DSL系
アプリケーションドメインをそのままかけるような専用言語によってソリューションドメインとの身時を埋める
Example
BRMS
システムのロジックの一部をデシジョンテーブルで記述できるようにする
Problem
我々の世界はそこまで綺麗にコードをかける実力もツールもない
TDD Solution
まずテストコードに達成したい事を表現する
プロダクトコードを実装する
テストが通った状態で綺麗にする
Test Code of TDD
TDDはDog Foodingである
テストコードが最初のユーザー
テストコードに要求を書いている
テストコードにアプリケーションドメインがある
Production Code of TDD
まずはある範囲で保証できるコードを書く
保証できる中で綺麗にしていく
TDDの中でどうやってテストとプロダクトを綺麗にするかは語られていない。
TDD用のリファクタリングがない
Best Production Code
アプリケーションドメイン= ソリューションドメイン
TDD
テストコード = アプリケーションドメイン
プロダクトコード = ソリューションドメイン
Product Refactoring
実際にはなんらかの形でアプリケーションドメインをプロダクトコードに入れている
命名、依存関係整理、レイヤ分割
Test Refactoring
DRY...?
Domain
テストコードにアプリケーションドメインが残ってしまっている。
アプリケーションドメインが重複している。
Domain
重複しているだけならまだいい。
実際には違うものが表現されている。
Example
TestDouble
Integration Test
Domain
TestDoubleもしくはIntegrationTestのsetupを書く事で、既にある他の機能の劣化コピーもしくは完全なコピーを書く事になる。
Domain
ツールとTDDの都合でテストコードもしくはプロダクトコードにあるアプリケーションドメインを変化させてコピーしなければいけない
Domain
そのテストを動かすために最短でセットアップできるものを書くのは本当に正しいのかも怪しい。
何よりアプリケーションドメインが重複している。
TDD Suicide
プロダクトコードからアプリケーションドメインが漏れたり、埋め込まれないことがある
それを促進する力がTDDにはある
TDD Suicide
アプリケーションドメインがないプロダクトコードなんて何やっているかわからない死体と同然である。
TDDは開発の理想を壊す、守るべきプロダクトコードを死体にしてしまう事がある。だが、それに気づきにくい。
TDD Suicide
レゾンデートルを自ら破壊してしまうというTDDはまさに自殺しているに等しい。
「ドメインの重複、エセドメインの生産をしてプロダクトコードをダメにしてしまう」というTDDは自殺している。これをTDDの自殺という。
Agenda
自動統合テスト
誤解と効果
TDD/BDDについて
歴史
TDDの自殺
失敗するTDD
TDD
TDDをして品質があがると思う人が多くいる。一方で上がらないと思っている人がいる。
(効果のある品質特性が異なるという話ではないよ。
Good TDD
強制的に検査されたプロダクトしか手に入らなくなる事によって、つまらないバグが減る。
最低限のテスト、最低限のプロダクトのみによって進められるサイクルによって得られる本質に近づくための知識を取得できる。
Bad TDD
あるコミュニティにとってTDDは成功しやすい手法かもしれないが、失敗する場合もある。
例
AdaコンパイラはTDDを採用したが、よろしくないTDDを行ってしまって、今までにないバグを発生させた。
Why Fail
TDDが難しいから?
TDDでカバレッジ100%を目指したから?
自動テストの実行結果がオールグリーンのスクリーンショットをExcelにはったから?
上3つをクリアしても失敗する原因がある
Why Fail
TDDはコードを増やすことになっている。
低スキルなプログラマーが「プロダクト」だとしても「テスト」だとしても書くのは「ひどいコード」であることには変わりない。
でも、意味の通じないドキュメントを書いてしまうことよりはずっとマシ :-p
言い換えれば、TDDで効果があがるのは、属個人性の排除と、意味の通じないドキュメントによって生み出されるバグ予防、確認不足の予防
ご清聴ありがとうございました!