C++でテスト駆動開発

13,685 views

Published on

Boost.勉強会 #8 大阪での発表資料です。

Published in: Technology
0 Comments
35 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
13,685
On SlideShare
0
From Embeds
0
Number of Embeds
113
Actions
Shares
0
Downloads
78
Comments
0
Likes
35
Embeds 0
No embeds

No notes for slide

C++でテスト駆動開発

  1. 1. C++でテスト駆動開発
  2. 2. 自己紹介 HN: 秋猫 Twitter: @akineko Blog: http://d.hatena.ne.jp/Akineko/ 絶賛更新停滞中! 職歴: ホテル→Webデザイン→ゲームプログラマ Aimingという会社でオンラインゲームの サーバープログラマやってます C++とかアジャイル開発が好きです
  3. 3. アジェンダ C++のテストライブラリの紹介 テスト駆動開発とは 実践!テスト駆動開発 テスト駆動開発の恩恵 テスト駆動開発に必要な知識
  4. 4. テストライブラリの紹介
  5. 5. Boost.Test@hotwatermorningさんにパス!
  6. 6. Google Test 公式: http://code.google.com/p/googletest/ ドキュメントの翻訳: http://opencv.jp/googletestdocs/ 名前の通りGoogle製のC++テストライブラリ 豊富なアサーション  http://lovejava.blog85.fc2.com/blog-entry-3.html 豊富な機能 比較的癖がなく使いやすい
  7. 7. Google Testのテストコード例#include <gtest/gtest.h>TEST(CalcTest, AddTest) { // 致命的なアサーション ASSERT_EQ(5, add(2, 3)); // 致命的でないアサーション EXPECT_EQ(5, add(2, 3));}
  8. 8. Google Testのフィクスチャ機能class FooTest : public ::testing::Test {public: FooTest() { /* テストスイート単位での初期化処理 */ } ~FooTest() { /* テストスイート単位での終了処理 */ }protected: virtual void SetUp() { /* テスト毎の初期化処理 */ } virtual void TearDown() { /* テスト毎の終了処理 */ } Foo foo;}TEST_F(FooTest, hogeTest) { /* fooを使ったテスト */ }
  9. 9. Cutter http://cutter.sourceforge.net/index.html.ja CのテストライブラリにC++の機能を追加 他ライブラリとは異なった独自の機能を持つ テストは共有ライブラリ化して実行する  cutter テストディレクトリ  上記のコマンドで指定ディレクトリ内の 共有ライブラリよりテストコードを抽出して実行します ドキュメントが超親切!…過ぎてわかりづらいorz
  10. 10. Cutterのテストコード例#include <cppcutter.h>namespace calc_test{ void test_add() { cppcut_assert_equal(5, add(2, 3)); }}
  11. 11. Cutterのフィクスチャ機能 cut_startup()  テストスイート単位での初期化処理 cut_shutdown()  テストスイート単位での終了処理 cut_setup()  テストケース単位での初期化処理 cut_teardown()  テストケース単位での終了処理 これらをnamespace内に含めればOK
  12. 12. その他 CppUnit  http://sourceforge.net/apps/mediawiki/cppunit/index.php CxxTest  http://cxxtest.com/ QTestLib  http://developer.qt.nokia.com/doc/qt-4.8/qtestlib-manual.html UnitTest++  http://unittest-cpp.sourceforge.net/
  13. 13. モックライブラリ GoogleMock  http://code.google.com/p/googlemock/  http://opencv.jp/googlemockdocs/index.html Mockitopp  http://code.google.com/p/mockitopp/
  14. 14. テスト駆動開発とは
  15. 15. テスト駆動開発とは? 通常の開発手法  実装を行い、それに対するテストを書く  時にはテストがないものも… テスト駆動開発  先にテストコードを書き、 そのテストが通る実装を行なっていく開発手法  あくまで開発手法でありテスト手法ではない
  16. 16. テスト駆動開発のサイクル1. テストコードを書く2. 実行して失敗することを確認する3. そのテストに成功する最低限の実装コードを書く4. 実行して成功することを確認する5. テストが通る状態のままリファクタリングを行う6. 1〜5をリズムよく繰り返す
  17. 17. 実践!テスト駆動開発
  18. 18. ダメージ計算 プレイヤーがモンスターから受けるダメージを計算せよ 受けるダメージは 攻撃力 ー 防御力 とする プレイヤーが防御をしていた場合、 受けるダメージは1/2となる 20%の確率でクリティカルとなりダメージは2倍となる
  19. 19. 仕様変更!!! 20%の確率で攻撃がミスするようにして! ダメージは0.8〜1.2ぐらいの変動にして! クリティカルの時は防御していても無視して! ダメージの上限は9999ね! ダメージはーになっても回復じゃなくて0にしてね! やっぱり避ける確率はすばやさの差で!
  20. 20. テスト駆動開発の恩恵
  21. 21. テスト可能な設計・実装になる テストしたいけど複雑に絡み合ってできないを避けれる  他クラスの状態に依存しまくったクラスとか…  膨大な引数の関数とか…  条件分岐しまくりな関数とか… 特定の箇所のパフォーマンス測定も容易  テスト出来る=単独実行可能  計測できるので必要な箇所にのみ最適化ができる  なんとなくここが遅いはずは不要な最適化が…
  22. 22. 直ぐに実行可能なテストがある 変更によるバグの混入を防げる  変更の多いゲームこそテストによって守りましょう  仕様変更といっても一から作り直しはしませんよね? めんどくさいからで変更の影響の確認をしないを防げる  確認しないことが問題ではなくめんどくさいことが問題  簡単にできれば大事な事なのでみんなしますよね
  23. 23. 使いやすいインターフェイス テストを書く = 使い方を考える 先に使い方を考えるので 使いにくいインターフェイスに気づける 凝集度の高い関数 使い方を考えることは設計をする事にもつながる 設計について考える機会が増える
  24. 24. テスト駆動開発に 必要な知識
  25. 25. テスト駆動開発に必要な知識 テストに関する知識  どういうテストを書けばいいのか 設計に関する知識  大きい問題を小さい問題の集合へ分割する リファクタリングに関する知識  コードを良い設計へ改善する
  26. 26. テストのレベル 単体テスト  1つのクラスや1つの関数など プログラムの最も小さい部品に対するテスト  単体の定義は言語により様々  Cだと関数1つ、C++だとクラス1つなど  テスト駆動開発で書くテストのレベルは主にこれ 統合テスト  単体を組み合わせた1つのサブシステムに対するテスト Etc…
  27. 27. テストの種別 ブラックボックステスト  要件や仕様に基づいてどのように振る舞うべきかのテスト  内部の実装や構造の知識を必要としない ホワイトボックステスト  内部の実装や構造に基づいたテスト  if文やcase文などの全ての経路を通っているかなど プログラミングの知識もある程度必要なもの
  28. 28. ピンポイントテスト 仕様書を見て嫌な予感がするところをテストする コードを書いていて嫌な予感がするところをテストする 間、対称、類推、外側を考える  具体的な値を並べる  その値の間に値はないか、対称となる値はないか、 類似した値はないか、外側になる値はないか 意地悪条件を考える  めちゃくちゃでかい値、0、nullとか… マインドマップを使って考えると効果的
  29. 29. 同値クラステスト 無数にあるテストケースの数を減らす技法 意味のある範囲で分割しその中の代表値をテストする この分割された範囲のことを同値クラスと呼ぶ ほとんどの人が無意識に実践しています
  30. 30. 同値クラステスト 仕様: HPの表示の色を%によって変えよ  通常は白色  30%以下は黄色  5%以下は赤色 この場合の値としては  0~ 5% 6~ 30% 31~100%  という範囲に分割でき、この各範囲が同値クラスです
  31. 31. 境界値テスト 同値クラステストと併用される技法 境界となる値はバグが発生しやすい この境界に着目してテストする値を選ぶ 同値クラスの例だと  0〜5、6〜30、31〜100なので  -1、0、5、6、30、31、100、101  各同値クラスの境界となる値と その直前・直後の値をテストする
  32. 32. その他いろいろ ドメイン分析テスト デシジョンテーブル CFD法 HAYST法 状態遷移テスト 制御フローテスト データフローテスト
  33. 33. テストに対する懸念点
  34. 34. 分割され過ぎちゃってパフォーマンスが悪いんじゃないの?
  35. 35. パフォーマンス問題 前述の通り根拠なき予想による無駄な最適化が防げます 分割が原因でも最適化は関数を展開するだけ パフォーマンスの問題が起きるのは全体ではなく 特定の箇所が問題となる事が多い 最適化しか考えてないごちゃごちゃしたコードは 変更コストの増大や変更によるバグを発生させます
  36. 36. テストできない場所ってあるでしょ? できない場所あるんだから やっても意味ないじゃん!
  37. 37. テスト問題 テストしにくい場所、できない場所は確かにあります それでもそこ以外のテストができていれば 問題発生時の特定は比較的容易になります プリントデバッグ・デバッガでどこが原因か わからないものを闇雲に探したくないですよね?
  38. 38. 最後に
  39. 39. まずは… 完璧なものなんて気にせずやってみましょう! 〜の知識がついてからは来ません! 書くテストも自分が必要と思う分だけでOK テストが不足していた失敗体験で自然と増えます やればやるだけ身につきます!
  40. 40. 参考書籍 テスト駆動開発入門  http://amzn.to/wsqgW3 はじめて学ぶソフトウェアのテスト技法  http://amzn.to/zXZz8D ソフトウェアテスト技法ドリル  http://amzn.to/zVkXLI マインドマップから始めるソフトウェアテスト  http://amzn.to/w3BSN7
  41. 41. 参考文献 TDD Advent Calendar jp: 2011  http://atnd.org/events/22027 和田さんの資料  http://www.slideshare.net/t_wada Twitter・Blog・Google検索いろいろ…
  42. 42. ご清聴ありがとうございました!

×