Slide 1

Slide 1 text

CakePHP Fixture Factories の登場によって変化する、 PHPプロジェクトにおけるテストフィクスチャ管理の 選択肢 2022/04/11 PHPerKaigi 2022 #phperkaigi #b @takoba

Slide 2

Slide 2 text

誰? takoba / ばーばら 🌹 🏢 コネヒト株式会社 󰳕 Webアプリケーション / PHP / ちょっとReact / たまにUXデザイン 🏓 インターネット / 音楽 / カレーライス / 銭湯 / Jリーグ / ポッドキャスト @takoba @takoba_

Slide 3

Slide 3 text

[PR]会社紹介 「あなたの家族像が実現できる社会をつくる」というビジョンを掲げ、 ママの3人に1人(※) が利用する「ママリ」などを運営しています。 ※「ママリ」で2019年に出産予定と設定したユーザー数と、厚生労働省発表「人口動態統計」の出生数から算出

Slide 4

Slide 4 text

[PR]会社紹介 「あなたの家族像が実現できる社会をつくる」というビジョンを掲げ、 ママの3人に1人(※) が利用する「ママリ」などを運営しています。 ※「ママリ」で2019年に出産予定と設定したユーザー数と、厚生労働省発表「人口動態統計」の出生数から算出 「ママリ」は主にサーバーサイドが CakePHP 3-4 で書かれています! (ご興味のある方は Twitter: @takoba_ まで 💌 )

Slide 5

Slide 5 text

xUnitとテストフィクスチャと私 (愛するあなたのために)前提

Slide 6

Slide 6 text

● cf. xUnit - Wikipedia ○ > コンピュータプログラムの単体テスト(ユニットテスト)を行うためのテ スティングフレームワークの総称 ○ この中の xUnitの設計 項の中に"テストスイート"、"テストの実行"、"ア サーション(表明、検証)"と並んで"テストフィクスチャ"がある ● 各種言語にxUnitに準拠したテスティングフレームワークが存在する ○ JUnit(Java向けテスティングフレームワーク) ○ test-unit / Test::Unit(Ruby向けテスティングフレームワーク) ○ MochiKit(JavaScript向けテスティングフレームワーク) ○ PHPUnit(PHP向けテスティングフレームワーク) (おさらい)xUnitとは?

Slide 7

Slide 7 text

● cf. xUnit - Wikipedia ○ > テストを実行、成功させるために必要な状態や前提条件の集合を、フィク スチャ(英語版)と呼ぶ。これらはテストコンテキストとも呼ばれる。開 発者はテストの実行前にテストに適した状態を整え、テスト実行後に元の 状態を復元することが望ましい。 ● テストフィクスチャは前提条件となるもの全てを指してる ○ データベースにレコードを登録するアプリだったら、データベース(およ び事前に必要になるレコード)がテストフィクスチャ ○ 文字をトークナイズするライブラリだったら、自然言語のテキストたちが テストフィクスチャ ■ 小さなライブラリなら単なる文字列とか配列とかもそう テストフィクスチャとは

Slide 8

Slide 8 text

● cf. xUnit - Wikipedia ○ > テストを実行、成功させるために必要な状態や前提条件の集合を、フィク スチャ(英語版)と呼ぶ。これらはテストコンテキストとも呼ばれる。開 発者はテストの実行前にテストに適した状態を整え、テスト実行後に元の 状態を復元することが望ましい。 ● テストフィクスチャは前提条件となるもの全てを指してる ○ データベースにレコードを登録するアプリだったら、データベース(およ び事前に必要になるレコード)がテストフィクスチャ ○ 文字をトークナイズするライブラリだったら、自然言語のテキストたちが テストフィクスチャ ■ 小さなライブラリなら単なる文字列とか配列とかもそう テストフィクスチャとは xUnitに準拠したユニットテストでは、 テストフィクスチャはなくてはならないもの(=前提)

