xUnit Test Patterns - Chapter19

Takuto Wada
Takuto WadaChief Executive Programmer at Towersquest
Chapter 19.
xUnit Basic
 Patterns
●   Test Definition
    ●   Test Method
        –   Four-Phase Test
    ●   Assertion Method
        –   Assertion Message
    ●   Testcase Class
●   Test Execution
    ●   Test Runner
    ●   Testcase Object
    ●   Test Suite Object
    ●   Test Discovery
    ●   Test Enumeration
    ●   Test Selection
Test Method
How It Works(1)
●   テストコードってどこに書くの?
    ●   ひとつひとつのテスト毎にメソッド (Test Method) にし
        てクラスに配置しましょう
●   How It Works
    ●   各テストをメソッド/手続き/関数のかたちで Four-
        Phase(358) の実装を行い、Fully Automated Test と
        する。
    ●   大事なのは、 assertion を書いて自己テストコード
        (Self-Checking Test:26) とすること
How It Works(2)
●   Test Method には標準 Template がある
    ●   Simple Success Test
        –   正常系のテスト。 Fixture setup から result verification ま
            で一本道
    ●   Expected Exception Test
        –   例外系のテスト
    ●   Constructor Test
        –   オブジェクトを作成し属性をテストするだけのテスト
Why We Do This
●   手続き型言語の場合
    ●   Test Method をファイルやモジュールに書く
●   オブジェクト指向言語の場合
    ●   Test Method を Testcase Class(373) の中に書
        き、Test Discovery(393) や Test Enumeration(399)
        を使って Test Method を Testcase Object(382) とし
        てインスタンス化する
    ●   標準 template に従うことでテストを読みやすくシンプ
        ルにし、 SUT の動くドキュメントとすることができる
Implementation Notes
●   どう仕組みを実装する?
    ●   Static method として実装し呼び出しを列挙する
        –   テスト結果を集めたりする共通化がやりにくい
    ●   Test Method 一つ一つに対応する Test Suite
        Object(387)をつくる
        –   Test Discovery や Test Enumaration でインスタンス化する
            場合に便利
    ●   静的型付け言語の場合はメソッドに “throws
        Exception” などを書かなければならない
        –   コンパイラに対して「この例外は Test Runner が処理するよ」
            という意思表示になる
    ●   殆どの Test Method は3パターンに分類できる
Simple Success Test
●   ソフトウェアには正常系 “happy path” があ
    る。Simple Success Test はそれを書く
    ●   SUT をインスタンス化して叩き、結果を assert
        –   言い換えると、 Four-Phase に則ったテストを書く
    ●   例外はキャッチせず、 Test Automation Framework ま
        で貫通させる
        –   テストの中で例外を扱うと Obscure Test や誤解のもと
        –   Tests as Documentation の原則を思い出そう
        –   Try-catch を書かない利点は他にもあって、 Test
            Automation Framework が例外発生行を特定しやすくなる
            こと
Simple Success Test のダメな例

public void testFlightMileage_asKm() throws Exception {
  //set up fixture
  Flight newFlight = new Flight(validFlightNumber);
  try {
    //exercise SUT
    newFlight.setMileage(1122);
                    
    //verify results
    int actualKilometres = newFlight.getMileageAsKm();
    int expectedKilometres = 1810;
    //verify results
    assertEquals( expectedKilometres, actualKilometres);
  } catch (InvalidArgumentException e) {
    fail(e.getMessage());
  } catch (ArrayStoreException e) {
    fail(e.getMessage());
  }
}



                                                      不要な try/catch
Simple Success Test の良い例

public void testFlightMileage_asKm() throws Exception {
  //set up fixture
  Flight newFlight = new Flight(validFlightNumber);
  newFlight.setMileage(1122);
  //exercise mileage translator
  int actualKilometres = newFlight.getMileageAsKm();
                   
  //verify results
  int expectedKilometres = 1810;
  assertEquals( expectedKilometres, actualKilometres);
}




                                          xUnit は unexpected exception を
                                                失敗として扱えるので、
                                           throws Exception しておけばよい
Expected Exception Test (1)
●   多くの不具合は正常系以外のパスに潜む。特に例
    外系のシナリオ。それは、
    ●   Untested Requirements (268) や、
    ●   Untested Code (268) であったりするため
●   Expected Exception Test はわざと SUT が例外
    を出すようなテストを書き、きちんと例外が出ること
    を調べる
    ●   例外の中身も調べたいときは Equality Assertion で調
        べる
    ●   例外が出なかったときは fail メソッドなどでテストを失
        敗させる
Expected Exception Test (2)
●   想定される (expected) 例外には、テストを書いた
    ほうがよい
●   再現が難しいが、出るかもしれない (might raise)
    例外には、テストを書かなくてよい
    ●   (★ ネットワーク障害とか、 Disk full とか)
    ●   そういう例外は Simple Success Test の失敗として現
        れるため
    ●   もしそういう例外もテストしたいなら、 Test Stub から例
        外を発生させてテストする
Expected Exception Test (3)
●   例外をテストするときの仕組み
    ●   JUnit 3.x
        –   ExpectedException クラスを継承させる (?)
             ●   小さいテストクラスが沢山できるし、あまり旨味は無い
    ●   JUnit 4.x, NUnit
        –   Test Method の annotation/attribute に書く
    ●   Block のある言語 (Smalltalk, Ruby, …)
        –   Block で例外が発生するか調べるテストを書ける
Expected Exception Test のダメな例

public void testSetMileage_invalidInput() throws Exception {
  //set up fixture
  Flight newFlight = new Flight(validFlightNumber);
  //exercise SUT
                   
  newFlight.setMileage(-1122); //invalid
  //how do we verify an exception was thrown?
}




                                      想定された例外なのにテストが失敗してしまう
Expected Exception Test の良い例

public void testSetMileage_invalidInput()throws Exception {
  //set up fixture
  Flight newFlight = new Flight(validFlightNumber);
  try {
                    
    //exercise SUT
    newFlight.setMileage(-1122);
    fail("Should have thrown InvalidInputException");
  } catch(InvalidArgumentException e) {
    //verify results
    assertEquals( "Flight mileage must be positive", e.getMessage());
  }
}




                                                  想定される例外を catch する
                                                 例外が出なかった場合は fail させる
Expected Exception Test の特殊例?
public void testSetMileage_invalidInput2() throws Exception {
  //set up fixture
  Flight newFlight = new Flight(validFlightNumber);
  try {
    //exercise SUT
    newFlight.setMileage(-1122);
                    
    //cannot fail() here if SUT throws same kind of exception
  } catch(AssertionFailedError e) {
    //verify results
    assertEquals( "Flight mileage must be positive", e.getMessage());
    return;
  }
  fail("Should have thrown InvalidInputException");
}




     Fail メソッドが投げる例外と同じ例外を SUT が投げる場合にはこう書くしかない !?
Method Attribute を使った EET
[Test]
[ExpectedException(typeof( InvalidArgumentException),
                       "Flight mileage must be > zero")]
public void testSetMileage_invalidInput_AttributeWithMessage() {
  //set up fixture
  Flight newFlight = new Flight(validFlightNumber);
                   
  //exercise SUT
  newFlight.setMileage(-1122);
}
Block を使った EET
Smalltalk:

testSetMileageWithInvalidInput
 self
  should: [Flight new mileage: -1122]
  raise: RuntimeError new 'Should have raised error'


Ruby:

def testSetMileage_invalidInput
 flight = Flight.new()
 assert_raises( RuntimeError, "Should have raised error") do
   flight.setMileage(-1122)
 end
end
Rspec でやってみる
describe Flight do
 before do
  @flight = Flight.new
 end

 it "Should have raised error" do
   lambda {
     flight.setMileage(-1122)
   }.should_raise(RuntimeError)
 end

