狠狠撸

狠狠撸Share a Scribd company logo
长谷川
?   テスト駆动开発の説明
?   テストから先に作る開発技法
    ? テスト技法ではないので本資料ではxUnitの説明はしな
      い
?   テスティングフレームワークによるテストの自動
    化
    ? JUnit、CUnit等
?   リファクタリングによるシンプルな設計
    ? 重複のない、再利用可能な、テストコードがある
?   設計→コーディング→テスト

    設計



         コーディング




                  テスト
?   コーディングの前にテスト

    設計



         テスト




               コーディング
?   コーディングの後にもテスト

    設計



         テスト




               コーディング




                        テスト
?   その繰り返し
             設計




     テスト              テスト




             コーディング
?          バグ対策に掛かる費用は、後工程になるほど指数関数的に増大する。
                100
                 90
バグ1件あたりの修正コスト




                 80
                 70
                 60
                 50
                 40
                 30
                 20
                 10
                  0

                      要求定義   設計   コーディング   テスト   運用
                                  工程
TDD
?   コスト
    ? 工程の早い段階でバグ発見
?   生産性
    ? バグの少ない高品質なプログラムを高価なツールの導入
      なしに作成できる
    ? プログラマの生産性のギャップを埋めることができる
?   保守性
    ? すべてのコードにテストコードがあるので変更、リファ
      クタリング時に妥当性の確認が容易
?   必要なもの
    ? JDK
    ? Eclipse
    ? JUnit
?   設計:設計をする。
?   テスト(赤):テストが失敗するテストコードを書く
?   コーディング:テストが成功するコードを書く。リファクタリングする。
?   テスト(緑):テストを成功させる


                   設計




     テスト                         テスト




                  コーディング
?   Goodsクラスを作成する。                Goods

?   Goodsクラス         -price:int
    ? 商品の価格を保持する
    ? 税込価格を取得する      +getPrice:int
                     +getTaxIncludedPrice


                            クラス設計の例
import static org.junit.Assert.*;
import org.junit.Test;                    まだなし
public class GoodsTest {


@Test
public void testGetGoodsPrice() {
    Goods ice = new Goods(100);
    assertEquals (100, ice.getPrice());
}
}




        Goodsクラスがまだ定義されていないのでテストを実行すると失敗(赤)
import static org.junit.Assert.*;            public class Goods {
import org.junit.Test;
public class GoodsTest {                                 public Goods(int i) {
             @Test                                       }
    public void testGetGoodsPrice() {
        Goods ice = new Goods(100);                      public int getPrice() {
        assertEquals(100, ice.getPrice());                            return 100;
    }                                                    }
}
                                             }




        Eclipseのクイック?フィックスでGoodsクラスを自動生成、少し修正
import static org.junit.Assert.*;            public class Goods {
import org.junit.Test;                                   private int unitPrice = 0;
public class GoodsTest {                                 public Goods(int unitPrice) {
             @Test                                                    this.unitPrice = unitPrice;
    public void testGetGoodsPrice() {                    }
        Goods ice = new Goods(100);                      public int getPrice() {
        assertEquals(100, ice.getPrice());                            return this.unitPrice;
    }                                                    }
}                                            }




        変数名を変更、クラス変数を作成→テストを実行し、問題の無いことを確認