Slide 9

Slide 9 text

「その中でも、データベースと密接に連携するWebアプリケーションに おいては、データベースにデータを投入し、そのデータをテストフィク スチャとして利用するテクニックは初期の頃から利用されてきました」

Slide 10

Slide 10 text

(ほんと...?) 🤔

Slide 11

Slide 11 text

● 「どんくらい昔からやってるのそれ?」 ○ とりあえず Rails 2.x の段階ではすでにテストフィクスチャについて RailsGuides に言及されていた ので、まあフルスタックフレームワークが登 場した初期の頃(2008年くらい)から存在してそう ○ そして rails/rails v1.0.0 の activerecord にも普通にfixtures.rb があった ので、rails正式リリース当初(2005年くらい)から存在してそう ■ @t_wada「エリック・ガンマとケント・ベックがチューリッヒからア トランタまでのフライトの中で"SUnitをJUnitに移植する"という伝説の ペアプロを行った、ってのがあって、それが今年(2022年)で25年」 ● cf. 9. The 20th Anniversary of TDD by texta.fm Webアプリケーションのテストフィクスチャ

Slide 12

Slide 12 text

● 「うん...そうなんだ...」 ○ @t_wada「テスト駆動開発(TDD; Test-Driven Development)が生まれた のも2002年」とも言ってるので、割とフルスタックフレームワークでテス トが整備されたのってRuby on Railsは割と早かったんだと思う ○ @t_wada「TDD原著が出たのも言葉が生まれた直後。2002年だった、と」 ○ もしかしたら初期のStrutsとかで用意されてる可能性はあるけど調べきれ ず Webアプリケーションのテストフィクスチャ

Slide 13

Slide 13 text

「各種アプリケーションフレームワークではテストフィクスチャはどん なかんじで取り入れられてるの??」

Slide 14

Slide 14 text

● Ruby on Railsの場合はどういう仕組みになってる? ○ (ちょっと先に言っちゃったけど)YAMLファイルとか定義してDBに取り込 む ActiveRecord::FixtureSet ってクラスがある ○ cf. 4.2. テストフィクスチャのしくみ | Rails テスティングガイド - Railsガ イド Ruby on Railsのテストフィクスチャ

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

● CakePHPの場合はどういう仕組みになってる? ○ class Cake\TestSuite\Fixture\TestFixture ってクラスがある ○ PHPファイルに配列を書いて定義するかんじ ○ cf. フィクスチャー | テスト - CakePHP 4.x Strawberry Cookbook CakePHPのテストフィクスチャ

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

● Laravelの場合はどういう仕組みになってる? ○ おっと?? Laravel 9 ではModel Factories という概念を使ってるね?? ○ cf. Defining Model Factories | Database Testing - Laravel - The PHP Framework For Web Artisans ■ Laravel 5.3くらいからあるっぽい?誰か補足して... ● cf. Writing Factories | Database Testing - Laravel - The PHP Framework For Web Artisans Laravelのテストフィクスチャ

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

● xUnitの構成要素としてテストフィクスチャという概念は定義されてる ● データベースを使ったテストフィクスチャは、Webアプリのフルスタックフレー ムワークが登場したタイミングには既にあった ● 各種フルスタックフレームワークには、テストフィクスチャを扱う仕組みが大 体整備されている ○ YAMLとか言語構文で提供されてたけど、Laravelでは早い段階からModel Factoriesという概念/実装が実現されていた ここまでのまとめ

Slide 21

Slide 21 text

テストフィクスチャを分解してみる セットアップ戦略とライフサイクル

Slide 22

Slide 22 text

(どこから分解すればよいの...?) 😳

Slide 23

Slide 23 text

● セットアップについては Test fixture - Wikipedia に載っていた ● > Test fixtures can be set up three different ways: in-line, delegate, and implicit. ○ テストフィクスチャは”インライン”、”委譲”、”暗黙的”といった3通りの方 法でセットアップできるんやで 3つのセットアップ戦略