end
Constructor Test
●   Fixture Setup phase で作成されたオブジェクトが
    正しく作成されているかを各 Test Method で調べ
    ていると Test Code Duplication (213) がひどく
    なる
    ●   オブジェクト作成のテストだけ別の Test Method にす
        ることで他のテストをシンプルにすることができる
    ●   Defect Localication にもなる
        –   各属性の Test Method を分けるとさらに Defect
            Localization
    ●   Constructor Test は Simple Success Test の形をと
        る場合もあるし、 Expected Exception Test の形をと
        る場合もある
Dependency Initialization Test
●   Constructor Test の亜種
●   置き換え可能な依存があるオブジェクトがある場
    合、本番環境では本物の依存オブジェクトが参照さ
    れることをテストする
●   ふつうの Constructor Test と分けて管理した方
    がよい
Constructor Test のダメな例
public void testFlightMileage_asKm2() throws Exception {
  //set up fixture
  //exercise constructor
  Flight newFlight = new Flight(validFlightNumber);
  //verify constructed object
  assertEquals(validFlightNumber, newFlight.number);
  assertEquals("", newFlight.airlineCode);
  assertNull(newFlight.airline);
  //set up mileage    
  newFlight.setMileage(1122);
  //exercise mileage translator
  int actualKilometres = newFlight.getMileageAsKm();
  //verify results
  int expectedKilometres = 1810;
  assertEquals( expectedKilometres, actualKilometres);
  //now try it with a canceled flight
  newFlight.cancel();
  try {
    newFlight.getMileageAsKm();
    fail("Expected exception");
  } catch (InvalidRequestException e) {
    assertEquals( "Cannot get cancelled flight mileage", e.getMessage());
  }
}
                                                    いろいろやりすぎでピントがあっていない
                                                           Eager Test
Constructor Test の良い例1 正常系
public void testFlightConstructor_OK() throws Exception {
  //set up fixture
  //exercise SUT
  Flight newFlight = new Flight(validFlightNumber);
  //verify results
  assertEquals(   
                 validFlightNumber, newFlight.number );
  assertEquals( "", newFlight.airlineCode );
  assertNull( newFlight.airline );
}
Constructor Test の良い例2 異常系
public void testFlightConstructor_badInput() {
  //set up fixture
  BigDecimal invalidFlightNumber = new BigDecimal(-1023);
  //exercise SUT
  try {
    Flight newFlight = new Flight(invalidFlightNumber);
                     
    fail("Didn't catch negative flight number!");
  } catch (InvalidArgumentException e) {
    //verify results
    assertEquals( "Flight numbers must be positive", e.getMessage());
  }
}
Constructor Test があると他のテストの
        ピントがはっきりする
 public void testFlightMileage_asKm() throws Exception {
   //set up fixture
   Flight newFlight = new Flight(validFlightNumber);
   newFlight.setMileage(1122);
                    
   //exercise mileage translator
   int actualKilometres = newFlight.getMileageAsKm();
   //verify results
   int expectedKilometres = 1810;
   assertEquals( expectedKilometres, actualKilometres);
 }




                                      インスタンス化直後の assertion は不要
Four-Phase Test
●   Test Definition
    ●   Test Method
        –   Four-Phase Test
    ●   Assertion Method
        –   Assertion Message
    ●   Testcase Class
●   Test Execution
    ●   Test Runner
    ●   Testcase Object
    ●   Test Suite Object
    ●   Test Discovery
    ●   Test Enumeration
    ●   Test Selection
Four-Phase Test
●   良いテストには4つの Phase がある
    ●   Setup
    ●   Exercise
    ●   Verify
    ●   Teardown
●   ワンパターン = テストの読みやすさ = Tests as
    Documentation
    ●   Test Method の中身はテスト内容に集中すべし
Four-Phase Test
●   どう setup/teardown する?
    ●   Testcase Class per Class または Testcase Class
        per Feature の場合
        –   In-line Setup
        –   Garbase-Collected Teardown または In-line Teardown
    ●   Testcase per Fixture の場合
        –   Implicit Setup
             ●   例えば setUp メソッド
        –   Implicit Teardown
             ●   例えば tearDown メソッド
例: Four-Phase Test (In-line)

public void testGetFlightsByOriginAirport_NoFlights_inline() throws Exception {
  //Fixture setup
  NonTxFlightMngtFacade facade =new NonTxFlightMngtFacade();
  BigDecimal airportId = facade.createTestAirport("1OF");
  try {
    //Exercise system
    List flightsAtDestination1 =
      facade.getFlightsByOriginAirport(airportId);
    //Verify outcome
    assertEquals( 0, flightsAtDestination1.size() );
  } finally {
    //Fixture teardown
    facade.removeAirport(airportId );
  }
}
例: 4PT (Implicit Setup/Teardown)
NonTxFlightMngtFacade facade = new NonTxFlightMngtFacade();
private BigDecimal airportId;

protected void setUp() throws Exception {
  //Fixture setup
  super.setUp();
  airportId = facade.createTestAirport("1OF");
}

public void testGetFlightsByOriginAirport_NoFlights_implicit() throws Exception {
  //Exercise SUT
  List flightsAtDestination1 = facade.getFlightsByOriginAirport(airportId);
  //Verify outcome
  assertEquals( 0, flightsAtDestination1.size() );
}

protected void tearDown() throws Exception {
  //Fixture teardown
  facade.removeAirport(airportId);
  super.tearDown();
}
Assertion Method
●   Test Definition
    ●   Test Method
        –   Four-Phase Test
    ●   Assertion Method
        –   Assertion Message
    ●   Testcase Class
●   Test Execution
    ●   Test Runner
    ●   Testcase Object
    ●   Test Suite Object
    ●   Test Discovery
    ●   Test Enumeration
    ●   Test Selection
Assertion Method
●   どうやってテストに自己チェックさせるか
    ●   ユーティリティメソッドを呼ぶことで望んだ結果になった
        かどうかの評価をすればいい
●   Fully Automated Tests(26)の肝は、テストをSelf-
    Checking Tests(26)にすること
    ●   そのためには期待する結果を表現し、自動でチェックす
        ることが必要
●   Assertion Method は期待する結果を表現し、
    ●   コンピュータにとっては実行可能に
    ●   人間には Tests as Documentation(23) になる。
Why We Do This
●   期待する結果を Conditional Test Logic(200)で
    表現すると…
    ●   饒舌に過ぎ、読むのも理解するのも難しい
    ●   Test Code Duplication(213)が発生しやすい
    ●   Buggy Test(260)も発生しやすい
●   Assetion Method はこの問題を…
    ●   再利用性の高い Test Utility Methods(599)に複雑さ
        を移すことにより解決する
    ●   そのメソッドの正しさは Test Utility Tests(599)でテス
        トすることも可能
まずはひどい例から
if (x.equals(y)) {
    throw new AssertionFailedError(
        "expected: <" + x.toString() +
        "> but found: <" + y.toString() + ">");
} else { // Okay, continue
    // ...
}

// 上の例では NPE が発生するのでガード節を入れてみると…
                      
if (x == null) { //cannot do null.equals(null)
    if (y == null ) { //they are both null so equal
        return;
    } else {
        throw new AssertionFailedError(
           "expected null but found: <" + y.toString() +">");
    }
} else if (!x.equals(y)) { //comparable but not equal!
    throw new AssertionFailedError(
            "expected: <" + x.toString() +
            "> but found: <" + y.toString() + ">");
} //equal
JUnit はこうリファクタリングした
/**
 * Asserts that two objects are equal. If they are not,
 * an AssertionFailedError is thrown with the given message.
 */
