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

    設計



         コーディング




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

    設計



         テスト




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

    設計



         テスト




               コーディング




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




     テスト              テスト




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




                 80
                 70
                 60
                 50
                 40
                 30
                 20
                 10
                  0

                      要求定義   設計   コーディング   テスト   運用
                                  工程
   コスト
    ◦ 工程の早い段階でバグ発見
   生産性
    ◦ バグの少ない高品質なプログラムを高価なツールの導入
      なしに作成できる
    ◦ プログラマの生産性のギャップを埋めることができる
   保守性
    ◦ すべてのコードにテストコードがあるので変更、リファ
      クタリング時に妥当性の確認が容易
   必要なもの
    ◦ 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

More from Tetsuya Hasegawa

CVE-2021-3156 Baron samedit (sudoの脆弱性)
CVE-2021-3156 Baron samedit (sudoの脆弱性)CVE-2021-3156 Baron samedit (sudoの脆弱性)
CVE-2021-3156 Baron samedit (sudoの脆弱性)Tetsuya Hasegawa
 
RFC8528(YANG Schema Mount)の勉強資料
RFC8528(YANG Schema Mount)の勉強資料RFC8528(YANG Schema Mount)の勉強資料
RFC8528(YANG Schema Mount)の勉強資料Tetsuya Hasegawa
 
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料Tetsuya Hasegawa
 
面白いセキュリティツール その2
面白いセキュリティツール その2面白いセキュリティツール その2
面白いセキュリティツール その2Tetsuya Hasegawa
 
RFC7589(NETCONF Protocol over TLS)の勉強資料
RFC7589(NETCONF Protocol over TLS)の勉強資料RFC7589(NETCONF Protocol over TLS)の勉強資料
RFC7589(NETCONF Protocol over TLS)の勉強資料Tetsuya Hasegawa
 
RFC8632(A YANG Data Model for Alarm Management)の勉強資料
RFC8632(A YANG Data Model for Alarm Management)の勉強資料RFC8632(A YANG Data Model for Alarm Management)の勉強資料
RFC8632(A YANG Data Model for Alarm Management)の勉強資料Tetsuya Hasegawa
 
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料Tetsuya Hasegawa
 
RFC8341(Network Configuration Access Control Model)の勉強資料。
RFC8341(Network Configuration Access Control Model)の勉強資料。RFC8341(Network Configuration Access Control Model)の勉強資料。
RFC8341(Network Configuration Access Control Model)の勉強資料。Tetsuya Hasegawa
 
RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。Tetsuya Hasegawa
 
3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要Tetsuya Hasegawa
 
RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料Tetsuya Hasegawa
 
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)Tetsuya Hasegawa
 
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料Tetsuya Hasegawa
 
RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料Tetsuya Hasegawa
 
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料Tetsuya Hasegawa
 
RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料Tetsuya Hasegawa
 
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向Tetsuya Hasegawa
 
MCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモMCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモTetsuya Hasegawa
 
面白いセキュリティツール
面白いセキュリティツール面白いセキュリティツール
面白いセキュリティツールTetsuya Hasegawa
 

More from Tetsuya Hasegawa (20)

CVE-2021-3156 Baron samedit (sudoの脆弱性)
CVE-2021-3156 Baron samedit (sudoの脆弱性)CVE-2021-3156 Baron samedit (sudoの脆弱性)
CVE-2021-3156 Baron samedit (sudoの脆弱性)
 
RFC8528(YANG Schema Mount)の勉強資料
RFC8528(YANG Schema Mount)の勉強資料RFC8528(YANG Schema Mount)の勉強資料
RFC8528(YANG Schema Mount)の勉強資料
 
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
RFC7951(JSON Encoding of Data Modeled with YANG)の勉強資料
 
面白いセキュリティツール その2
面白いセキュリティツール その2面白いセキュリティツール その2
面白いセキュリティツール その2
 
RFC7589(NETCONF Protocol over TLS)の勉強資料
RFC7589(NETCONF Protocol over TLS)の勉強資料RFC7589(NETCONF Protocol over TLS)の勉強資料
RFC7589(NETCONF Protocol over TLS)の勉強資料
 
RFC8632(A YANG Data Model for Alarm Management)の勉強資料
RFC8632(A YANG Data Model for Alarm Management)の勉強資料RFC8632(A YANG Data Model for Alarm Management)の勉強資料
RFC8632(A YANG Data Model for Alarm Management)の勉強資料
 
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
RFC5717(Partial Lock Remote Procedure Call (RPC) for NETCONF)の勉強資料
 
RFC8341(Network Configuration Access Control Model)の勉強資料。
RFC8341(Network Configuration Access Control Model)の勉強資料。RFC8341(Network Configuration Access Control Model)の勉強資料。
RFC8341(Network Configuration Access Control Model)の勉強資料。
 
RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。RFC8525(YANG Library)の勉強資料。
RFC8525(YANG Library)の勉強資料。
 
3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要3GPP F1インターフェース(TS38.470-f50)の概要
3GPP F1インターフェース(TS38.470-f50)の概要
 
RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料RFC8340(YANG Tree Diagrams)の勉強資料
RFC8340(YANG Tree Diagrams)の勉強資料
 
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)
SSHパケットの復号ツールを作ろう_v1(Decrypt SSH .pcap File)
 
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
RFC8071(NETCONF Call Home and RESTCONF Call Home)の勉強資料
 
RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料RFC6243(With-defaults Capability for NETCONF)の勉強資料
RFC6243(With-defaults Capability for NETCONF)の勉強資料
 
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
RFC6241(Network Configuration Protocol (NETCONF))の勉強資料
 
RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料RFC5277(NETCONF Event Notifications)の勉強資料
RFC5277(NETCONF Event Notifications)の勉強資料
 
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
5Gを含む将来ネットワークにおけるAI活用に関する国際標準化動向
 
MCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモMCPC第5回イノベーションチャレンジセミナーメモ
MCPC第5回イノベーションチャレンジセミナーメモ
 
RFC5996(IKEv2)第2版
RFC5996(IKEv2)第2版RFC5996(IKEv2)第2版
RFC5996(IKEv2)第2版
 
面白いセキュリティツール
面白いセキュリティツール面白いセキュリティツール
面白いセキュリティツール
 

TDD

  • 2. テスト駆動開発の説明
  • 3. テストから先に作る開発技法 ◦ テスト技法ではないので本資料ではxUnitの説明はしな い  テスティングフレームワークによるテストの自動 化 ◦ JUnit、CUnit等  リファクタリングによるシンプルな設計 ◦ 重複のない、再利用可能な、テストコードがある
  • 4. 設計→コーディング→テスト 設計 コーディング テスト
  • 5. コーディングの前にテスト 設計 テスト コーディング
  • 6. コーディングの後にもテスト 設計 テスト コーディング テスト
  • 7. その繰り返し 設計 テスト テスト コーディング
  • 8. バグ対策に掛かる費用は、後工程になるほど指数関数的に増大する。 100 90 バグ1件あたりの修正コスト 80 70 60 50 40 30 20 10 0 要求定義 設計 コーディング テスト 運用 工程
  • 9.
  • 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.  テストコードのリファクタリング  設計の見直し(デザインパターンの適用など)  消費税変更への対応  準正常、異常時の動作の考慮とテストケースの作 成 などなど