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
2k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JSTDD Intro for EVERY JavaScripters @kanazawa.js v1.7 (2012-03-31)
デザイナもエンジニアも参加する kanazawa.js のために JavaScript を題材にして TDD を紹介します。
wtnabe
March 31, 2012
More Decks by wtnabe
See All by wtnabe
新しいフロントプロセスとドキュメントフォーマットを考えてみた
wtnabe
0
27
Rubyでもモノリポしたい - 調査、おさわり編 -
wtnabe
0
65
Ruby de Railway Oriented Programming
wtnabe
0
110
Bindanのススメ
wtnabe
0
68
そのオブジェクト、何を保証してくれますか? - GuideRailのススメ -
wtnabe
0
78
Effective Jekyll
wtnabe
0
100
5 min Jekyll/Liquid Plugin cooking
wtnabe
0
69
Ruby de Wasm
wtnabe
0
95
Cloud Native Buildpacksって結局どうなの?
wtnabe
0
84
Other Decks in Programming
See All in Programming
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
240
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
570
片田舎のおっさん、 Swift Buildのダイアモンド問題解決の不具合修正PRを出すが、解決方法がキャッシュをしないようにすることであり、ビルド時間が伸びると言われてマージされないので高速化もする/swiftbuild
yimajo
0
250
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
140
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
170
承認済みなのに差戻しできてしまうバグ、型で潰せます
shinchit
0
100
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
3
1.6k
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
240
Cloudflare is Agents
chimame
0
180
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.6k
【QA Test Talk Vol.8】AI-DLC による Whole Team Approach の加速
pkshadeck
PRO
0
220
Go 1.27 における memory allocation の高速化
andpad
0
300
Featured
See All Featured
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Design in an AI World
tapps
1
290
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
480
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
How GitHub (no longer) Works
holman
316
150k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
500
Optimizing for Happiness
mojombo
378
71k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
280
Producing Creativity
orderedlist
PRO
348
40k
Agile that works and the tools we love
rasmusluckow
331
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