static public void assertEquals(String message,
                          Object expected,
                          Object actual) {
   if (expected == null &&actual == null)
       return;    
   if (expected != null && expected.equals(actual))
       return;
   failNotEquals(message, expected, actual);
}


---------------------------------


assertEquals( x, y ); // 呼び出し側はこれだけ!!
Implementation Notes
●   全ての xUnit ファミリーは Assetion Method を備
    えているが、考えるべきことはある
    ●   Assertion Method をどうやって呼ぶか
    ●   最適な Assertion Method をどう選ぶか
    ●   Assertion Message(370) に何を書くか
Calling Built-in Assertion Methods
●   Test Method(348) からテストフレームワーク組み
    込みで提供されている Assertion Method を呼ぶ
    には…
    ●   フレームワークが提供する Testcase Superclass(638)
        を継承する (JUnit タイプ)
    ●   グローバルクラス/モジュールを完全修飾名で呼び出す
        (NUnit タイプ)
    ●   Mixin (Test::Unit タイプ)
    ●   マクロ (CppUnit タイプ)
Assertion Messages
●   テスト失敗時の出力に含めるメッセージ
    ●   どのテストが失敗したかをわかりやすくする
        –   Assertion Roulette 参照
    ●   省略可能な引数として Assertion Method に渡すかた
        ちが多い
●   テスト失敗時に「なぜ失敗したか」の情報が多けれ
    ばデバッグは容易になる
    ●   正しい Assertion Method を選ぶことはエラー時のメッ
        セージ出力を適切にする意味でも重要
●   問題なのは、 Assertion Message の引数の順番
    が xUnit 毎にブレていること
Choosing the Right Assertion
●   Assertion Method には二つのゴールがある
    ●   期待しない結果のときにはテストを失敗させること
    ●   SUT がどう振る舞うかのドキュメントになること
●   これらのゴールを満たすため、最適な Assertion
    Method を選ぶことが重要になる
●   Assertion Method には以下のカテゴリがある
    ●   Single-Outcome Assertions
    ●   Stated Outcome Assertions
    ●   Expected Exception Assertions
    ●   Equality Assertions
    ●   Fuzzy Equality Assertions
Equality Assertion
●   結果が期待値と等価かどうかを調べる
    ●   もっとも使われる Assertion Method
●   引数の順番は規約としては expected, actual の
    順番
    ●   順番は失敗時のメッセージに関係するので重要
    ●   ★この順番でない xUnit もある。(NUnit とか)
    ●   ★自分の使う Equality Assertion の順を覚えよう
●   内部では等価性を調べるメソッドが呼ばれる
    ●   Java では equals とか
    ●   SUT ごと調べたい場合は Test-Specific Subclass
Equality Assertion いろいろ
assertEquals( expected, actual ); // since JUnit3.x

assertThat( actual, is(expected) ); // since JUnit 4.4

Assert.AreEqual( actual, expected ); // NUnit

is( actual, expected );   // Test::Simple (Perl)

equals( actual,    
                expected ); // QUnit

actual.should == expected // Rspec
Fuzzy Equality Assertion
●   結果と期待値との完全な一致が難しい場合
    ●   浮動小数点をあつかうとき
    ●   期待値と完全一致させるには結果に本質的でない不要
        なゴミが多いとき (XML の空白ノードとか)




assertEquals( 3.1415, diameter/2/radius, 0.001);

assertEquals( expectedXml, actualXml, elementsToCompare );
Stated Outcome Assertion
●   期待値を渡す必要がないとき
●   Conditional Test Logic を避けるためのガード節
    としても使える



assertNotNull(a );

assertTrue(b > c );

assertNonZero(b );
Expected Exception Assertion
●   ブロックやクロージャを備えている言語は発生する
    であろう例外をパラメータとして渡す Assertion
    Method が使える

self
  should: [Flight new mileage: -1122]
  raise: RuntimeError new 'Should have raised error'


assert_raises( RuntimeError,
            "Should have raised error")
            { flight.setMileage(-1122) }


assert_raises( RuntimeError, "Should have raised error")do
  flight.setMileage(-1122)
end
Single-Outcome Assertion
●   常に同じ振る舞いをする Assertion Method
    ●   例えば fail メソッド
●   使われる状況
    ●   まだ完成していないテスト Unfinished Test Assertion を示す
    ●   Expected Exception Test の中の try/catch ブロックで使う



fail( "Expected an exception" );


unfinishedTest();
Single-Outcome Assertion の例

public void testSetMileage_invalidInput()throws Exception {
  //set up fixture
  Flight newFlight = new Flight(validFlightNumber);
  try {
                    
    //exercise SUT
    newFlight.setMileage(-1122);
    fail("Should have thrown InvalidInputException");
  } catch(InvalidArgumentException e) {
    //verify results
    assertEquals( "Flight mileage must be positive", e.getMessage());
  }
}




                                                  想定される例外を catch する
                                                 例外が出なかった場合は fail させる
Assertion Message
●   Test Definition
    ●   Test Method
        –   Four-Phase Test
    ●   Assertion Method
        –   Assertion Message
    ●   Testcase Class
●   Test Execution
    ●   Test Runner
    ●   Testcase Object
    ●   Test Suite Object
    ●   Test Discovery
    ●   Test Enumeration
    ●   Test Selection
Assertion Message
●   どの Assertion Method が落ちたか知りたい
    ●   Assertion Method 毎にメッセージ引数を渡す
●   テスト失敗時の出力に含めるメッセージ
    ●   どのテストが失敗したかをわかりやすくする
        –   Assertion Roulette 参照
    ●   省略可能な引数として Assertion Method に渡すかた
        ちが多い
When to Use It
●   二つの学派(School)がある
    ●   テスト駆動派 (Test drivers) と、その他派
●   テスト駆動派
    ●   “single assertion per Test Method”
    ●   Test Method に Assertion Method がひとつしかな
        いので、どの Assertion Method が落ちたかは自明。
        故に Assertion Message は不要。
●   その他派
    ●   ひとつの Test Method に複数 Assertion Method が
        あるので、 Assertion Message を使いたくなる
Implementation Notes
●   Assertion Message に何を書くべきか
    ●   Assertion-Identifying Message
    ●   Expectation-Describing Message
    ●   Argument-Describing Message
Assertion-Identifying Message
●   同種の Assertion Method が複数ある場合にどれ
    が失敗したか分かりにくい
    ●   Assertion Method 毎に違う文字列を渡して識別する
●   識別に使う文字列の例
    ●   Assertion Method に使う変数名
        –   名前に悩む必要がないので便利かも
    ●   単なる連番
        –   テストコードを読まないと結局どこが失敗したかわからなかっ
            たりする
Expectation-Describing Message
●   テストが失敗した時に「実際何が起こったか」はわ
    かる。だが「何が起こるべきだったか」はわからな
    い。
    ●   テストコード内にコメントを書く手もある
●   もっと良いのは Assertion Message に期待値の
    説明を書くこと
    ●   Equality Assertion の場合は自動でやってくれるので
        必要無し
    ●   Stated Outcome Assertion の場合は入れなければ
        わからない
Argument-Describing Message
●   いくつかの Assertion Method は失敗時の出力が
    不親切
    ●   特に Stated Outcome Assertion
        –   assertTrue(式) とか
        –   失敗したのはわかるが、どんな式が失敗したのかわからない
        –   式を Assertion Message に含めてしまう手がある
Argument-Describing Messageの例

assertTrue( "Expected a > b but a was '" + a.toString() +
         "' and b was '" + b.toString() + "'", a.gt(b) );

assertTrue( "Expected b > c but b was '" + b.toString() +
         "' and    '" + c.toString + "'", b > c ); }
               c was
ご清聴
 ありがとう
ございました
1 of 58

Recommended