import static org.junit.Assert.*;                      public class Goods {
import org.junit.Test;                                             private int unitPrice = 0;
public class GoodsTest {                                           public Goods(int unitPrice) {
              @Test                                                             this.unitPrice = unitPrice;
              public void testGetGoodsPrice() {                    }
                           Goods ice = new                         public int getPrice() {
Goods(100);                                                                     return this.unitPrice;
                                                                   }
              assertEquals(100, ice.getPrice());
                                                       }
              }
              @Test
              public void testGetTaxIncludedPrice(){
                           Goods ice = new
Goods(100);

              assertEquals(105, ice.getTaxIndludedPr
ice());
              }

          getTaxIncludedPriceメソッドが未定義で失敗
}
import static org.junit.Assert.*;                      public class Goods {
import org.junit.Test;                                             private int unitPrice = 0;
public class GoodsTest {                                           public Goods(int unitPrice) {
              @Test                                                             this.unitPrice = unitPrice;
              public void testGetGoodsPrice() {                    }
                           Goods ice = new                         public int getPrice() {
Goods(100);                                                                     return this.unitPrice;
                                                                   }
              assertEquals(100, ice.getPrice());
                                                                   public int getTaxIndludedPrice() {
              }
                                                                                return 105;
              @Test
                                                                   }
              public void testGetTaxIncludedPrice(){
                                                       }
                           Goods ice = new
Goods(100);

              assertEquals(105, ice.getTaxIndludedPr
ice());
              }

          必要最低限の変更でテストをパスする
}
import static org.junit.Assert.*;                      public class Goods {
import org.junit.Test;                                              private int unitPrice = 0;
public class GoodsTest {                                            public Goods(int unitPrice) {
             @Test                                                               this.unitPrice = unitPrice;
             public void testGetGoodsPrice() {                      }
                          Goods ice = new                           public int getPrice() {
Goods(100);                                                                      return this.unitPrice;
                                                                    }
              assertEquals(100, ice.getPrice());
                                                                    public int getTaxIndludedPrice() {
              }
                                                                                 return 105;
              @Test
                                                                    }
              public void testGetTaxIncludedPrice(){
                                                       }
                           Goods ice = new
Goods(100);
                          Goods juice = new
Goods(500);

              assertEquals(105, ice.getTaxIndludedPr
ice());

          assertEquals(525, juice.getTaxIndluded
       500円のジュースをテストケースに追加。105を返すので失敗。
Price());
          }
}
import static org.junit.Assert.*;                      public class Goods {
import org.junit.Test;                                               private int unitPrice = 0;
public class GoodsTest {                                             public Goods(int unitPrice) {
             @Test                                                                 this.unitPrice = unitPrice;
             public void testGetGoodsPrice() {                       }
                          Goods ice = new                            public int getPrice() {
Goods(100);                                                                        return this.unitPrice;
                                                                     }
              assertEquals(100, ice.getPrice());
                                                                     public int getTaxIndludedPrice() {
              }
                                                                                   return
              @Test                                    (int)(this.unitPrice*1.05);
              public void testGetTaxIncludedPrice(){                 }}
                           Goods ice = new
Goods(100);
                          Goods juice = new
Goods(500);

              assertEquals(105, ice.getTaxIndludedPr
ice());

          assertEquals(525, juice.getTaxIndluded
       成功。
Price());
          }
}
? テストコードのリファクタリング
? 設計の見直し(デザインパターンの適用など)
? 消費税変更への対応

? 準正常、異常時の動作の考慮とテストケースの作
  成
などなど

More Related Content