Slide 24

Slide 24 text

● こんなかんじの構成を用いて説明するよ ○ App ■ class UsersClient ■ class User ○ TestSuite ■ class TestCase (class PHPUnit\Framework\TestCase のイメージ) ○ Test ■ class UsersClientTest extends TestCase ※このあとお見せするソースコードの前提

Slide 25

Slide 25 text

Slide 26

Slide 26 text

data)) { return null; } return $this->data[$id]; } public function setData(array $data): self { $isVector = array_values($data) === $data; $this->data = $isVector ? array_reduce(function ($carry, User $user) { $carry[$user->id] = $user; return $carry; }, $data) : $data; return $this; } } fields = $fields; } public function &__get(string $field) { return $this->fields[$field]; } public function __set(string $field, $value) { $this->fields[$field] = $value; } }

Slide 27

Slide 27 text

● 日本語で扱うなら「インライン・セットアップ」でよいかな ● > In-line setup creates the test fixture in the same method as the rest of the test. While in-line setup is the simplest test fixture to create, it leads to duplication when multiple tests require the same initial data. ○ 要は、テストケース内で定義される形式 In-line setup

Slide 28

Slide 28 text

● cf. Inline Setup at XUnitPatterns.com ● テストメソッドから直接テストフィクスチャ にアクセスする、ってのが図示されてる ● > Setting up the test fixture inline in each test is the most obvious way to build it. FYI: XUnitPatterns.comにはさっきのsetupも解説あり〼

Slide 29

Slide 29 text

1, 'name' => 'John']), new User(['id' => 2, 'name' => 'Paul']), ]; $client = (new UsersClient())->setData($fixture); // when $actual = $client->getUserById('1'); // then $expected = new User(['id' => 1, 'name' => 'John']); $this->assertEqual($expected, $actual); $this->assertEqual($expected->id, $actual->id); $this->assertEqual($expected->name, $actual->name); } } (new UsersClientTest())->test_getUserById(); https://3v4l.org/FhFpp テストケースの内部で定義してるから In-line setup

Slide 30

Slide 30 text

● 日本語で扱うなら「委譲セットアップ」でよいかな ● > Delegate setup places the test fixture in a separate standalone helper method that is accessed by multiple test methods. ○ 複数のテストメソッドから呼ばれるstandaloneなヘルパーメソッドを経由 して呼び出される形式 Delegate setup

Slide 31

Slide 31 text

● cf. Delegated Setup at XUnitPatterns.com ● テストメソッドからは”Utility Method”を解 してテストフィクスチャにアクセスする、っ てのが図示されてる ● > We are using a Fresh Fixture approach to build a Minimal Fixture for the use of this one test and we'd like to avoid Test Code Duplication. FYI: XUnitPatterns.comにはさっきのsetupも解説あり〼

Slide 32

Slide 32 text

validUsersDataProvider(); $client = (new UsersClient())->setData($fixture); // when $actual = $client->getUserById('1'); // then $expected = new User(['id' => 1, 'name' => 'John']); $this->assertEqual($expected, $actual); $this->assertEqual($expected->id, $actual->id); $this->assertEqual($expected->name, $actual->name); } public function validUsersDataProvider(): array { return [ new User(['id' => 1, 'name' => 'John']), new User(['id' => 2, 'name' => 'Paul']), ]; } } (new UsersClientTest())->test_getUserById(); https://3v4l.org/bdABQ テストデータの生成を別のメソッドに委譲してるので Delegate setup

Slide 33

Slide 33 text