xUnit Test Patterns - Chapter16 by
xUnit Test Patterns - Chapter16xUnit Test Patterns - Chapter16
xUnit Test Patterns - Chapter16Takuto Wada
4K views90 slides
xUTP Chapter19 (2). Testcase Class by
xUTP Chapter19 (2). Testcase ClassxUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassTakuto Wada
2.6K views22 slides
Akka Unit Testing by
Akka Unit TestingAkka Unit Testing
Akka Unit TestingMasashi (Jangsa) Kawaguchi
567 views34 slides
あんなテスト、こんなテスト(this and that about testing) by
あんなテスト、こんなテスト(this and that about testing)あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)Takuya Tsuchida
2.4K views31 slides
CLRH_120414_WFTDD by
CLRH_120414_WFTDDCLRH_120414_WFTDD
CLRH_120414_WFTDDTomoyuki Obi
773 views49 slides
C# から java へのプログラム移植で体験したtddの効果は? by
C# から java へのプログラム移植で体験したtddの効果は?C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?Shinichi Hirauchi
4.9K views89 slides

More Related Content

What's hot

Apache Wicketのユニットテスト機能 by
Apache Wicketのユニットテスト機能Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能Hiroto Yamakawa
1.8K views35 slides
ソフトウェア・テスト入門5 by
ソフトウェア・テスト入門5ソフトウェア・テスト入門5
ソフトウェア・テスト入門5Kenta Hattori
204 views26 slides
xUnit Test Patterns - Chapter11 by
xUnit Test Patterns - Chapter11xUnit Test Patterns - Chapter11
xUnit Test Patterns - Chapter11Takuto Wada
5.8K views19 slides
モデル検査入門 #wacate by
モデル検査入門 #wacateモデル検査入門 #wacate
モデル検査入門 #wacateKinji Akemine
15.7K views56 slides
Introduction to boost test by
Introduction to boost testIntroduction to boost test
Introduction to boost testKohsuke Yuasa
4.1K views122 slides
20161203 selenium adventcalender by
20161203 selenium adventcalender20161203 selenium adventcalender
20161203 selenium adventcalenderNaoya Kojima
949 views11 slides

What's hot(16)

Apache Wicketのユニットテスト機能 by Hiroto Yamakawa
Apache Wicketのユニットテスト機能Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能
Hiroto Yamakawa1.8K views
ソフトウェア・テスト入門5 by Kenta Hattori
ソフトウェア・テスト入門5ソフトウェア・テスト入門5
ソフトウェア・テスト入門5
Kenta Hattori204 views
xUnit Test Patterns - Chapter11 by Takuto Wada
xUnit Test Patterns - Chapter11xUnit Test Patterns - Chapter11
xUnit Test Patterns - Chapter11
Takuto Wada5.8K views
モデル検査入門 #wacate by Kinji Akemine
モデル検査入門 #wacateモデル検査入門 #wacate
モデル検査入門 #wacate
Kinji Akemine15.7K views
Introduction to boost test by Kohsuke Yuasa
Introduction to boost testIntroduction to boost test
Introduction to boost test
Kohsuke Yuasa4.1K views
20161203 selenium adventcalender by Naoya Kojima
20161203 selenium adventcalender20161203 selenium adventcalender
20161203 selenium adventcalender
Naoya Kojima949 views
ゆもつよ博士論文説明資料公開 by Tsuyoshi Yumoto
ゆもつよ博士論文説明資料公開ゆもつよ博士論文説明資料公開
ゆもつよ博士論文説明資料公開
Tsuyoshi Yumoto2K views
Ruby初級者向けレッスン 第46回 ─── Test::Unit by higaki
Ruby初級者向けレッスン 第46回 ─── Test::UnitRuby初級者向けレッスン 第46回 ─── Test::Unit
Ruby初級者向けレッスン 第46回 ─── Test::Unit
higaki4.4K views
Code complete ch22_developper_test by Sho Shimauchi
Code complete ch22_developper_testCode complete ch22_developper_test
Code complete ch22_developper_test
Sho Shimauchi849 views
111008 silverlight square_datavalidation by Takayoshi Tanaka
111008 silverlight square_datavalidation111008 silverlight square_datavalidation
111008 silverlight square_datavalidation
Takayoshi Tanaka792 views
xUTP Chapter26. Dependency Injection by Takuto Wada
xUTP Chapter26. Dependency InjectionxUTP Chapter26. Dependency Injection
xUTP Chapter26. Dependency Injection
Takuto Wada4.3K views
第4回勉強会 単体テストのすすめ by hakoika-itwg
第4回勉強会 単体テストのすすめ第4回勉強会 単体テストのすすめ
第4回勉強会 単体テストのすすめ
hakoika-itwg9.4K views
はこだてIKA 第4回勉強会 単体テスト by Seiji KOMATSU
はこだてIKA 第4回勉強会 単体テストはこだてIKA 第4回勉強会 単体テスト
はこだてIKA 第4回勉強会 単体テスト
Seiji KOMATSU785 views
Inside Frontend 2 #insideFE by Hiroyuki Anai
Inside Frontend 2 #insideFEInside Frontend 2 #insideFE
Inside Frontend 2 #insideFE
Hiroyuki Anai6.4K views

Viewers also liked

Introduction to Unit Testing by
Introduction to Unit TestingIntroduction to Unit Testing
Introduction to Unit TestingGil Zilberfeld
556 views41 slides
ASP.NET Core 2.0 - .NET São Paulo - Outubro-2017 by
ASP.NET Core 2.0 - .NET São Paulo - Outubro-2017ASP.NET Core 2.0 - .NET São Paulo - Outubro-2017
ASP.NET Core 2.0 - .NET São Paulo - Outubro-2017Renato Groff
201 views37 slides
Using xUnit as a Swiss-Aarmy Testing Toolkit by
Using xUnit as a Swiss-Aarmy Testing ToolkitUsing xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing ToolkitChris Oldwood
672 views31 slides
Mini training - Moving to xUnit.net by
Mini training - Moving to xUnit.netMini training - Moving to xUnit.net
Mini training - Moving to xUnit.netBetclic Everest Group Tech Team
1.6K views23 slides
Le Tour de xUnit by
Le Tour de xUnitLe Tour de xUnit
Le Tour de xUnitAbdelmonaim Remani
1.6K views104 slides
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017 by
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017Carol Smith
4.9M views66 slides

Viewers also liked(6)

Introduction to Unit Testing by Gil Zilberfeld
Introduction to Unit TestingIntroduction to Unit Testing
Introduction to Unit Testing
Gil Zilberfeld556 views
ASP.NET Core 2.0 - .NET São Paulo - Outubro-2017 by Renato Groff
ASP.NET Core 2.0 - .NET São Paulo - Outubro-2017ASP.NET Core 2.0 - .NET São Paulo - Outubro-2017
ASP.NET Core 2.0 - .NET São Paulo - Outubro-2017
Renato Groff201 views
Using xUnit as a Swiss-Aarmy Testing Toolkit by Chris Oldwood
Using xUnit as a Swiss-Aarmy Testing ToolkitUsing xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing Toolkit
Chris Oldwood672 views
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017 by Carol Smith
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017
AI and Machine Learning Demystified by Carol Smith at Midwest UX 2017
Carol Smith4.9M views

Similar to xUnit Test Patterns - Chapter19

