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
Effective Jekyll
wtnabe
0
32
5 min Jekyll/Liquid Plugin cooking
wtnabe
0
17
Ruby de Wasm
wtnabe
0
40
Cloud Native Buildpacksって結局どうなの?
wtnabe
0
32
Decoupled System with Turbo Frame
wtnabe
1
110
join-kanazawarb-or-7years-passed-since-it-was-borned
wtnabe
0
760
let-me-edit-with-editor
wtnabe
0
320
google-photos-and-storage-and-rclone
wtnabe
0
430
one case of how to begin vuejs
wtnabe
2
450
Other Decks in Programming
See All in Programming
In geheimer Mission: AI Agents entwickeln
joergneumann
0
110
flutter_kaigi_mini_4.pdf
nobu74658
0
150
Golangci-lint v2爆誕: 君たちはどうすべきか
logica0419
1
230
KawaiiLT 登壇資料 キャリアとモチベーション
hiiragi
0
160
By the way Google Cloud Next 2025に行ってみてどうだった
ymd65536
0
120
Lambda(Python)の リファクタリングが好きなんです
komakichi
4
250
スモールスタートで始めるためのLambda×モノリス(Lambdalith)
akihisaikeda
2
390
マイコンでもRustのtestがしたい/KernelVM Kansai 11
tnishinaga
0
810
API for docs
soutaro
4
1.7k
M5UnitUnified 最新動向 2025/05
gob
0
130
Jakarta EE Meets AI
ivargrimstad
0
830
ぽちぽち選択するだけでOSSを読めるVSCode拡張機能
ymbigo
12
5.6k
Featured
See All Featured
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Designing Experiences People Love
moore
142
24k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
700
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
21k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
32
5.6k
Done Done
chrislema
184
16k
Product Roadmaps are Hard
iamctodd
PRO
53
11k
Designing for Performance
lara
608
69k
Rails Girls Zürich Keynote
gr2m
94
13k
Gamification - CAS2011
davidbonilla
81
5.3k
Practical Orchestrator
shlominoach
187
11k
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