Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
C++でテスト駆動開発
自己紹介

 HN: 秋猫

 Twitter: @akineko

 Blog: http://d.hatena.ne.jp/Akineko/ 絶賛更新停滞中!

 職歴: ホテル→Webデザイン→ゲームプログラマ

 Aimingという会社でオンラインゲームの
  サーバープログラマやってます

 C++とかアジャイル開発が好きです
アジェンダ

 C++のテストライブラリの紹介

 テスト駆動開発とは

 実践!テスト駆動開発

 テスト駆動開発の恩恵

 テスト駆動開発に必要な知識
テストライブラリの
紹介
Boost.Test




@hotwatermorningさんにパス!
Google Test

 公式: http://code.google.com/p/googletest/

 ドキュメントの翻訳: http://opencv.jp/googletestdocs/

 名前の通りGoogle製のC++テストライブラリ

 豊富なアサーション
   http://lovejava.blog85.fc2.com/blog-entry-3.html

 豊富な機能

 比較的癖がなく使いやすい
Google Testのテストコード例
#include <gtest/gtest.h>


TEST(CalcTest, AddTest) {
    // 致命的なアサーション
    ASSERT_EQ(5, add(2, 3));


    // 致命的でないアサーション
    EXPECT_EQ(5, add(2, 3));
}
Google Testのフィクスチャ機能
class FooTest : public ::testing::Test {
public:
  FooTest() { /* テストスイート単位での初期化処理 */ }
  ~FooTest() { /* テストスイート単位での終了処理 */ }
protected:
  virtual void SetUp() { /* テスト毎の初期化処理 */ }
  virtual void TearDown() { /* テスト毎の終了処理 */ }
  Foo foo;
}

TEST_F(FooTest, hogeTest) { /* fooを使ったテスト */ }
Cutter

 http://cutter.sourceforge.net/index.html.ja

 CのテストライブラリにC++の機能を追加

 他ライブラリとは異なった独自の機能を持つ

 テストは共有ライブラリ化して実行する
   cutter テストディレクトリ
   上記のコマンドで指定ディレクトリ内の
     共有ライブラリよりテストコードを抽出して実行します

 ドキュメントが超親切!…過ぎてわかりづらいorz
Cutterのテストコード例
#include <cppcutter.h>


namespace calc_test
{
    void test_add()
    {
        cppcut_assert_equal(5, add(2, 3));
    }
}
Cutterのフィクスチャ機能

 cut_startup()
   テストスイート単位での初期化処理

 cut_shutdown()
   テストスイート単位での終了処理

 cut_setup()
   テストケース単位での初期化処理

 cut_teardown()
   テストケース単位での終了処理

 これらをnamespace内に含めればOK
その他

 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/
モックライブラリ

 GoogleMock
   http://code.google.com/p/googlemock/
   http://opencv.jp/googlemockdocs/index.html



 Mockitopp
   http://code.google.com/p/mockitopp/
テスト駆動開発とは
テスト駆動開発とは?

 通常の開発手法
  実装を行い、それに対するテストを書く
  時にはテストがないものも…




 テスト駆動開発
  先にテストコードを書き、
   そのテストが通る実装を行なっていく開発手法
  あくまで開発手法でありテスト手法ではない
テスト駆動開発のサイクル

1.   テストコードを書く

2.   実行して失敗することを確認する

3.   そのテストに成功する最低限の実装コードを書く

4.   実行して成功することを確認する

5.   テストが通る状態のままリファクタリングを行う

6.   1〜5をリズムよく繰り返す
実践!テスト駆動開発
ダメージ計算

 プレイヤーがモンスターから受けるダメージを計算せよ

 受けるダメージは 攻撃力 ー 防御力 とする

 プレイヤーが防御をしていた場合、
        受けるダメージは1/2となる

 20%の確率でクリティカルとなりダメージは2倍となる
仕様変更!!!

 20%の確率で攻撃がミスするようにして!

 ダメージは0.8〜1.2ぐらいの変動にして!

 クリティカルの時は防御していても無視して!

 ダメージの上限は9999ね!

 ダメージはーになっても回復じゃなくて0にしてね!

 やっぱり避ける確率はすばやさの差で!
テスト駆動開発の恩恵
テスト可能な設計・実装になる

 テストしたいけど複雑に絡み合ってできないを避けれる
  他クラスの状態に依存しまくったクラスとか…
  膨大な引数の関数とか…
  条件分岐しまくりな関数とか…

 特定の箇所のパフォーマンス測定も容易
  テスト出来る=単独実行可能
  計測できるので必要な箇所にのみ最適化ができる
  なんとなくここが遅いはずは不要な最適化が…