Tokyor14 - R言語でユニットテスト by
Tokyor14 - R言語でユニットテストTokyor14 - R言語でユニットテスト
Tokyor14 - R言語でユニットテストYohei Sato
6.6K views41 slides
究極のバッチフレームワーク(予定) by
究極のバッチフレームワーク(予定)究極のバッチフレームワーク(予定)
究極のバッチフレームワーク(予定)fumoto kazuhiro
1.4K views26 slides
Unit test in android by
Unit test in androidUnit test in android
Unit test in androidTatsuya Maki
1.9K views92 slides
tdd4cpp demo by
tdd4cpp demotdd4cpp demo
tdd4cpp demoKaoru NAKAMURA
1.3K views14 slides
Effective java 勉強会 by
Effective java 勉強会Effective java 勉強会
Effective java 勉強会Takinami Kei
2.5K views42 slides
ソフトウェア工学2023 11 テスト by
ソフトウェア工学2023 11 テストソフトウェア工学2023 11 テスト
ソフトウェア工学2023 11 テストToru Tamaki
13 views83 slides

Similar to xUnit Test Patterns - Chapter19(19)

Tokyor14 - R言語でユニットテスト by Yohei Sato
Tokyor14 - R言語でユニットテストTokyor14 - R言語でユニットテスト
Tokyor14 - R言語でユニットテスト
Yohei Sato6.6K views
究極のバッチフレームワーク(予定) by fumoto kazuhiro
究極のバッチフレームワーク(予定)究極のバッチフレームワーク(予定)
究極のバッチフレームワーク(予定)
fumoto kazuhiro1.4K views
Unit test in android by Tatsuya Maki
Unit test in androidUnit test in android
Unit test in android
Tatsuya Maki1.9K views
Effective java 勉強会 by Takinami Kei
Effective java 勉強会Effective java 勉強会
Effective java 勉強会
Takinami Kei2.5K views
ソフトウェア工学2023 11 テスト by Toru Tamaki
ソフトウェア工学2023 11 テストソフトウェア工学2023 11 テスト
ソフトウェア工学2023 11 テスト
Toru Tamaki13 views
About func unit by gray Space
About func unitAbout func unit
About func unit
gray Space335 views
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~ by normalian
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
normalian10.4K views
Java scriptによるテスト駆動開発 by Hidekazu Nakamura
Java scriptによるテスト駆動開発Java scriptによるテスト駆動開発
Java scriptによるテスト駆動開発
Hidekazu Nakamura3.6K views
Java scriptによるテスト駆動開発 by Hidekazu Nakamura
Java scriptによるテスト駆動開発Java scriptによるテスト駆動開発
Java scriptによるテスト駆動開発
Hidekazu Nakamura1.5K views
Angular2 rc.1 unit testing overview by Mitsuru Ogawa
Angular2 rc.1 unit testing overviewAngular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overview
Mitsuru Ogawa1.7K views
Swift 2.0 で変わったところ「前編」 #cswift by Tomohiro Kumagai
Swift 2.0 で変わったところ「前編」 #cswiftSwift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswift
Tomohiro Kumagai28.6K views
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜 by JustSystems Corporation
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Unit testで定時帰宅! by Funato Takashi
Unit testで定時帰宅!Unit testで定時帰宅!
Unit testで定時帰宅!
Funato Takashi2.9K views
リファクタリング読書会20120220 by Suguru Shirai
リファクタリング読書会20120220リファクタリング読書会20120220
リファクタリング読書会20120220
Suguru Shirai1K views
TypeScript 言語処理系ことはじめ by Yu Nobuoka
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめ
Yu Nobuoka3.3K views
ありえるえりあ勉強会@五反田~テスト編~ Part3 by Tomoyuki Sato
ありえるえりあ勉強会@五反田~テスト編~ Part3ありえるえりあ勉強会@五反田~テスト編~ Part3
ありえるえりあ勉強会@五反田~テスト編~ Part3
Tomoyuki Sato667 views

More from Takuto Wada

組織にテストを書く文化を根付かせる戦略と戦術 by
組織にテストを書く文化を根付かせる戦略と戦術組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術Takuto Wada
76.4K views33 slides
OSS活動の活発さと評価の関係について by
OSS活動の活発さと評価の関係についてOSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係についてTakuto Wada
14.7K views64 slides
unassert - encourage reliable programming by writing assertions in production by
unassert - encourage reliable programming by writing assertions in productionunassert - encourage reliable programming by writing assertions in production
unassert - encourage reliable programming by writing assertions in productionTakuto Wada
18.1K views36 slides
OSS についてあれこれ by
OSS についてあれこれOSS についてあれこれ
OSS についてあれこれTakuto Wada
41.8K views65 slides
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」 by
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
148.7K views45 slides
power-assert, mechanism and philosophy by
power-assert, mechanism and philosophypower-assert, mechanism and philosophy
power-assert, mechanism and philosophyTakuto Wada
48.4K views29 slides

More from Takuto Wada(20)

組織にテストを書く文化を根付かせる戦略と戦術 by Takuto Wada
組織にテストを書く文化を根付かせる戦略と戦術組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術
Takuto Wada76.4K views
OSS活動の活発さと評価の関係について by Takuto Wada
OSS活動の活発さと評価の関係についてOSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係について
Takuto Wada14.7K views
unassert - encourage reliable programming by writing assertions in production by Takuto Wada
unassert - encourage reliable programming by writing assertions in productionunassert - encourage reliable programming by writing assertions in production
unassert - encourage reliable programming by writing assertions in production
Takuto Wada18.1K views
OSS についてあれこれ by Takuto Wada
OSS についてあれこれOSS についてあれこれ
OSS についてあれこれ
Takuto Wada41.8K views
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」 by Takuto Wada
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
Takuto Wada148.7K views
power-assert, mechanism and philosophy by Takuto Wada
power-assert, mechanism and philosophypower-assert, mechanism and philosophy
power-assert, mechanism and philosophy
Takuto Wada48.4K views
アジャイルサムライの次に読む技術書 by Takuto Wada
アジャイルサムライの次に読む技術書アジャイルサムライの次に読む技術書
アジャイルサムライの次に読む技術書
Takuto Wada25.6K views
Test Yourself - テストを書くと何がどう変わるか by Takuto Wada
Test Yourself - テストを書くと何がどう変わるかTest Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるか
Takuto Wada38.3K views
テスト用ライブラリ power-assert by Takuto Wada
テスト用ライブラリ power-assertテスト用ライブラリ power-assert
テスト用ライブラリ power-assert
Takuto Wada12.7K views
Reviewing RESTful Web Apps by Takuto Wada
Reviewing RESTful Web AppsReviewing RESTful Web Apps
Reviewing RESTful Web Apps
Takuto Wada9K views
power-assert in JavaScript by Takuto Wada
power-assert in JavaScriptpower-assert in JavaScript
power-assert in JavaScript
Takuto Wada9K views
TDD のこころ @ OSH2014 by Takuto Wada
TDD のこころ @ OSH2014TDD のこころ @ OSH2014
TDD のこころ @ OSH2014
Takuto Wada15.8K views
テストを書く文化を育てる戦略と戦術 by Takuto Wada
テストを書く文化を育てる戦略と戦術テストを書く文化を育てる戦略と戦術
テストを書く文化を育てる戦略と戦術
Takuto Wada49.4K views
私にとってのテスト by Takuto Wada
私にとってのテスト私にとってのテスト
私にとってのテスト
Takuto Wada16.8K views
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版) by Takuto Wada
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
Takuto Wada70.7K views
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 by Takuto Wada
SQLアンチパターン - 開発者を待ち受ける25の落とし穴SQLアンチパターン - 開発者を待ち受ける25の落とし穴
SQLアンチパターン - 開発者を待ち受ける25の落とし穴
Takuto Wada17.2K views
愛せないコードを書くには人生はあまりにも短い by Takuto Wada
愛せないコードを書くには人生はあまりにも短い愛せないコードを書くには人生はあまりにも短い
愛せないコードを書くには人生はあまりにも短い
Takuto Wada26.6K views
ペアプログラミング ホントのところ by Takuto Wada
ペアプログラミング ホントのところペアプログラミング ホントのところ
ペアプログラミング ホントのところ
Takuto Wada38.4K views
RESTful Web アプリの設計レビューの話 by Takuto Wada
RESTful Web アプリの設計レビューの話RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話
Takuto Wada72.2K views
例外設計における大罪 by Takuto Wada
例外設計における大罪例外設計における大罪
例外設計における大罪
Takuto Wada68.6K views

