Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JSTDD Intro for EVERY JavaScripters @kanazawa.j...
Search
wtnabe
March 31, 2012
Programming
3
2k
JSTDD Intro for EVERY JavaScripters @kanazawa.js v1.7 (2012-03-31)
デザイナもエンジニアも参加する kanazawa.js のために JavaScript を題材にして TDD を紹介します。
wtnabe
March 31, 2012
Tweet
Share
More Decks by wtnabe
See All by wtnabe
Ruby de Railway Oriented Programming
wtnabe
0
23
Bindanのススメ
wtnabe
0
22
そのオブジェクト、何を保証してくれますか? - GuideRailのススメ -
wtnabe
0
34
Effective Jekyll
wtnabe
0
62
5 min Jekyll/Liquid Plugin cooking
wtnabe
0
30
Ruby de Wasm
wtnabe
0
57
Cloud Native Buildpacksって結局どうなの?
wtnabe
0
47
Decoupled System with Turbo Frame
wtnabe
1
130
join-kanazawarb-or-7years-passed-since-it-was-borned
wtnabe
0
790
Other Decks in Programming
See All in Programming
パッケージ設計の黒魔術/Kyoto.go#63
lufia
3
440
Updates on MLS on Ruby (and maybe more)
sylph01
1
180
アルテニア コンサル/ITエンジニア向け 採用ピッチ資料
altenir
0
110
Android 16 × Jetpack Composeで縦書きテキストエディタを作ろう / Vertical Text Editor with Compose on Android 16
cc4966
2
260
Android端末で実現するオンデバイスLLM 2025
masayukisuda
1
170
print("Hello, World")
eddie
2
530
Navigation 2 を 3 に移行する(予定)ためにやったこと
yokomii
0
330
請來的 AI Agent 同事們在寫程式時,怎麼用 pytest 去除各種幻想與盲點
keitheis
0
120
AI時代のUIはどこへ行く?
yusukebe
18
9k
Design Foundational Data Engineering Observability
sucitw
3
200
Performance for Conversion! 分散トレーシングでボトルネックを 特定せよ
inetand
0
2.4k
「待たせ上手」なスケルトンスクリーン、 そのUXの裏側
teamlab
PRO
0
560
Featured
See All Featured
Designing for humans not robots
tammielis
253
25k
Raft: Consensus for Rubyists
vanstee
140
7.1k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.7k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.6k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
The World Runs on Bad Software
bkeepers
PRO
70
11k
Docker and Python
trallard
46
3.6k
It's Worth the Effort
3n
187
28k
Designing Experiences People Love
moore
142
24k
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
4 Signs Your Business is Dying
shpigford
184
22k
Transcript
JSTDD Intro for EVERY JavaScripters 〜 4周⽬のTDDを始めよう 〜
kanazawa.js v1.7 @wtnabe ⾦沢歌劇座 2012-03-31
Self-Introduction
None
Webの開発とシステム管理全般 Ruby, JavaScript, PHP kanazawa.js Certified Ruby Programmer Gold
JavaScriptの専⾨家 TDDの専⾨家
つまり皆さんと同じです
ちょっと違うこと 以下は少なめ F5押して ⽬を凝らす
今⽇はそのためのお話 何を知り 何を準備し ⽇々どうしていくか
私とTDD 課題 2002年 XP, テストファーストを知る 2003年 リファクタリングしたい テストないじゃん 設計上⼿になりたい クソコードを紡ぐ不安
私とTDD テスト 2005年 Ruby, PHP でユニットテスト開始 2006年 JavaScriptでユニットテスト開始 WSH +
JScript + jsUnit
私とTDD インターフェイス 2007年 『アジャイルプラクティス』 「変更に強いコードとうまい設計を⽬ 指す覚え書き」 - あーありがち 2008年 『インターフェイス指向設計』
『RESTful Webサービス』
私とTDD ⾃動化 2009年 『Release It !』 Rake, Capistrano プロセス監視
私とTDD ⽂化 2010年 3⽉ TDDBC北陸 9⽉ 『レガシーコード改善ガイド』 12⽉ kanazawa.js v0.0.1
2011年 Rails 3 で TDD
私とTDD 2012年3⽉ kanazawa.js v1.7 ← イマココ
まとめると
設計は難しい http://www.flickr.com/photos/mrbill/3267227227/
⽬の前にはスパゲッティ http://www.flickr.com/photos/katiejean97/6966583763/
不安
http://www.flickr.com/photos/cauchipics/4444456369/ TDDを始めて
とってもハッピー ※ 不適切な画像は削除されました
以上、⾃⼰紹介おわり
本⽇のお品書き TDDってなに? テスティングフレームワークと関連知識 やってみよう JavaScript TDDの課題 TDDの始め⽅(スピリチュアル注意)
本⽇のターゲット とりあえずJavaScript書いて動かせる⼈ TDD始めたい⼈
覚えてほしいこと Red / Green / Refactoring Firebugだけではつらい ⾃動テストで安⼼を⼿に⼊れよう
What is TDDってなに?
だいぶ乱暴な説明
テスト駆動開発 Test-Driven Development テスト - テストコードの実⾏によって 駆動 - 頑張りやすくする 開発
- 開発⼿法
テストコード? プログラムをテストするプログラム
プログラムをテストするプログラム?
こんな感じ function isOdd( num ) { return num % 2;
} function testIsOdd() { console.log(true === isOdd( 3 )); console.log(false === isOdd( 2 )); } testIsOdd();
実⾏結果 $ node /path/to/test_code.js true true
あとでもうちょっと詳しく
詳しい⼈向けの諸注意 TDDのテストは開発者が⾃らのために⾏ うテストです TDDはあくまでDevelopmentであっ てTestではありません
どうしてプログラムで テストするの?
Firebugじゃダメなの?
Firebugじゃダメなの? 「確認」のくり返し 正確さ? 変更 → 全部やり直し ⾒ていないところは?
Firebugはダメじゃない Firebugだけでやるのは⼤変
コンピュータは 疲れを知らず 同じことを正確に 延々くり返せる
だからテストコード
では次に
得られるメリット 現場で困っていそうなこと
困っていませんか? console.log(), var_dump(), p, ... 間違ってそのままcommit/deploy
困っていませんか? デザイン vs Viewのコード システム vs DOMのロード
困っていませんか? ライブラリのバージョンアップ 機能追加 気づかないところが壊れてた
困っていませんか? 以前作ったコード 仕様書 vs 実際の動作 何が正しいのか?
TDDでこうした課題に⽴ち 向かいやすくなります
その理由は? 開発の進め⽅が違います
これまでの開発⼿法(1) コードを書き倒す 祈る (-⼈"- ; ウゴケ! 実⾏ orz
これまでの開発⼿法(2) 実装が済んでからまとめてテスト テストは基本的に⼿動
これまでの開発⼿法の問題 デバッグは祈りと⽬⼒ ⽬⼒頼み テスト開始が遅い 遅い → バグや仕様漏れの発⾒も遅い 遅い テストは疲れる 疲れる
後半しんどすぎる
TDDによる開発の流れ プログラムをテストする⼩さなコード 実⾏ → 失敗 成功するまでプログラムを直す 以上を⼩さく素早くくり返す
TDDで問題を解決 ⼿動テストのくり返しで疲れる → ⾃動化 ⾃動化 テストを始めるのが遅い → テストファースト テストファースト 「待ち時間」
→ インターフェイスを決めて並⾏作業 インターフェイスを決めて並⾏作業
もう⼀度コードを⾒てみる
プログラムをテストするプログラム function isOdd( num ) { return num % 2;
} function testIsOdd() { console.log(true === isOdd( 3 )); console.log(false === isOdd( 2 )); } testIsOdd();
こんなコード公開する? プロダクトコードとテストコード混在 JavaScriptの容量増加 テストに⽤意するデータ丸⾒え
無理でしょ
そこでフレームワークですよ!
Testing Frameworks and knowledge around there テスティングフレームワークと関連知識
フレームワークってなに? テストの記述 テストの実⾏
頻出ワード 実⾏環境 ブラウザなど組み込み / node.jsなど 種類 ユニット / インテグレーション スタイル
xUnit / BDD
今回は 実⾏環境 ブラウザ ブラウザなど組み込み / node.jsなど 種類 ユニット ユニット /
インテグレーション スタイル xUnit / BDD
今回は ブラウザ ユニットテスト
ユニットテスト 主にメソッドやクラス単位で⾏うテスト
メソッド function method() { ... }
クラス function klass() { ... }
おんなじだ!
JavaScriptでは functionに対するテストと 思っていいです
なぜユニットテスト? JavaScriptだけで話が完結する すぐにでも始められる ← 重要 cf. JavaScriptのテスト事情-ダイジェスト版- 2011年10⽉13⽇
どんなものがあるの? Jasmine ( 44% ) QUnit ( 41% ) via
http://dailyjs.com/files/DailyJSSurvey2011.pdf ※ 複数回答なので合計は100%以上
今回はQUnit
QUnitの理由 準備が少ない 記述が少ない つまりコードをスライドに載せやすい ※ 実務ではまた別な理由があると思います。
というわけで ブラウザで QUnitを使って ユニットテスト
Try it ! やってみよう
最速QUnit解説
HTMLを⽤意 qunit.jsとqunit.cssを読み込む
<!doctype html> <html> <head> <link href="./qunit.css" rel="stylesheet" <script src="./qunit.js" type="text/javasc
</head> <body> <h1 id="qunit-header">QUnit example</h1> <h2 id="qunit-banner"></h2> <div id="qunit-testrunner-toolbar"></div> <h2 id="qunit-userAgent"></h2> <ol id="qunit-tests"></ol> <div id="qunit-fixture">test markup, will </body> </html>
プロダクトコードとテストコードも⾜す ... <head> <link href="./qunit.css" rel="stylesheet" ty <script src="./qunit.js" type="text/javascri
<script src="./product.js" type="text/javasc <script src="./test_product.js" type="text/j </head>
ファイルの状態 . ├── index.html ├── product.js <- プロダクトコード ├── qunit.css
├── qunit.js └── test_product.js <- テストコード
テストの書き⽅ test('テストの名前', function() { ... });
今⽇使うAssertion ok( 確認したいコード ); equal( 確認したいコード, 期待する値 );
これだけ
組み合わせるとこう test('isOdd', function() { ok( isOdd(3) ); });
さて
サンプルを⽤意しました a) 奇数判定 b) ⽇付の整形
a) 奇数判定 確認したいこと TDDの教科書的な流れ
a) 奇数判定 設計 奇数を与えたら true が返ってくる 偶数を与えたら false が返ってくる
TDDの教科書的な流れ Fail it - まず失敗 - Red Fake it -
仮実装 - Green 三⾓測量 & Refactoring
None
by @t_wada 何かに似てる
Diagram by Karn G. Bulsuk
⼩さく進める 間違った⽅向に進んでないことを確認 するためにわざと間違える すぐにチェック(テスト)して フィードバックを次のサイクルに
Fail it 1 プロダクトコードのないテスト test('isOdd', function() { ok( isOdd(3) );
});
None
None
Fake it 1 内容のないプロダクトコード function isOdd( num ) { return
true; } test('isOdd', function() { ok( isOdd(3) ); });
None
Fail it 2 通らないテストパターン function isOdd( num ) { return
true; } test('isOdd', function() { ok( isOdd(3) ); ok( !isOdd(2) ); // new ! });
None
Fake it 2 Fail 回避 function isOdd( num ) {
if ( num == 3 ) { return true; } else if ( num == 2 ) { return false; } } test('isOdd', function() { ok( isOdd(3) ); ok( !isOdd(2) ); // new ! });
None
Refactoring 異なる⽅向からの2つ以上のテスト これらを元にゴールをより正確に計る これが三⾓測量 三⾓測量できたらリファクタリング
つまり今がチャンス! function isOdd( num ) { return num % 2;
// Refactoring } test('isOdd', function() { ok( isOdd(3) ); ok( !isOdd(2) ); });
もう⼀度おさらい Fail it - まず失敗 - Red Fake it -
仮実装 - Green 三⾓測量 & Refactoring
テストコードは設計を表す test('isOdd', function() { ok( isOdd(3) ); ok( !isOdd(2) );
});
サンプル a) 奇数判定 b) ⽇付の整形 ⽇付の整形
b) ⽇付の整形 確認したいこと 変化するものはひとまず固定してテスト 設計のbreak downが⼤事 設計 Date → 「YYYY/MM/DD」な⽂字列
Fail it test('formatDate', function() { equal('2012/02/14', formatDate(new Date('Tue Feb 14
2012 1 });
ちょっと確認したいことが function formatDate( date ) { return [date.getFullYear(), date.getMonth() +
1, date.getDate()].join('/'); }
Failed Expected: "2012/2/14" Result: "2012/02/14" Diff: "2012/2/14" "2012/02/14" // あ
Dateのメソッドは 桁数が合わない場合も
設計やり直し メソッドを分割する Date -> YYYY/MM/DD 数字の桁数を2桁に正規化する 2 -> 02 sprintfやstrftimeがあれば…。
さらに設計 数字の2桁への正規化? 2 -> 02 12 -> 12 110 ->
? 2012 -> ?
さらに設計 今回は⽇付の処理に特化 ⽉、⽇に3桁以上の数字はあり得ない 整数以外もあり得ない
Fail it test('padZero', function() { equal('02', padZero(2)); });
端折って本実装 function padZero( num ) { return '0' + num;
}
Fail it 2 test('padZero', function() { equal('02', padZero(2)); equal('12', padZero(12));
// new });
頑張る function padZero( num ) { var str = num.toString();
if ( str.length < 2 ) { return ('0' + str); } else { return str; } }
Refactoring function padZero( num ) { var str = '0'
+ num; return str.substr(str.length - 2, 2); }
完成テストコード test('formatDate', function() { equal('2012/02/14', formatDate(new Date('Tue Feb 14 2012
1 }); test('padZero', function() { equal('02', padZero(2)); equal('12', padZero(12)); });
完成プロダクトコード function formatDate( date ) { return [date.getFullYear(), padZero(date.getMonth() +
1), padZero(date.getDate())].join('/'); } function padZero( num ) { var str = '0' + num; return str.substr(str.length - 2, 2); }
⽇付の整形のまとめ 「今」はテストしにくいので固定 設計重要 / 場合分け重要 TDDそのものとは異なる経験も⼤事
Promblems of JavaScript TDD JavaScript TDDの課題
できないこと ⾒た⽬の雰囲気 効果の雰囲気 ※ レイアウトはすごく頑張れば可能
⼯夫すればできること 処理が複雑 頑張って分ける 頑張って分ける
⼯夫すればできること まとめて読み込むと動かない 名前空間を分ける どうしてもダメな部分はHTMLに直接 適切な分割には経験が必要です。
名前空間 var Namespace = { ... } HTML <script type="text/javascript">
... </script>
⼯夫すればできること DOM操作ばかりで結局⽬視 要素の有無や数を数えることは可能 ※ 不安がなければテスト不要
⼯夫すればできること 無名関数ばかり できるだけ名前を付けよう 即時実⾏無名関数だらけ できるだけ避ける。中⾝は⼩さく。
無名関数 func1( function() { ... }); 名前付き func1( function() {
func2(); }) function func2() { }
(function() { ... })(); 中⾝をちゃんと外に (function() { func1(); })(); function
func1() { }
諦めも肝⼼ 根本的に不可能なテストや現時点で無理 なテストはある 別な⽅法を考えよう
How to Start TDDの始め⽅
できることからやる TDDは⼩さなくり返し その導⼊が最初から完璧だなんて不⾃然 まずは現状の「困った」を⼀つでも解決
できる⼈を探そう 分かってそうな⼈、頑張ったら分かりそ うな⼈に⽚っ端から声を掛けよう
うまくいかないかも お前は最初から⼀⼈で⾃転⾞に乗れたのか?
はじめよう
例え失敗しても 今動いているコードは なくならない
今やり直せよ。未来を。 詠み⼈知らず
もう⼀つ
TDDがすべてではない 我々の⽬的は何か? より良いプロダクトで顧客、ユーザーに より⾼い価値を届けること
そのためにやれることを やるだけ
TDDは⼤事な⼿段の⼀つ
最後にもう⼀度
覚えてほしいこと Red / Green / Refactoring Firebugだけではつらい ⾃動テストで安⼼を⼿に⼊れよう
Any Questions ? Thanks to developers of testing frameworks, TDD
evangelists and prcatitioners and panelists And You