● 日本語で扱うなら「暗黙的セットアップ」でよいかな ● > Implicit setup places the test fixture in a setup method which is used to set up multiple test methods. This differs from delegate setup in that the overall setup of multiple tests is in a single setup method where the test fixture gets created rather than each test method having its own setup procedures and linking to an external test fixture. ○ 単一のセットアップ処理で生成されて、それが複数のテストメソッドから 呼び出される ○ 多くのアプリケーションフレームワークで標準装備されてるのは、この形 式のテストフィクスチャ管理になるはず Implicit setup

Slide 34

Slide 34 text

● cf. Implicit Setup at XUnitPatterns.com ● テストメソッドからではなく setUp() がテス トフィクスチャにアクセスする、ってのが図 示されてる ● > SImplicit Setup is a way to reuse the fixture setup code for all the Test Methods in a Testcase Class. FYI: XUnitPatterns.comにはさっきのsetupも解説あり〼

Slide 35

Slide 35 text

fixture = [ new User(['id' => 1, 'name' => 'John']), new User(['id' => 2, 'name' => 'Paul']), ]; $this->subject = (new UsersClient())->setData($this->fixture); } public function test_getUserById(): void { // when $actual = $this->subject->getUserById('1'); // then $expected = current($this->fixture); $this->assertEqual($expected, $actual); } } $subject = new UsersClientTest(); $subject->setUp(); $subject->test_getUserById(); https://3v4l.org/OHsR1 テストケースの最初に暗黙的に定義しておくので Implicit setup

Slide 36

Slide 36 text

Slide 37

Slide 37 text

● cf. Fresh Fixture at XUnitPatterns.com ● > We design and build the test fixture such that only a single running of a single test will use it. We construct the fixture as part of running the test and tear down the fixture when the test has finished. ○ テストケース実行するたびにビルドして、テストケース終わったら破棄 ○ 基本的なフルスタックフレームワークはこれが前提だと思うで ● > When each test creates a Fresh Fixture, it prevents Erratic Tests and is more likely to result in Tests as Documentation. ○ Fresh Fixtureを採用すると、不規則なテストがなくなるし”Tests as Documentation(ドキュメントとしてのテスト)”となってよいわよ ○ あれ?最強そうじゃん?? これらのsetupは”Fresh Fixture”という戦略の上にある

Slide 38

Slide 38 text

弟子「じゃあFresh Fixtureでよいじゃん」 師匠「待て待て、テストスイートで大事なのはそれだけじゃないのよ」

Slide 39

Slide 39 text

● cf. abseil / Software Engineering at Google ● Part.11 Testing Overview の序文 ○ > If you have a robust testing practice, you needn’t fear change—you can embrace it as an essential quality of developing software. The more and faster you want to change your systems, the more you need a fast way to test them. ■ システムをスピード感持って変更するためには、より高速なテスト実 行環境が必要だよ ● Fresh Fixtureは都度読み込むから実行コスト/速度がかかりそうね...?? そもそも、テストスイートに重要な観点って何?

Slide 40

Slide 40 text

● cf. Software Design 2022年3月号|技術評論社 ○ @t_wadaさんの「自動テストとテスト駆動開発、その全体像」の序盤 ○ > 自動テストが必ず満たすべき性質が2つあります。自己検証可能 (Self-Validating)であることと、繰り返し可能(Repeatable)であるこ と ■ 繰り返し可能であるためにFresh Fixtureは必須になりそう ○ > 自動テストに強く推奨される性質が2つあります。独立している (Independent / Isolated)ことと高速である(Fast)こと ■ 独立していることを担保するためにテストフィクスチャも分離したい ■ 高速であるためには、Fresh Fixtureだとオーバーヘッドが大きいかも そもそも、テストスイートに重要な観点って何?

Slide 41

Slide 41 text

● cf. 現在時刻が関わるユニットテストから、テスト容易性設計を学ぶ - t-wadaの ブログ ○ > Repeatable であるとは、テストを実行するだけで、いつでも、何回でも 同じように動くということです。環境や時間によってテスト結果が変化し てしまう場合、そのテストは Repeatable ではありません。 テストコードが 変わっていないのに、状況によって通ったり通らなかったりするテスト は、書籍『xUnit Test Patterns』ではErratic Test (不安定なテスト)と 表現されています。 ● 何度も繰り返し実行するので速度も大事だし、安定して動くことも大事 FYI: 「よいユニットテストとはRepeatable」

Slide 42

Slide 42 text

● cf. Shared Fixture at XUnitPatterns.com ○ > To execute an automated test, we require a text fixture that is well understood and completely deterministic. Setting up a Fresh Fixture can be time consuming, especially when dealing with complex system state stored in a test database. ■ “Fresh Fixture”だと都度テストフィクスチャをsetupするから時間かか るのよね ■ あっ基本的にデータ投入して用意しとくから使ってや!なあ兄ちゃん ● これってテストケースの実行サイクルとは別に、”すでに用意され ているテストフィクスチャ”として扱う必要があるのよね 高速化のためのテストフィクスチャ戦略

Slide 43

Slide 43 text

● Shared Fixtureを実現するには、”完全に決定論的であり、よく理解されたテス トフィクスチャ"が必要 ○ cf. 決定論 - Wikipedia ■ > 決定論(英: determinism)とは、あらゆる出来事は、その出来事に 先行する出来事のみによって決定している、とする哲学的な立場。 ○ 要は、状態とかが諸々固定されたテストフィクスチャが必要になる ■ 「あれ?じゃあ同じテストケースでも、前提条件が異なるテストフィ クスチャが必要な時はどうするの...?」「...君のような勘のいいガキは 嫌いだよ」 決定論的なテストフィクスチャが必要なのだけど...

Slide 44

Slide 44 text

● cf. Standard Fixture at XUnitPatterns.com ○ > A Standard Fixture is a way to reuse the same fixture design in several tests without necessarily sharing the same fixture instance. ■ 使い回せるような、Standardなテストフィクスチャを設計しような! ● cf. Minimal Fixture at XUnitPatterns.com ○ > A key part of understanding a test is understanding the test fixture and how it influences the expected outcome of the test. Tests are much easier to understand if the fixture is small and simple. ■ 余計な要素を削ることでテストフィクスチャの内容を把握するぞ! ● これらの戦略も決定論的にテストフィクスチャを整理するための戦略 高速化のためのテストフィクスチャ戦略

Slide 45

Slide 45 text

● ここまでを整理すると ○ 実行速度を求めるならば事前にセットアップしておけるShared Fixtureが 効果的なのはわかる ■ でも決定論的ではなく多様な前提条件を表現する必要がある ■ テストフィクスチャならばFresh Fixtureで用意するしかないのでは? ● 要はトレードオフなのだと思う ○ 決定論的なテストフィクスチャを”表現”するのそんなむずかしくない ■ 内容を調整するのは大変だが、フィクスチャが洗練され高速化も期待 ○ 多様なパターンがあるテストフィクスチャ群を表現するのが難しいので、 それが柔軟に表現できる"表現力があると便利!ってことじゃない?? なんかたくさんの用語が出てきたし、整理するよ

Slide 46

Slide 46 text

CakePHP Fixture Factoriesの登場 ようやく本題

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

● vierge-noire/cakephp-fixture-factories ○ CakePHPで複雑なテストフィクスチャを柔軟に扱うときに便利ってわけ ○ これのおかげで、Laravelでは既に実現されてるModel FactoriesをCakePHP で使えるようになった🙌 ここでCakePHP Fixture Factoriesの登場だ!!

Slide 49

Slide 49 text

● 基本的に class UserFactory extends BaseFactory というかんじで読み込む 具体的にはこんな感じに使えるよん setDefaultData(function (Generator $faker) { return [ 'screen_name' => $faker->userName(), 'name' => $faker->name(), 'icon_url' => $faker->imageUrl(128, 128), ]; }); } }