Recently uploaded

光コラボは契約してはいけない by
光コラボは契約してはいけない光コラボは契約してはいけない
光コラボは契約してはいけないTakuya Matsunaga
25 views17 slides
The Things Stack説明資料 by The Things Industries by
The Things Stack説明資料 by The Things IndustriesThe Things Stack説明資料 by The Things Industries
The Things Stack説明資料 by The Things IndustriesCRI Japan, Inc.
76 views29 slides
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」 by
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」PC Cluster Consortium
23 views36 slides
SNMPセキュリティ超入門 by
SNMPセキュリティ超入門SNMPセキュリティ超入門
SNMPセキュリティ超入門mkoda
453 views15 slides
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」 by
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」PC Cluster Consortium
45 views12 slides
定例会スライド_キャチs 公開用.pdf by
定例会スライド_キャチs 公開用.pdf定例会スライド_キャチs 公開用.pdf
定例会スライド_キャチs 公開用.pdfKeio Robotics Association
132 views64 slides

Recently uploaded(12)

光コラボは契約してはいけない by Takuya Matsunaga
光コラボは契約してはいけない光コラボは契約してはいけない
光コラボは契約してはいけない
Takuya Matsunaga25 views
The Things Stack説明資料 by The Things Industries by CRI Japan, Inc.
The Things Stack説明資料 by The Things IndustriesThe Things Stack説明資料 by The Things Industries
The Things Stack説明資料 by The Things Industries
CRI Japan, Inc.76 views
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」 by PC Cluster Consortium
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」
PCCC23:東京大学情報基盤センター 「Society5.0の実現を目指す『計算・データ・学習』の融合による革新的スーパーコンピューティング」
SNMPセキュリティ超入門 by mkoda
SNMPセキュリティ超入門SNMPセキュリティ超入門
SNMPセキュリティ超入門
mkoda453 views
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」 by PC Cluster Consortium
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」
PCCC23:富士通株式会社 テーマ1「次世代高性能・省電力プロセッサ『FUJITSU-MONAKA』」
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料) by NTT DATA Technology & Innovation
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
SSH応用編_20231129.pdf by icebreaker4
SSH応用編_20231129.pdfSSH応用編_20231129.pdf
SSH応用編_20231129.pdf
icebreaker4380 views
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20... by NTT DATA Technology & Innovation
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...
今、改めて考えるPostgreSQLプラットフォーム - マルチクラウドとポータビリティ -(PostgreSQL Conference Japan 20...
Windows 11 information that can be used at the development site by Atomu Hidaka
Windows 11 information that can be used at the development siteWindows 11 information that can be used at the development site
Windows 11 information that can be used at the development site
Atomu Hidaka90 views

xUnit Test Patterns - Chapter19

  • 2. Test Definition ● Test Method – Four-Phase Test ● Assertion Method – Assertion Message ● Testcase Class ● Test Execution ● Test Runner ● Testcase Object ● Test Suite Object ● Test Discovery ● Test Enumeration ● Test Selection
  • 4. How It Works(1) ● テストコードってどこに書くの? ● ひとつひとつのテスト毎にメソッド (Test Method) にし てクラスに配置しましょう ● How It Works ● 各テストをメソッド/手続き/関数のかたちで Four- Phase(358) の実装を行い、Fully Automated Test と する。 ● 大事なのは、 assertion を書いて自己テストコード (Self-Checking Test:26) とすること
  • 5. How It Works(2) ● Test Method には標準 Template がある ● Simple Success Test – 正常系のテスト。 Fixture setup から result verification ま で一本道 ● Expected Exception Test – 例外系のテスト ● Constructor Test – オブジェクトを作成し属性をテストするだけのテスト
  • 6. Why We Do This ● 手続き型言語の場合 ● Test Method をファイルやモジュールに書く ● オブジェクト指向言語の場合 ● Test Method を Testcase Class(373) の中に書 き、Test Discovery(393) や Test Enumeration(399) を使って Test Method を Testcase Object(382) とし てインスタンス化する ● 標準 template に従うことでテストを読みやすくシンプ ルにし、 SUT の動くドキュメントとすることができる
  • 7. Implementation Notes ● どう仕組みを実装する? ● Static method として実装し呼び出しを列挙する – テスト結果を集めたりする共通化がやりにくい ● Test Method 一つ一つに対応する Test Suite Object(387)をつくる – Test Discovery や Test Enumaration でインスタンス化する 場合に便利 ● 静的型付け言語の場合はメソッドに “throws Exception” などを書かなければならない – コンパイラに対して「この例外は Test Runner が処理するよ」 という意思表示になる ● 殆どの Test Method は3パターンに分類できる
  • 8. Simple Success Test ● ソフトウェアには正常系 “happy path” があ る。Simple Success Test はそれを書く ● SUT をインスタンス化して叩き、結果を assert – 言い換えると、 Four-Phase に則ったテストを書く ● 例外はキャッチせず、 Test Automation Framework ま で貫通させる – テストの中で例外を扱うと Obscure Test や誤解のもと – Tests as Documentation の原則を思い出そう – Try-catch を書かない利点は他にもあって、 Test Automation Framework が例外発生行を特定しやすくなる こと
  • 9. Simple Success Test のダメな例 public void testFlightMileage_asKm() throws Exception { //set up fixture Flight newFlight = new Flight(validFlightNumber); try { //exercise SUT newFlight.setMileage(1122);     //verify results int actualKilometres = newFlight.getMileageAsKm(); int expectedKilometres = 1810; //verify results assertEquals( expectedKilometres, actualKilometres); } catch (InvalidArgumentException e) { fail(e.getMessage()); } catch (ArrayStoreException e) { fail(e.getMessage()); } } 不要な try/catch
  • 10. Simple Success Test の良い例 public void testFlightMileage_asKm() throws Exception { //set up fixture Flight newFlight = new Flight(validFlightNumber); newFlight.setMileage(1122); //exercise mileage translator int actualKilometres = newFlight.getMileageAsKm();     //verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); } xUnit は unexpected exception を 失敗として扱えるので、 throws Exception しておけばよい
  • 11. Expected Exception Test (1) ● 多くの不具合は正常系以外のパスに潜む。特に例 外系のシナリオ。それは、 ● Untested Requirements (268) や、 ● Untested Code (268) であったりするため ● Expected Exception Test はわざと SUT が例外 を出すようなテストを書き、きちんと例外が出ること を調べる ● 例外の中身も調べたいときは Equality Assertion で調 べる ● 例外が出なかったときは fail メソッドなどでテストを失 敗させる
  • 12. Expected Exception Test (2) ● 想定される (expected) 例外には、テストを書いた ほうがよい ● 再現が難しいが、出るかもしれない (might raise) 例外には、テストを書かなくてよい ● (★ ネットワーク障害とか、 Disk full とか) ● そういう例外は Simple Success Test の失敗として現 れるため ● もしそういう例外もテストしたいなら、 Test Stub から例 外を発生させてテストする
  • 13. Expected Exception Test (3) ● 例外をテストするときの仕組み ● JUnit 3.x – ExpectedException クラスを継承させる (?) ● 小さいテストクラスが沢山できるし、あまり旨味は無い ● JUnit 4.x, NUnit – Test Method の annotation/attribute に書く ● Block のある言語 (Smalltalk, Ruby, …) – Block で例外が発生するか調べるテストを書ける
  • 14. Expected Exception Test のダメな例 public void testSetMileage_invalidInput() throws Exception { //set up fixture Flight newFlight = new Flight(validFlightNumber); //exercise SUT     newFlight.setMileage(-1122); //invalid //how do we verify an exception was thrown? } 想定された例外なのにテストが失敗してしまう
  • 15. Expected Exception Test の良い例 public void testSetMileage_invalidInput()throws Exception { //set up fixture Flight newFlight = new Flight(validFlightNumber); try {     //exercise SUT newFlight.setMileage(-1122); fail("Should have thrown InvalidInputException"); } catch(InvalidArgumentException e) { //verify results assertEquals( "Flight mileage must be positive", e.getMessage()); } } 想定される例外を catch する 例外が出なかった場合は fail させる
  • 16. Expected Exception Test の特殊例? public void testSetMileage_invalidInput2() throws Exception { //set up fixture Flight newFlight = new Flight(validFlightNumber); try { //exercise SUT newFlight.setMileage(-1122);     //cannot fail() here if SUT throws same kind of exception } catch(AssertionFailedError e) { //verify results assertEquals( "Flight mileage must be positive", e.getMessage()); return; } fail("Should have thrown InvalidInputException"); } Fail メソッドが投げる例外と同じ例外を SUT が投げる場合にはこう書くしかない !?
  • 17. Method Attribute を使った EET [Test] [ExpectedException(typeof( InvalidArgumentException), "Flight mileage must be > zero")] public void testSetMileage_invalidInput_AttributeWithMessage() { //set up fixture Flight newFlight = new Flight(validFlightNumber);     //exercise SUT newFlight.setMileage(-1122); }
  • 18. Block を使った EET Smalltalk: testSetMileageWithInvalidInput self should: [Flight new mileage: -1122] raise: RuntimeError new 'Should have raised error' Ruby: def testSetMileage_invalidInput flight = Flight.new() assert_raises( RuntimeError, "Should have raised error") do flight.setMileage(-1122) end end
  • 19. Rspec でやってみる describe Flight do before do @flight = Flight.new end it "Should have raised error" do lambda { flight.setMileage(-1122) }.should_raise(RuntimeError) end end
  • 20. Constructor Test ● Fixture Setup phase で作成されたオブジェクトが 正しく作成されているかを各 Test Method で調べ ていると Test Code Duplication (213) がひどく なる ● オブジェクト作成のテストだけ別の Test Method にす ることで他のテストをシンプルにすることができる ● Defect Localication にもなる – 各属性の Test Method を分けるとさらに Defect Localization ● Constructor Test は Simple Success Test の形をと る場合もあるし、 Expected Exception Test の形をと る場合もある
  • 21. Dependency Initialization Test ● Constructor Test の亜種 ● 置き換え可能な依存があるオブジェクトがある場 合、本番環境では本物の依存オブジェクトが参照さ れることをテストする ● ふつうの Constructor Test と分けて管理した方 がよい
  • 22. Constructor Test のダメな例 public void testFlightMileage_asKm2() throws Exception { //set up fixture //exercise constructor Flight newFlight = new Flight(validFlightNumber); //verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); //set up mileage     newFlight.setMileage(1122); //exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); //verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); //now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } } いろいろやりすぎでピントがあっていない Eager Test
  • 23. Constructor Test の良い例1 正常系 public void testFlightConstructor_OK() throws Exception { //set up fixture //exercise SUT Flight newFlight = new Flight(validFlightNumber); //verify results assertEquals(    validFlightNumber, newFlight.number ); assertEquals( "", newFlight.airlineCode ); assertNull( newFlight.airline ); }
  • 24. Constructor Test の良い例2 異常系 public void testFlightConstructor_badInput() { //set up fixture BigDecimal invalidFlightNumber = new BigDecimal(-1023); //exercise SUT try { Flight newFlight = new Flight(invalidFlightNumber);     fail("Didn't catch negative flight number!"); } catch (InvalidArgumentException e) { //verify results assertEquals( "Flight numbers must be positive", e.getMessage()); } }
  • 25. Constructor Test があると他のテストの ピントがはっきりする public void testFlightMileage_asKm() throws Exception { //set up fixture Flight newFlight = new Flight(validFlightNumber); newFlight.setMileage(1122);     //exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); //verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); } インスタンス化直後の assertion は不要
  • 27. Test Definition ● Test Method – Four-Phase Test ● Assertion Method – Assertion Message ● Testcase Class ● Test Execution ● Test Runner ● Testcase Object ● Test Suite Object ● Test Discovery ● Test Enumeration ● Test Selection
  • 28. Four-Phase Test ● 良いテストには4つの Phase がある ● Setup ● Exercise ● Verify ● Teardown ● ワンパターン = テストの読みやすさ = Tests as Documentation ● Test Method の中身はテスト内容に集中すべし
  • 29. Four-Phase Test ● どう setup/teardown する? ● Testcase Class per Class または Testcase Class per Feature の場合 – In-line Setup – Garbase-Collected Teardown または In-line Teardown ● Testcase per Fixture の場合 – Implicit Setup ● 例えば setUp メソッド – Implicit Teardown ● 例えば tearDown メソッド
  • 30. 例: Four-Phase Test (In-line) public void testGetFlightsByOriginAirport_NoFlights_inline() throws Exception { //Fixture setup NonTxFlightMngtFacade facade =new NonTxFlightMngtFacade(); BigDecimal airportId = facade.createTestAirport("1OF"); try { //Exercise system List flightsAtDestination1 = facade.getFlightsByOriginAirport(airportId); //Verify outcome assertEquals( 0, flightsAtDestination1.size() ); } finally { //Fixture teardown facade.removeAirport(airportId ); } }
  • 31. 例: 4PT (Implicit Setup/Teardown) NonTxFlightMngtFacade facade = new NonTxFlightMngtFacade(); private BigDecimal airportId; protected void setUp() throws Exception { //Fixture setup super.setUp(); airportId = facade.createTestAirport("1OF"); } public void testGetFlightsByOriginAirport_NoFlights_implicit() throws Exception { //Exercise SUT List flightsAtDestination1 = facade.getFlightsByOriginAirport(airportId); //Verify outcome assertEquals( 0, flightsAtDestination1.size() ); } protected void tearDown() throws Exception { //Fixture teardown facade.removeAirport(airportId); super.tearDown(); }
  • 33. Test Definition ● Test Method – Four-Phase Test ● Assertion Method – Assertion Message ● Testcase Class ● Test Execution ● Test Runner ● Testcase Object ● Test Suite Object ● Test Discovery ● Test Enumeration ● Test Selection
  • 34. Assertion Method ● どうやってテストに自己チェックさせるか ● ユーティリティメソッドを呼ぶことで望んだ結果になった かどうかの評価をすればいい ● Fully Automated Tests(26)の肝は、テストをSelf- Checking Tests(26)にすること ● そのためには期待する結果を表現し、自動でチェックす ることが必要 ● Assertion Method は期待する結果を表現し、 ● コンピュータにとっては実行可能に ● 人間には Tests as Documentation(23) になる。
  • 35. Why We Do This ● 期待する結果を Conditional Test Logic(200)で 表現すると… ● 饒舌に過ぎ、読むのも理解するのも難しい ● Test Code Duplication(213)が発生しやすい ● Buggy Test(260)も発生しやすい ● Assetion Method はこの問題を… ● 再利用性の高い Test Utility Methods(599)に複雑さ を移すことにより解決する ● そのメソッドの正しさは Test Utility Tests(599)でテス トすることも可能
  • 36. まずはひどい例から if (x.equals(y)) { throw new AssertionFailedError( "expected: <" + x.toString() + "> but found: <" + y.toString() + ">"); } else { // Okay, continue // ... } // 上の例では NPE が発生するのでガード節を入れてみると…     if (x == null) { //cannot do null.equals(null) if (y == null ) { //they are both null so equal return; } else { throw new AssertionFailedError( "expected null but found: <" + y.toString() +">"); } } else if (!x.equals(y)) { //comparable but not equal! throw new AssertionFailedError( "expected: <" + x.toString() + "> but found: <" + y.toString() + ">"); } //equal
  • 37. JUnit はこうリファクタリングした /** * Asserts that two objects are equal. If they are not, * an AssertionFailedError is thrown with the given message. */ static public void assertEquals(String message, Object expected, Object actual) { if (expected == null &&actual == null) return;     if (expected != null && expected.equals(actual)) return; failNotEquals(message, expected, actual); } --------------------------------- assertEquals( x, y ); // 呼び出し側はこれだけ!!
  • 38. Implementation Notes ● 全ての xUnit ファミリーは Assetion Method を備 えているが、考えるべきことはある ● Assertion Method をどうやって呼ぶか ● 最適な Assertion Method をどう選ぶか ● Assertion Message(370) に何を書くか
  • 39. Calling Built-in Assertion Methods ● Test Method(348) からテストフレームワーク組み 込みで提供されている Assertion Method を呼ぶ には… ● フレームワークが提供する Testcase Superclass(638) を継承する (JUnit タイプ) ● グローバルクラス/モジュールを完全修飾名で呼び出す (NUnit タイプ) ● Mixin (Test::Unit タイプ) ● マクロ (CppUnit タイプ)
  • 40. Assertion Messages ● テスト失敗時の出力に含めるメッセージ ● どのテストが失敗したかをわかりやすくする – Assertion Roulette 参照 ● 省略可能な引数として Assertion Method に渡すかた ちが多い ● テスト失敗時に「なぜ失敗したか」の情報が多けれ ばデバッグは容易になる ● 正しい Assertion Method を選ぶことはエラー時のメッ セージ出力を適切にする意味でも重要 ● 問題なのは、 Assertion Message の引数の順番 が xUnit 毎にブレていること
  • 41. Choosing the Right Assertion ● Assertion Method には二つのゴールがある ● 期待しない結果のときにはテストを失敗させること ● SUT がどう振る舞うかのドキュメントになること ● これらのゴールを満たすため、最適な Assertion Method を選ぶことが重要になる ● Assertion Method には以下のカテゴリがある ● Single-Outcome Assertions ● Stated Outcome Assertions ● Expected Exception Assertions ● Equality Assertions ● Fuzzy Equality Assertions
  • 42. Equality Assertion ● 結果が期待値と等価かどうかを調べる ● もっとも使われる Assertion Method ● 引数の順番は規約としては expected, actual の 順番 ● 順番は失敗時のメッセージに関係するので重要 ● ★この順番でない xUnit もある。(NUnit とか) ● ★自分の使う Equality Assertion の順を覚えよう ● 内部では等価性を調べるメソッドが呼ばれる ● Java では equals とか ● SUT ごと調べたい場合は Test-Specific Subclass
  • 43. Equality Assertion いろいろ assertEquals( expected, actual ); // since JUnit3.x assertThat( actual, is(expected) ); // since JUnit 4.4 Assert.AreEqual( actual, expected ); // NUnit is( actual, expected ); // Test::Simple (Perl) equals( actual,     expected ); // QUnit actual.should == expected // Rspec
  • 44. Fuzzy Equality Assertion ● 結果と期待値との完全な一致が難しい場合 ● 浮動小数点をあつかうとき ● 期待値と完全一致させるには結果に本質的でない不要 なゴミが多いとき (XML の空白ノードとか) assertEquals( 3.1415, diameter/2/radius, 0.001); assertEquals( expectedXml, actualXml, elementsToCompare );
  • 45. Stated Outcome Assertion ● 期待値を渡す必要がないとき ● Conditional Test Logic を避けるためのガード節 としても使える assertNotNull(a ); assertTrue(b > c ); assertNonZero(b );
  • 46. Expected Exception Assertion ● ブロックやクロージャを備えている言語は発生する であろう例外をパラメータとして渡す Assertion Method が使える self should: [Flight new mileage: -1122] raise: RuntimeError new 'Should have raised error' assert_raises( RuntimeError, "Should have raised error") { flight.setMileage(-1122) } assert_raises( RuntimeError, "Should have raised error")do flight.setMileage(-1122) end
  • 47. Single-Outcome Assertion ● 常に同じ振る舞いをする Assertion Method ● 例えば fail メソッド ● 使われる状況 ● まだ完成していないテスト Unfinished Test Assertion を示す ● Expected Exception Test の中の try/catch ブロックで使う fail( "Expected an exception" ); unfinishedTest();
  • 48. Single-Outcome Assertion の例 public void testSetMileage_invalidInput()throws Exception { //set up fixture Flight newFlight = new Flight(validFlightNumber); try {     //exercise SUT newFlight.setMileage(-1122); fail("Should have thrown InvalidInputException"); } catch(InvalidArgumentException e) { //verify results assertEquals( "Flight mileage must be positive", e.getMessage()); } } 想定される例外を catch する 例外が出なかった場合は fail させる
  • 50. Test Definition ● Test Method – Four-Phase Test ● Assertion Method – Assertion Message ● Testcase Class ● Test Execution ● Test Runner ● Testcase Object ● Test Suite Object ● Test Discovery ● Test Enumeration ● Test Selection
  • 51. Assertion Message ● どの Assertion Method が落ちたか知りたい ● Assertion Method 毎にメッセージ引数を渡す ● テスト失敗時の出力に含めるメッセージ ● どのテストが失敗したかをわかりやすくする – Assertion Roulette 参照 ● 省略可能な引数として Assertion Method に渡すかた ちが多い
  • 52. When to Use It ● 二つの学派(School)がある ● テスト駆動派 (Test drivers) と、その他派 ● テスト駆動派 ● “single assertion per Test Method” ● Test Method に Assertion Method がひとつしかな いので、どの Assertion Method が落ちたかは自明。 故に Assertion Message は不要。 ● その他派 ● ひとつの Test Method に複数 Assertion Method が あるので、 Assertion Message を使いたくなる
  • 53. Implementation Notes ● Assertion Message に何を書くべきか ● Assertion-Identifying Message ● Expectation-Describing Message ● Argument-Describing Message
  • 54. Assertion-Identifying Message ● 同種の Assertion Method が複数ある場合にどれ が失敗したか分かりにくい ● Assertion Method 毎に違う文字列を渡して識別する ● 識別に使う文字列の例 ● Assertion Method に使う変数名 – 名前に悩む必要がないので便利かも ● 単なる連番 – テストコードを読まないと結局どこが失敗したかわからなかっ たりする
  • 55. Expectation-Describing Message ● テストが失敗した時に「実際何が起こったか」はわ かる。だが「何が起こるべきだったか」はわからな い。 ● テストコード内にコメントを書く手もある ● もっと良いのは Assertion Message に期待値の 説明を書くこと ● Equality Assertion の場合は自動でやってくれるので 必要無し ● Stated Outcome Assertion の場合は入れなければ わからない
  • 56. Argument-Describing Message ● いくつかの Assertion Method は失敗時の出力が 不親切 ● 特に Stated Outcome Assertion – assertTrue(式) とか – 失敗したのはわかるが、どんな式が失敗したのかわからない – 式を Assertion Message に含めてしまう手がある
  • 57. Argument-Describing Messageの例 assertTrue( "Expected a > b but a was '" + a.toString() + "' and b was '" + b.toString() + "'", a.gt(b) ); assertTrue( "Expected b > c but b was '" + b.toString() + "' and    '" + c.toString + "'", b > c ); } c was