直ぐに実行可能なテストがある

 変更によるバグの混入を防げる
  変更の多いゲームこそテストによって守りましょう
  仕様変更といっても一から作り直しはしませんよね?



 めんどくさいからで変更の影響の確認をしないを防げる
  確認しないことが問題ではなくめんどくさいことが問題
  簡単にできれば大事な事なのでみんなしますよね
使いやすいインターフェイス

 テストを書く = 使い方を考える

 先に使い方を考えるので
  使いにくいインターフェイスに気づける

 凝集度の高い関数

 使い方を考えることは設計をする事にもつながる

 設計について考える機会が増える
テスト駆動開発に
     必要な知識
テスト駆動開発に必要な知識

 テストに関する知識
  どういうテストを書けばいいのか

 設計に関する知識
  大きい問題を小さい問題の集合へ分割する

 リファクタリングに関する知識
  コードを良い設計へ改善する
テストのレベル

 単体テスト
   1つのクラスや1つの関数など
    プログラムの最も小さい部品に対するテスト
   単体の定義は言語により様々
   Cだと関数1つ、C++だとクラス1つなど
   テスト駆動開発で書くテストのレベルは主にこれ

 統合テスト
   単体を組み合わせた1つのサブシステムに対するテスト

 Etc…
テストの種別

 ブラックボックステスト
  要件や仕様に基づいてどのように振る舞うべきかのテスト
  内部の実装や構造の知識を必要としない




 ホワイトボックステスト
  内部の実装や構造に基づいたテスト
  if文やcase文などの全ての経路を通っているかなど
  プログラミングの知識もある程度必要なもの
ピンポイントテスト
 仕様書を見て嫌な予感がするところをテストする

 コードを書いていて嫌な予感がするところをテストする

 間、対称、類推、外側を考える
   具体的な値を並べる
    その値の間に値はないか、対称となる値はないか、
    類似した値はないか、外側になる値はないか

 意地悪条件を考える
   めちゃくちゃでかい値、0、nullとか…

 マインドマップを使って考えると効果的
同値クラステスト

 無数にあるテストケースの数を減らす技法

 意味のある範囲で分割しその中の代表値をテストする

 この分割された範囲のことを同値クラスと呼ぶ

 ほとんどの人が無意識に実践しています
同値クラステスト

 仕様: HPの表示の色を%によって変えよ
     通常は白色
  30%以下は黄色
   5%以下は赤色

 この場合の値としては
   0~  5%
    6~ 30%
   31~100%
  という範囲に分割でき、この各範囲が同値クラスです
境界値テスト

 同値クラステストと併用される技法

 境界となる値はバグが発生しやすい

 この境界に着目してテストする値を選ぶ

 同値クラスの例だと
  0〜5、6〜30、31〜100なので
  -1、0、5、6、30、31、100、101
  各同値クラスの境界となる値と
  その直前・直後の値をテストする
その他いろいろ

 ドメイン分析テスト

 デシジョンテーブル

 CFD法

 HAYST法

 状態遷移テスト

 制御フローテスト

 データフローテスト
テストに対する懸念点
分割され過ぎちゃって
パフォーマンスが悪いんじゃないの?
パフォーマンス問題

 前述の通り根拠なき予想による無駄な最適化が防げます

 分割が原因でも最適化は関数を展開するだけ

 パフォーマンスの問題が起きるのは全体ではなく
 特定の箇所が問題となる事が多い

 最適化しか考えてないごちゃごちゃしたコードは
 変更コストの増大や変更によるバグを発生させます
テストできない場所ってあるでしょ?
  できない場所あるんだから
  やっても意味ないじゃん!
テスト問題

 テストしにくい場所、できない場所は確かにあります

 それでもそこ以外のテストができていれば
 問題発生時の特定は比較的容易になります

 プリントデバッグ・デバッガでどこが原因か
 わからないものを闇雲に探したくないですよね?
最後に
まずは…

 完璧なものなんて気にせずやってみましょう!

 〜の知識がついてからは来ません!

 書くテストも自分が必要と思う分だけでOK

 テストが不足していた失敗体験で自然と増えます

 やればやるだけ身につきます!
参考書籍

 テスト駆動開発入門
  http://amzn.to/wsqgW3

 はじめて学ぶソフトウェアのテスト技法
  http://amzn.to/zXZz8D

 ソフトウェアテスト技法ドリル
  http://amzn.to/zVkXLI

 マインドマップから始めるソフトウェアテスト
  http://amzn.to/w3BSN7
参考文献

 TDD Advent Calendar jp: 2011
   http://atnd.org/events/22027

 和田さんの資料
   http://www.slideshare.net/t_wada

 Twitter・Blog・Google検索いろいろ…
ご清聴ありがとうございました!

More Related Content

C++でテスト駆動開発