自作して理解する xUnit 改訂版・最終版 /self-made xunit final edition

自作して理解する xUnit 改訂版・最終版 /self-made xunit final edition

PHPerKaigi 2020 の資料です。

88964b936e864ca7d326272eaa70fa9a?s=128

Kazuki Higashiguchi

February 11, 2020
Tweet

Transcript

  1. © - BASE, Inc. X ⾃作して理解する xUnit - 改訂版 &

    最終版 - . . PHPerKaigi - @hgsgtk
  2. © - BASE, Inc. エピローグ • 我々は⽇々PHPUnitにお世話になる PHPerである • しかし、PHPUnitのユーザーとしての

    関わりばかりで、PHPUnit⾃⾝が何を しているのかに⽬を向ける機会は少ない
  3. © - BASE, Inc. エピローグ • PHPUnitはxUnitというテスティングフ レームワークファミリーの⼀⼈ • そもそもxUnitという単語は知っていて

    も、それらがどのような役割‧機能を 持っているものなのか知っているだろう か
  4. © - BASE, Inc. xUnitの “輪郭” を、 かんたんな⾃作を通じて 理解する 本⽇のゴール設定

  5. © - BASE, Inc. About me BASE BANK, Inc. /

    Dev Division / Tech Lead これまでの PHPerKaigi • . New!!! • 2019. 「質」のいいユニットテストを書くためのプラクティス • 2018. レビューをもらいやすい細かい プルリクの切り分け⽅ @hgsgtk Kazuki Higashiguchi
  6. © - BASE, Inc. hgsgtk/mpunit - Mini PHP xUnit Testing

    Framework https://github.com/hgsgtk/mpunit
  7. © - BASE, Inc. Agenda xUnit Test Automation Framework Summary

  8. © - BASE, Inc. xUnitとは “Test Automation Framework” の総称 Kent

    Beck⽒が作成したSmalltalk製の SUnit が起源となり、Javaの JUnit で広 まり、PHPでは、PHPUnit が2020年にお けるデファクトスタンダードに https://en.wikipedia.org/wiki/XUnit https://martinfowler.com/bliki/Xunit.html
  9. © - BASE, Inc. “Test Automation Framework” “We use a

    framework that provides all the mechanisms needed to run the test logic so the test writer needs to provide only the test-specific logic.” Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 18. Test Strategy Patterns
  10. © - BASE, Inc. Ref: “xUnit Test Patterns: Refactoring Test

    Code” https://www.amazon.co.jp/xUnit-Test-Patterns-Refactoring-Addison-Wesley/dp/
  11. © - BASE, Inc. テストスイートを実⾏し結果を記録する ために必要なメカニズムを持つ • テストを⾒つける • テストスイートに組み⽴てる

    • 順番に実⾏する • 期待値を検証する • テストの失敗‧エラーをレポートする • 失敗‧エラー発⽣時にクリーンアップする “Test Automation Framework” Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 18. Test Strategy Patterns
  12. © - BASE, Inc. 様々な “Test Automation Frameworks” • Robot

    User Test Frameworks (Recorded Test) • The xUnit of Test Automation Frameworks (Scripted Test) • Data-Driven Test Frameworks (Data-Driven Test) Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 18. Test Strategy Patterns
  13. © - BASE, Inc. ※補⾜ Recorded Test • アプリケーションとのやり取りを記録 し、テストツールとして使⽤する戦略

    • 現代のもので例えれば、Seleninum な どのUIを通じて SUT を操作してその画 ⾯を記録する、といったものが該当する といってよい。
  14. © - BASE, Inc. ※補⾜ Data-Driven Test • Data-Driven Test

    は、テストに必要な データを、ファイルとして保存し、テス ト実⾏時に利⽤する • “business people” を⾃動化テストの 作成に関与してもらうのに良い戦略とさ れる
  15. © - BASE, Inc. ※ 補⾜ Fit: Framework for Data-Driven

    Test http://fit.c .com/wiki.cgi?IntroductionToFit
  16. © - BASE, Inc. 様々な “Test Automation Frameworks” • Robot

    User Test Frameworks (Recorded Test) • The xUnit of Test Automation Frameworks (Scripted Test) • Data-Driven Test Frameworks (Data-Driven Test) Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 18. Test Strategy Patterns
  17. © - BASE, Inc. Agenda xUnit Test Automation Framework Summary

  18. © - BASE, Inc. 様々な “Test Automation Frameworks” • Robot

    User Test Frameworks (Recorded Test) • The xUnit of Test Automation Frameworks (Scripted Test) • Data-Driven Test Frameworks (Data-Driven Test) Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 18. Test Strategy Patterns
  19. © - BASE, Inc. “Scripted Test” 機能を実⾏する⽬的で SUT(System Under Test:

    テスト対象システム)と対話 するテストプログラムを書くことで、テ ストを⾃動化する 我々PHPerが息を吸うように書いている “あんな感じ” テストコード
  20. © - BASE, Inc. “あんな感じ” のテストコード

  21. © - BASE, Inc. ここまでの xUnit の “輪郭” Scripted Testによるテスト⾃動化のため

    に必要なメカニズムを提供する
  22. © - BASE, Inc. . テストを⾒つける . テストスイートに組み⽴てる . 順番に実⾏する

    . 期待値を検証する . テストの失敗‧エラーをレポートする . 失敗‧エラー発⽣時にクリーンアップする 必要なメカニズム
  23. © - BASE, Inc. Component Design Test Runner Test Suite

    Test Case Test Case Test Case Test Case SUT Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 7. xUnit Basic ※ ؆ུԽ͍ͯࣔͯ͠͠·͢ɻ
  24. © - BASE, Inc. Component Design Test Runner Test Suite

    Test Case Test Case Test Case Test Case SUT Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 7. xUnit Basic .テストを⾒つける .テストスイートに組み⽴てる .順番に実⾏する .期待値を検証する .テストの失敗‧エラーをレポートする .失敗‧エラー発⽣時にクリーンアップする ※ ؆ུԽ͍ͯࣔͯ͠͠·͢ɻ
  25. © - BASE, Inc. Test Runner • 開発者が実⾏するインターフェース (GUI, CUI

    etc) • 役割 • TestSuiteの初期化 • TestCaseの実⾏ • トラッキングとレポート
  26. © - BASE, Inc. 開発者が実⾏するインターフェース: CUIでの実⾏

  27. © - BASE, Inc. CUIでの実⾏インターフェースとなる実⾏ファイル https://github.com/hgsgtk/mpunit/blob/ c e a d

    f f c b bfe ffff c/bin/mpunit#L
  28. © - BASE, Inc. Test Suiteの初期化 • テストスイート、つまり対象のテストメ ソッド郡を⾒つけてまとめる作業といえ る

    • テストメソッドの⾒つけ⽅にテスティン グフレームワークの戦略が⾒られる
  29. © - BASE, Inc. テストメソッドの⾒つけ⽅ • Test Enumeration • ⼿動でテストスイートに属するすべてのテストを

    列挙する • Test Discovery • テストスイートに属するすべてのテストを⾃動で ⾒つける • Test Selection • 付与された attribute をもとに実⾏するテストを ⾒つける
  30. © - BASE, Inc. Test Discoveryの狙い “Lost TestによるProduction Bug”を回 避するため

    Lost Test: テストメソッド‧テストケース が無効またはテストスイートに追加され ていない状態 Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 17.Project Smells
  31. © - BASE, Inc. Test Discoveryを実現してみる https://github.com/hgsgtk/mpunit/blob/ f e be

    a df aaf a a fd b /src/Command.php#L *Test.php のファイルを集める
  32. © - BASE, Inc. Test Discoveryを実現してみる https://github.com/hgsgtk/mpunit/blob/ c f b

    f ac b dcfc b f /src/TestRunner.php#L TestSuiteを初期化 TestClassを⾒つけ出し ->addTest()
  33. © - BASE, Inc. Test Discoveryを実現してみる https://github.com/hgsgtk/mpunit/blob/ c f b

    f ac b dcfc b f /src/TestRunner.php#L 役割 • TestSuiteの初期化 • TestCaseの実⾏ • トラッキングとレポート
  34. © - BASE, Inc. テストの失敗‧エラーをレポートする

  35. © - BASE, Inc. テストの失敗‧エラーを TestResult として貯める https://github.com/hgsgtk/mpunit/blob/ e ffa

    c e f c d d fb d d ef b /src/TestResult.php#L
  36. © - BASE, Inc. Component Design Test Runner Test Suite

    Test Case Test Case Test Case Test Case SUT Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 7. xUnit Basic .テストを⾒つける .テストスイートに組み⽴てる .順番に実⾏する .期待値を検証する .テストの失敗‧エラーをレポートする .失敗‧エラー発⽣時にクリーンアップする ※ ؆ུԽ͍ͯࣔͯ͠͠·͢ɻ
  37. © - BASE, Inc. TestSuite / TestCase の実装パターン シンプルなインターフェース “Standard

    Test Interface” を実装している事が多い .Count Test - テストの個数をカウント .Run Test - テストを実⾏する 単⼀‧複数とテストの個数やそれに応じた実⾏⽅法 などの詳細について気にしなくていい、という狙い がある
  38. © - BASE, Inc. PHPUnitのTest Interface https://github.com/sebastianbergmann/phpunit/blob/ddd c dc b

    e ae b ff a /src/Framework/ Test.php#L
  39. © - BASE, Inc. 実⾏するインターフェースをもつTestCase https://github.com/hgsgtk/mpunit/blob/ fc a a d

    af b c ef ee ea b /src/TestCase.php#L
  40. © - BASE, Inc. 実⾏するインターフェースをもつTestCase https://github.com/hgsgtk/mpunit/blob/ fc a a d

    af b c ef ee ea b /src/TestCase.php#L テストクラスのPUBLICメソッドから、先頭が test で始まる メソッドを探す
  41. © - BASE, Inc. 実⾏するインターフェースをもつTestCase https://github.com/hgsgtk/mpunit/blob/ fc a a d

    af b c ef ee ea b /src/TestCase.php#L テストメソッドを実⾏ @dataProvider があれば、テストメソッドに引数を付与
  42. © - BASE, Inc. 期待値を検証する • 期待値の検証(Verify)に⾄るまでに は、以下の4つの要素が存在する。 • SUTを実⾏するための準備‧SUTの実

    ⾏‧実⾏後の検証‧実⾏後の後⽚付け • これらは、 “Four-Phase Test” という 概念整理がされている
  43. © - BASE, Inc. Four-Phase Test • “We structure each

    test with four distinct parts executed in sequence.” • Four-Phase • Fixture Setup • Exercise • Verify • Fixture TearDown Meszaros, Gerard. xUnit Test Patterns: Refactoring Test Code Chapter 19.xUnit Basics Patterns
  44. setUp() tearDown

  45. © - BASE, Inc. Verify: built-in assertion method xUnitファミリーの多くは、テスト作成の 省⼒化という⽬的感のもと、built-inのア

    サーションメソッドを⽤意している
  46. © - BASE, Inc. Verify: アサーションを実現するとしたら? • assert function(PHP) <-

    MPUnit • beberlei/assert • webmozart/assert • hamcrest/hamcrest-php etc
  47. © - BASE, Inc. $this->assertSame()などを実現してみる https://github.com/hgsgtk/mpunit/blob/f c da df ee

    b e d c/src/Assert.php#L
  48. © - BASE, Inc. ここまでの xUnit の “輪郭” • Scripted

    Testによるテスト⾃動化のた めに必要なメカニズムを提供する • 必要なメカニズム • テストを⾒つける • テストスイートに組み⽴てる • 順番に実⾏する • 期待値を検証する • テストの失敗‧エラーをレポートする • 失敗‧エラー発⽣時にクリーンアップする • メカニズムを構成するコンポーネント郡
  49. © - BASE, Inc. Agenda xUnit Test Automation Framework Summary

  50. © - BASE, Inc. ⾃作してみることで輪郭を捉える • 実際に実装してみることで、xUnitがど ういうメカニズムを我々に提供している のかがわかる •

    その背景の理由‧根拠を知ることで、メ カニズムの意図に沿った使い⽅をできる のではないか • xUnitの背景をもとにPHPUnitを読むと 理解しやすくなる
  51. © - BASE, Inc. X exit();