Slide 50

Slide 50 text

● UserFactory::make() でModel Factoryがセットアップされる ○ この時点では class UserFactory に定義されてる protected function setDefaultTemplate(): void の中で定義されているデータをセットアップす るだけ 具体的にはこんな感じに使えるよん public function test_getUserById(): void { // given $userFactory = UserFactory::make();

Slide 51

Slide 51 text

● $user = UserFactory::make()->getEntity() でエンティティが出てくる ○ UserFactory::make()->getEntities() で配列に入ったエンティティ群が出て くる 具体的にはこんな感じに使えるよん public function test_getUserById(): void { // given $users = UserFactory::make(2)->getEntities(); $client = (new UsersClient())->setData($users);

Slide 52

Slide 52 text

● UserFactory::make($data) でプロパティに値を渡せます ○ 無名関数も渡せます 具体的にはこんな感じに使えるよん public function test_getUserById(): void { // given $takoba = UserFactory::make(['name' => 'takoba'])->persist(); $somebody = UserFactory::make(function (UserFactory $factory, Faker\Generator $faker) { return ['screen_name' => $faker->userName()]; }, 3)->persist();

Slide 53

Slide 53 text

public function test_getUserById(): void { // given $users = UserFactory::make(2)->persist(); // 以下は同義 $fixture = [new User(['name' => 'John']), new User(['name' => 'Paul'])]; $UsersTable = TableRegistry::getTableLocator()->get('Users'); $users = $UsersTable->saveManyOrFail($fixture); ● CakePHPだと UserFactory::make()->persist() とかってやると cakephp/orm の class Cake\ORM\Table で定義された class UsersTable extends Table でデータ が保存されて、 class Cake\ORM\Entity で定義されてる class User extends Entity のインスタンスがヒュッと手に入る! 具体的にはこんな感じに使えるよん

Slide 54

Slide 54 text

public function test_getUserById(): void { // given $users = UserFactory::make(2) ->with('UserAddresses', UserAddressFactory::make(3)) ->persist(); ● そして UserFactory::make()->with('UserAddresses', UserAddressFactory::make(3)) みたいなかんじで簡単にassociationsも表現で きる!!! 具体的にはこんな感じに使えるよん

Slide 55

Slide 55 text

public function test_getUserById(): void { // given $users = UserFactory::make(2) ->listeningToModelEvents(‘Model.beforeMarshal’) ->getEntity(); ● UserFactory::make()->listeningToModelEvents('Model.beforeMarshal') とする ことでModelのイベントを発火することができる ○ 基本、CakePHP Fixture Factories側で一通りoffにしているので明示的に呼 び出す必要がある 具体的にはこんな感じに使えるよん

Slide 56

Slide 56 text

public function test_getUserById(): void { // given $users = UserFactory::make(2) ->listeningToBehaviors(‘Sluggable’) ->getEntity(); ● UserFactory::make()->listeningToBehaviors('Sluggable') とすることでModelの Behaviorを呼び出すことができる ○ CakePHP Fixture Factories側ではTimestampBehaviorだけ有効にしてある ○ 'TestFixtureGlobalBehaviors' というConfigに有効にしたいBehaviorを設定 できる 具体的にはこんな感じに使えるよん

Slide 57

Slide 57 text

(ようやくLaravelに追いついたね!やったね) 🙌

Slide 58

Slide 58 text

● CakePHP3以上をサポートしてる ○ 基本的にCakePHP3で導入された cakephp/orm のTableクラスとEntityクラ スを前提に実装されてる ○ CakePHP2はがんばったら使えるかもだけど恩恵はあまり受けられないか な... ■ フレームワークの前提が namespaced じゃないので、どう読み込むか は課題だけどたぶん使えそうではあるけど公式にはサポートされてな いし、そもそもEntityの恩恵は得られない サポート範囲

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

● vierge-noire/test-database-cleaner を使ってデータベースをcleanupするライ ブラリも提供してたりはする ○ これはLaravelでも他のアプリでも使えて、なおかつ速いぜ!という売り ○ ちなみにCakePHPアプリだと cakephp/migrationを用いる方法 でスキーマ を作成して FixtureStrategyによるrefleshをする方法 が推奨されてる ● データを生成したりデータベースへ登録するにはcakephp/ormに準拠したTable クラスとEntityクラスが必要になる ○ cf. cakephp-fixture-factories/no_cake_associations.md at main · vierge-noire/cakephp-fixture-factories ○ 将来的には拡張ができるようになるかもしれないけど、現状は一通り EventCompilerとかを書かないと差し替えられないね... ほんとにCakePHPに関わらず使えるの...?

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

● 特にissueとかないけど、なんとなくnon-CakePHP Applicationにも開放してい きたい気持ちはありそう...? ○ とはいえ、特に言及は見つけられなかった ● cakephp/orm 便利だから使ってみてよ!(そうじゃないけど便利なのは便利) ○ cf. データベースアクセス & ORM - CakePHP 4.x Strawberry Cookbook 使えないんじゃん💢

Slide 64

Slide 64 text

● CakePHP 4.3.0から、 class Cake\TestSuite\Fixture\TestFixture をベースにし たテストフィクスチャのライフサイクル戦略を設定することができるように なった ● 以下のようなクラスがプリセットで用意されている ● class TruncateStrategy implements FixtureStrategyInterface ○ テストケース実行後にテーブルをTRUNCATEする ● class TransactionStrategy implements FixtureStrategyInterface ○ BEGIN; でトランザクション張って、 tearDown() 時に ROLLBACK; ● 先ほど紹介したテストフィクスチャの戦略を実現できる...? FYI: CakePHPのフィクスチャステートマネージャ

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

まとめ あとスライド5枚!

Slide 67

Slide 67 text

● テストフィクスチャ、結局は決定論的なものも複雑で動的なものもバランスよ く使っていく必要があるよ! ● その”複雑で動的なもの(≒Fresh Fixture)”を簡単に表現できるのが vierge-noire/cakephp-fixture-factories ってわけ! ● CakePHPアプリケーションには容易に導入できるけど、まだまだ cakephp/orm に依存してるので今後に期待だ! ???「3行で頼んだ」

Slide 68

Slide 68 text

紹介した概念をバランスよく使って、 メンテナブルでファストなテストスイートを運用していこうな!!!

Slide 69

Slide 69 text

終 制作・著作

Slide 70

Slide 70 text

● Test fixture - Wikipedia ● Rubyのテスティングフレームワークの歴史(2014年版) - 2014-11-06 - クク ログ ● test-unit - Ruby用単体テストフレームワーク ● index at XUnitPatterns.com ○ Inline Setup at XUnitPatterns.com ○ Delegated Setup at XUnitPatterns.com ○ Implicit Setup at XUnitPatterns.com ○ Shared Fixture at XUnitPatterns.com ○ Fresh Fixture at XUnitPatterns.com 参考文献

Slide 71

Slide 71 text

● Amazon.co.jp: xUnit Test Patterns: Refactoring Test Code (Addison-Wesley Signature Series (Fowler)) (English Edition) 電子書籍: Meszaros, Gerard: 洋書 ● abseil / Software Engineering at Google ● Software Design 2022年3月号|技術評論社 ● vierge-noire/cakephp-fixture-factories: CakePHP Fixture Factories ● CakeFest 2020 - Fixture Factories Plugin - Juan Pablo Ramirez - YouTube ● データベースアクセス & ORM - CakePHP 4.x Strawberry Cookbook ● 現在時刻が関わるユニットテストから、テスト容易性設計を学ぶ - t-wadaのブ ログ ● Google Slidesにソースコードを貼り付ける - zenn.dev ○ 参考文献というよりSpecial Thanks 参考文献