TDD

  • 2. ? テスト駆动开発の説明
  • 3. ? テストから先に作る開発技法 ? テスト技法ではないので本資料ではxUnitの説明はしな い ? テスティングフレームワークによるテストの自動 化 ? JUnit、CUnit等 ? リファクタリングによるシンプルな設計 ? 重複のない、再利用可能な、テストコードがある
  • 4. ? 設計→コーディング→テスト 設計 コーディング テスト
  • 5. ? コーディングの前にテスト 設計 テスト コーディング
  • 6. ? コーディングの後にもテスト 設計 テスト コーディング テスト
  • 7. ? その繰り返し 設計 テスト テスト コーディング
  • 8. ? バグ対策に掛かる費用は、後工程になるほど指数関数的に増大する。 100 90 バグ1件あたりの修正コスト 80 70 60 50 40 30 20 10 0 要求定義 設計 コーディング テスト 運用 工程
  • 10. ? コスト ? 工程の早い段階でバグ発見 ? 生産性 ? バグの少ない高品質なプログラムを高価なツールの導入 なしに作成できる ? プログラマの生産性のギャップを埋めることができる ? 保守性 ? すべてのコードにテストコードがあるので変更、リファ クタリング時に妥当性の確認が容易
  • 11. ? 必要なもの ? JDK ? Eclipse ? JUnit
  • 12. ? 設計:設計をする。 ? テスト(赤):テストが失敗するテストコードを書く ? コーディング:テストが成功するコードを書く。リファクタリングする。 ? テスト(緑):テストを成功させる 設計 テスト テスト コーディング
  • 13. ? Goodsクラスを作成する。 Goods ? Goodsクラス -price:int ? 商品の価格を保持する ? 税込価格を取得する +getPrice:int +getTaxIncludedPrice クラス設計の例
  • 14. import static org.junit.Assert.*; import org.junit.Test; まだなし public class GoodsTest { @Test public void testGetGoodsPrice() { Goods ice = new Goods(100); assertEquals (100, ice.getPrice()); } } Goodsクラスがまだ定義されていないのでテストを実行すると失敗(赤)
  • 15. import static org.junit.Assert.*; public class Goods { import org.junit.Test; public class GoodsTest { public Goods(int i) { @Test } public void testGetGoodsPrice() { Goods ice = new Goods(100); public int getPrice() { assertEquals(100, ice.getPrice()); return 100; } } } } Eclipseのクイック?フィックスでGoodsクラスを自動生成、少し修正
  • 16. import static org.junit.Assert.*; public class Goods { import org.junit.Test; private int unitPrice = 0; public class GoodsTest { public Goods(int unitPrice) { @Test this.unitPrice = unitPrice; public void testGetGoodsPrice() { } Goods ice = new Goods(100); public int getPrice() { assertEquals(100, ice.getPrice()); return this.unitPrice; } } } } 変数名を変更、クラス変数を作成→テストを実行し、問題の無いことを確認
  • 17. import static org.junit.Assert.*; public class Goods { import org.junit.Test; private int unitPrice = 0; public class GoodsTest { public Goods(int unitPrice) { @Test this.unitPrice = unitPrice; public void testGetGoodsPrice() { } Goods ice = new public int getPrice() { Goods(100); return this.unitPrice; } assertEquals(100, ice.getPrice()); } } @Test public void testGetTaxIncludedPrice(){ Goods ice = new Goods(100); assertEquals(105, ice.getTaxIndludedPr ice()); } getTaxIncludedPriceメソッドが未定義で失敗 }
  • 18. import static org.junit.Assert.*; public class Goods { import org.junit.Test; private int unitPrice = 0; public class GoodsTest { public Goods(int unitPrice) { @Test this.unitPrice = unitPrice; public void testGetGoodsPrice() { } Goods ice = new public int getPrice() { Goods(100); return this.unitPrice; } assertEquals(100, ice.getPrice()); public int getTaxIndludedPrice() { } return 105; @Test } public void testGetTaxIncludedPrice(){ } Goods ice = new Goods(100); assertEquals(105, ice.getTaxIndludedPr ice()); } 必要最低限の変更でテストをパスする }
  • 19. import static org.junit.Assert.*; public class Goods { import org.junit.Test; private int unitPrice = 0; public class GoodsTest { public Goods(int unitPrice) { @Test this.unitPrice = unitPrice; public void testGetGoodsPrice() { } Goods ice = new public int getPrice() { Goods(100); return this.unitPrice; } assertEquals(100, ice.getPrice()); public int getTaxIndludedPrice() { } return 105; @Test } public void testGetTaxIncludedPrice(){ } Goods ice = new Goods(100); Goods juice = new Goods(500); assertEquals(105, ice.getTaxIndludedPr ice()); assertEquals(525, juice.getTaxIndluded 500円のジュースをテストケースに追加。105を返すので失敗。 Price()); } }
  • 20. import static org.junit.Assert.*; public class Goods { import org.junit.Test; private int unitPrice = 0; public class GoodsTest { public Goods(int unitPrice) { @Test this.unitPrice = unitPrice; public void testGetGoodsPrice() { } Goods ice = new public int getPrice() { Goods(100); return this.unitPrice; } assertEquals(100, ice.getPrice()); public int getTaxIndludedPrice() { } return @Test (int)(this.unitPrice*1.05); public void testGetTaxIncludedPrice(){ }} Goods ice = new Goods(100); Goods juice = new Goods(500); assertEquals(105, ice.getTaxIndludedPr ice()); assertEquals(525, juice.getTaxIndluded 成功。 Price()); } }
  • 21. ? テストコードのリファクタリング ? 設計の見直し(デザインパターンの適用など) ? 消費税変更への対応 ? 準正常、異常時の動作の考慮とテストケースの作 成 などなど