テストとともに 開 発 を 須 藤 功 平 株 式 会 社 クリアコード 2009/12/01
流 れ テストを 身 近 に テスティングフレームワーク 1/76
ここでのテスト 開 発 者 が 書 くテスト 自 動 化 されたテスト ( 主 に) 単 体 テスト 2/76
前 提 受 け 入 れテストとは 別 品 質 は 制 御 変 数 ではない : 低 くすると 早 くリリースできる 受 け 入 れテストが 長 くなる : 高 くするとリリースが 遅 くなる 受 け 入 れテストが 短 くなる 3/76
壁 4/76
壁 を 越 えるには きっかけ 方 法 どうして 越 えられないか 5/76
壁 を 越 える きっかけ
テスト? 世 間 では どういう 扱 い? 7/76
テストはストレス? ソフトウェア 開 発 プロジェク トにおいてテストは 極 めてス トレスに 満 ちています [ テンプレートから 学 ぶ 受 注 する 開 発 者 のための テスト 仕 様 書 (1/3):CodeZine より 引 用 ] 8/76
バグ 探 しは 不 愉 快? テストとは 作 った 成 果 物 に 誤 りがあるかどうかを 見 つけ る 作 業 だ という 本 質 的 に 不 愉 快 な 活 動 であること [ テンプレートから 学 ぶ 受 注 する 開 発 者 のための テスト 仕 様 書 (1/3):CodeZine より 引 用 ] 9/76
テストはきつい 作 業? プロジェクトの 終 わりにさし かかって 時 間 も 逼 迫 している のに 仕 様 変 更 を 受 けて 再 テス トなどという 体 力 的 にも 精 神 的 にもきつい 作 業 であるか らです [ テンプレートから 学 ぶ 受 注 する 開 発 者 のための テスト 仕 様 書 (1/3):CodeZine より 引 用 ] 10/76
とてもネガティブ バグ 探 しは 不 愉 快 テスト 実 行 はきつい ネガティブな ものなの? 11/76
完 璧? 自 分 が 完 璧 だという 前 提 に 立 っていないか テストとは 作 った 成 果 物 に 誤 りがあるかどうかを 見 つけ る 作 業 だ という 本 質 的 に 不 愉 快 な 活 動 であること [ テンプレートから 学 ぶ 受 注 する 開 発 者 のための テスト 仕 様 書 (1/3):CodeZine より 引 用 ] 12/76
現 実 と 向 き 合 う 完 璧 ではない 自 分 が よいソフトウェアを 書 くには どうしたらよいか 13/76
壁 を 越 えるきっかけ 現 実 と 向 き 合 う 14/76
壁 を 越 える 方 法
テス ト
自 動 化
さわると 壊 れるコード 頭 では 影 響 範 囲 を 網 羅 できない バグ 修 正 が 新 たなバグを 誘 発 変 更 するたび 手 動 で 再 テスト ストレス 人 為 的 ミス 18/76
実 装 完 了 手 動 テスト 開 始 実 装 時 たんたんと 実 装 手 動 テスト 時 バグ 出 し デバッグ 修 正 再 テスト 人 為 的 ミス 19/76
デバッグのしやすさ 実 装 してすぐ 覚 えているから 直 しやすい 後 でまとめて 思 い 出 すのが 大 変 20/76
すぐに 直 す すぐにバグを 見 つける 頻 繁 にテストする( 大 変 ) 常 にリリースできる 状 態 を 維 持 21/76
テストを 自 動 化 実 行 コストが 低 い 頻 繁 にテストできる 人 為 的 ミスを 防 げる テスト 開 発 コストがかかる 22/76
自 動 化 のコスト 継 続 するなら 割 に 合 う 23/76
壁 を 越 える 方 法 テストを 自 動 化 24/76
どうして 壁 を 越 えられ ないか
すばらしい 世 界 : テストを 書 けば : テストを 活 かせば 26/76
目 的 : テストを 書 くこと : よいソフトウェアを 書 くこと 27/76
TDDですべて 解 決? TDDは 身 につけられる 習 慣 : 使 えば 必 ずうまくいく : よいソフトウェアが 目 的 どうしてTDDしているかを 忘 れない 28/76
テストを 活 かす 29/76
どうして 壁 を 越 えられないか テストを 書 くことが 目 的 テストを 活 かしていない テストで 問 題 に 気 づかない 解 決 法 が 直 感 的 にわからない 30/76
壁 のまとめ 越 えるきっかけ 現 実 と 向 き 合 う 越 える 方 法 テストを 自 動 化 越 えられない 場 合 テストを 活 かしていない 31/76
テスティング フレームワーク テストを 身 近 に テスティングフレームワーク 32/76
何 を 支 援 するか テストを 活 かすこと 33/76
一 番 大 事 なこと 無 理 をしない 34/76
無 理 をしない : 新 しいコードから 始 める : 変 更 するコードから 始 める : テストを 書 くだけの 作 業 テストを 書 くことが 目 的 になる 35/76
続 けることが 大 事 完 璧 を 目 指 さない 続 けられるペースをキープ テストをストレスにしない 最 初 に 自 動 化 継 続 するなら 割 に 合 う 36/76
必 要 な 機 能 は 何 か テストの 作 りやすさ テストの 活 かしやすさ 37/76
作 りやすさの 目 的 無 理 せず 続 けるため 38/76
作 りやすさ? テストだけ 書 けば 動 く 面 倒 なことも 簡 単 に 書 ける 高 レベルな 便 利 機 能 とか いつも 通 り 書 ける 覚 えることが 少 ない キレイなテストが 書 ける 39/76
必 要 な 機 能
フィクスチャ setup/teardown 初 期 化 終 了 処 理 を 共 有 テストコンテキストを 共 有 テスト 内 容 のパラメータ 化 41/76
フィクスチャ: 実 状 実 装 されていることがほとんど 使 いこなせてないケースが 多 々 基 本 でもない? 42/76
書 くだけでテスト 定 義 スクリプトだと 当 たり 前 そうじゃないのもあるけど Cなどでは 登 録 が 必 要 そうじゃないのもあるけど 43/76
Pikzie (Python) import pikzie def test_add(): assert_equal(5, 2 + 3) % python test_add.py 44/76
gtest (C++) #include <gtest/gtest.h> TEST(CalcTest, Add) { } ASSERT_EQ(5, 2 + 3); 45/76
Cutter (C/C++) #include <cutter.h> void test_add(void) { cut_assert_equal_int(5, 2 + 3); } 46/76
データ 駆 動 テスト テストデータのパラメータ 化 動 的 にメソッド 定 義 動 的 なスクリプト 言 語 RSpec (Ruby) データ 登 録 NUnit (C#), gtest (C++), Cutter (C/C ++), UxU (JavaScript) 47/76
UxU (JavaScript) testadd.parameters = { plus: { x: 1, y: 2, expected: 3 }, minus: { x: 1, y: -2, expected: -1 } }; function testadd(aparameter) { assert.equals(aparameter.expected, aparameter.x + aparameter.y); } 48/76
ファイル 操 作 一 時 ディレクトリの 作 成 削 除 きれいな 環 境 を 作 るために 便 利 スクリプト 言 語 では 豊 富 言 語 標 準 でない 場 合 フレームワークで 提 供 便 利 ライブラリをオススメ 49/76
StringIO フレームワークのテストに 必 要 Ruby, Python - StringIO C++ - std::ostringstream Cutter (C, GLib) - GIOChannel テストしやすいコードへ IOオブジェクトをパラメータ 化 50/76
外 部 プロセス コマンドのテストで 便 利 出 力 を 文 字 列 でとれると 便 利 入 出 力 をやりとりできると 便 利 終 わったら 自 動 で 強 制 終 了 注 : 遅 い 51/76
イメージ spawn("echo") do process process.write("hello\n") assert_equal("hello\n", process.gets) end 52/76
マルチスレッド 同 じテストを 同 時 実 行 サブプロセスでやるのが 安 全 スレッドで 壊 れても 影 響 を 受 けない タイムアウトを 設 定 しやすい 結 果 はプロセス 間 通 信 で 渡 す CutterはXML 53/76
マルチプロセス 同 じテストを 多 重 実 行 サブプロセスでやるのが 安 全 SEGVっても 影 響 を 受 けない タイムアウトを 設 定 しやすい 結 果 はプロセス 間 通 信 で 渡 す CutterはXML 54/76
メモリ 管 理 GC スクリプト 言 語 は 標 準 搭 載 スコープは 決 まっている テスト 内 のみ 解 放 を 自 動 化 できる 55/76
Cutter (C) void test_strndup (void) { const char *actual; actual = cut_take_string(strndup("abcdef", 3)); cut_assert_equal_string("abc", actual); } 56/76
作 りやすさのまとめ 目 的 は 無 理 せず 続 けるため テストをイヤにならないように よく 使 う 機 能 は 標 準 で 面 倒 な 操 作 用 機 能 は 標 準 で 細 かくエラー 処 理 してあるとよい 57/76
活 かしやすさの 目 的 無 理 せず 続 けるため 58/76
活 かしやすさ? 問 題 が 何 か 見 つけやすい デバッグがしやすい よいコードに 導 く 使 い 勝 手 の 悪 さに 気 づく (ほんとは) アプリケーションを 書 いた 方 がよい 59/76
いつデバッグ? 開 発 はデバッグの 連 続 テストは 失 敗 するもの そんなことはない? あなたが 完 璧! 意 味 のないテスト? 60/76
テストは 味 方 ストレスじゃない 負 担 をかけるものじゃない イヤイヤやるものじゃない テストを 書 ける 幸 せ 61/76
必 要 な 機 能
特 定 のテストだけ 実 行 テスト 名 で 指 定 完 全 一 致 や 正 規 表 現 など テストケース 名 で 指 定 複 数 条 件 で 絞 り 込 めるとよい テストケース 名 テスト 名 63/76
テストを 間 引 く 多 くのテスト 長 い 実 行 時 間 興 味 のあるとこだけ 実 行 したい 指 定 するのは 面 倒 64/76
間 引 き 方 最 近 更 新 されたファイル 周 辺 決 まりが 必 要 (Rails) 前 に 失 敗 したやつを 実 行 成 功 するまで 他 に 手 をつけない! ランダムに 実 行 どこに 影 響 があるかわからない の 合 わせ 技 65/76
途 中 で 終 了 1つでも 失 敗 したら 止 めたい すぐに 確 認 したい C-cやキャンセルボタン 対 応 : RSpec, test-unit, Cutter 未 対 応 : minitest 66/76
何 が 悪 かった? 期 待 値 と 実 測 値 の 違 いは? 縦 に 並 べる diff なかったことを 示 すのは 難 しい 正 規 表 現 がマッチしなかった モックで 呼 び 出 されなかったのは? CSSセレクタがマッチしなかった 67/76
違 いは 縦 に 並 べる <111011> expected but was <110111> expected: <111011> actual: <110111> 68/76
diff 69/76
どうして 悪 くなった? バックトレース assert 失 敗 ブレークポイント C/C++: マクロをさける ステップ 実 行 しづらい 70/76
ソースへジャンプ Emacs: test/test-stack.c:10: assert_equal(...) Visual Studio: test\test-stack.c(10): assert_equal(...) 71/76
okはng 特 定 用 途 向 けassert 必 要 な 情 報 を 出 すため ok(file.exist?(path)) assert_path_exist(path) pathはなに? 72/76
まとめ テストは 活 用 するもの 継 続 するなら 割 にあう テストも 製 品 の 一 部 受 け 入 れテストとは 別 無 理 をしない 無 理 せずテストを 続 けられる フレームワークを 使 おう 73/76
明 日 からはじめる 人 へ テストを 書 くタイミング バグ 報 告 を 受 けたとき 新 機 能 を 追 加 するとき いきなり 無 理 をしない はじめから 完 璧 なテストは 書 けない まず 自 動 化 しておく 74/76
完 璧 は 無 理 : 学 んですべて 覚 えられる 感 覚 は 経 験 して 身 につける 身 につけている 人 と 開 発 する テストしづらい 分 野 もある GUI グラフィック ネットワーク いろいろな 視 点 が 必 要 仲 間 を 増 やす 継 続 する 75/76
テストのことなら クリアコードへ お 問 い 合 わせ 先 : http://www.clear-code.com/contact/ 76/76