自動テストの誤解とアンチパターン in 楽天 tech talk

Post on 10-May-2015

19.795 Views

Category:

Technology

7 Downloads

Preview:

Click to see full reader

DESCRIPTION

2014/02/12の楽天Tech Talkに登壇させてもらったときの発表スライドです。 2013年に発表したいくつかの内容をまとめました。 基本的に、ソフトウェアテストの絶望を聞きたい人向けです。

TRANSCRIPT

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で効果があがるのは、属個人性の排除と、意味の通じないドキュメントによって生み出されるバグ予防、確認不足の予防

ご清聴ありがとうございました!

top related