Slide 1

Slide 1 text

テストコードのない
 レガシーアプリケーション
 との向き合い方
 in JaSST'21 Kyushu
 2021-12-18 Sat


Slide 2

Slide 2 text

はじめまして
 \の方もそうでない方も/ 


Slide 3

Slide 3 text

はじめまして
 3


Slide 4

Slide 4 text

はじめまして
 4
 GMOペパボ株式会社 ホスティング事業部 バックエンドエンジニア 趣味: インターネットJK・ キャンプ @tosite / まおちゃ / 手島 尚人


Slide 5

Slide 5 text

はい
 \会社紹介/


Slide 6

Slide 6 text

はじめまして
 6


Slide 7

Slide 7 text

はじめまして
 7
 ドメイン・レンタルサーバー
 ご用命の際はぜひ弊社サービスを
 よろしくお願いいたします!


Slide 8

Slide 8 text

はじめまして
 8


Slide 9

Slide 9 text

はじめまして
 9
 コミュニティでステッカーやファングッズ・
 ノベルティなどを作成したい場合は
 ご利用ください!


Slide 10

Slide 10 text

ここから本題
 \いい仕事した/


Slide 11

Slide 11 text

突然ですが皆さん
 テストは
 書いていますか?
 \かの有名な方もこうおっしゃっていますよね/ 


Slide 12

Slide 12 text

突然ですが皆さん
 テストは
 書いていますか?
 著者: @mty_mno 「テスターちゃん番外編『ヤツが来る!!』の巻&メイキングオブジョジョ風の絵 」


Slide 13

Slide 13 text

と言っても
 テストが不十分な
 アプリケーションが
 あるのも現実…
 \理想と現実ってやつ/ 


Slide 14

Slide 14 text

前提
 14
 今年のテーマは「歴史から学ぶ」


Slide 15

Slide 15 text

前提
 15
 歴史の話をしよう


Slide 16

Slide 16 text

前提
 16


Slide 17

Slide 17 text

前提
 17
 ホスティング事業部のサービスは
 20年もの長い歴史があります
 
 今も一部リポジトリでは
 次のようなレガシーな構成を
 目にすることがあります
 \今回担当したのはムームードメインのPHPで書かれたアプリケーションコードでした/ 


Slide 18

Slide 18 text

前提
 18
 レガシーなアプリケーションではまれに
 次のような構成を目にすることがあります
 \ちなみに案件はPHPでした/ 


Slide 19

Slide 19 text

前提
 19
 コントローラーロジック(数百行) 
 関数群(数百〜数千行) 
 ビューファイル(数百〜数千行) 


Slide 20

Slide 20 text

前提
 20
 コントローラーロジック(数百行) 
 関数群(数百〜数千行) 
 ビューファイル(数百〜数千行) 
 1ファイルで全ての処理を実行している
 
 コントローラー・ビュー・
 ビジネスロジックが密結合している
 ためテストが難しい
 
 当然、既存のテストコードは
 ほとんどない状態


Slide 21

Slide 21 text

前提
 21
 1ファイル(数千行)
 コントローラーロジック(数百行) 
 関数群(数百〜数千行) 
 ビューファイル(数百〜数千行) 
 ・1ファイルで全ての処理を実行
 ・コントローラー・ビュー・
  ビジネスロジックが密結合
  しているためテストが難しい
 ・当然、既存のテストコードは
  ほとんどない状態


Slide 22

Slide 22 text

前提
 22
 リファクタリングしたいが 
 テストコードも仕様書もなく 
 「動いているコードが正しい」
 という状態


Slide 23

Slide 23 text

前提
 23
 要件は
 振る舞いを変えつつ
 変更後の挙動を担保した状態で
 かつバグが混入しないこと
 というもの


Slide 24

Slide 24 text

前提
 24
 つまり
 リアーキテクティング
 した上で振る舞いを変える
 必要があるということ


Slide 25

Slide 25 text

前提
 25
 リアーキテクティングするための
 テストがない
 
 コードが密結合しているため
 ユニットテストが書けない
 \鶏卵問題ですね/ 


Slide 26

Slide 26 text

前提
 26
 その状況でいきなり
 振る舞いを変えるのは
 自殺行為


Slide 27

Slide 27 text

前提
 27
 リファクタリングするためのテストがなく、
 テストを書こうにも密結合しているため
 そのままではテストできない
 
 とは言えいきなりリファクタリングするのも
 エンバグする危険性が極めて高い
 \鶏卵問題ですね/ 


Slide 28

Slide 28 text

皆さんなら
 どうしますか?
 \一緒に考えてみましょう/ 


Slide 29

Slide 29 text

私は次のような
 アプローチを取りました
 \一例ですが/


Slide 30

Slide 30 text

フェーズ1. 
 ロジックの分離
 \ローマの道も一歩から/ 


Slide 31

Slide 31 text

フェーズ1. ロジックの分離
 31


Slide 32

Slide 32 text

フェーズ1. ロジックの分離
 32
 これを


Slide 33

Slide 33 text

フェーズ1. ロジックの分離
 33
 index.php
 functions.php


Slide 34

Slide 34 text

フェーズ1. ロジックの分離
 34
 こう


Slide 35

Slide 35 text

フェーズ1. ロジックの分離
 35
 まずはファイルから
 ビジネスロジックを
 切り出すだけの作業
 を行った
 😅 


Slide 36

Slide 36 text

フェーズ2. 
 既存の関数に対して
 テストを記述
 \リファクタリングらしくなってきました/ 


Slide 37

Slide 37 text

フェーズ2. 既存の関数に対してテストを記述
 37


Slide 38

Slide 38 text

フェーズ2. 既存の関数に対してテストを記述
 38
 既存の仕様を満たす 
 テストケースを記載


Slide 39

Slide 39 text

フェーズ2. 既存の関数に対してテストを記述
 39
 ファイルを分割したので 
 テストが書ける!!
 😃 


Slide 40

Slide 40 text

フェーズ2. 既存の関数に対してテストを記述
 40
 とは言え全ての関数にテストを 
 追加する工数はなかったので 
 リアーキテクティング対象
 のみに留めた


Slide 41

Slide 41 text

フェーズ3. 
 リアーキテクティング
 \テストがあるので安全だね/ 


Slide 42

Slide 42 text

フェーズ3. リアーキテクティング
 42


Slide 43

Slide 43 text

フェーズ3. リアーキテクティング
 43
 気になる部分を
 リファクタ


Slide 44

Slide 44 text

フェーズ4. 
 落ちるテストを記述
 \赤より始めよ/


Slide 45

Slide 45 text

フェーズ3. 落ちるテストを記述
 45
 修正する関数のテストケース 
 既存の仕様を満たすテスト郡 
 リファクタリング後に 
 仕様を満たすようになるテスト郡 
 リファクタリング前にレッドにな ることを確認しておく リファクタリング後は グリーンになることを確認 することで安全に仕様を 変えることができる 脆弱性が混入されていないことを 
 確認するテスト郡


Slide 46

Slide 46 text

フェーズ4. 落ちるテストを記述
 46
 振る舞い変更前 => レッド
 
 振る舞い変更後 => グリーン


Slide 47

Slide 47 text

フェーズ4. 落ちるテストを記述
 47
 「既存仕様が壊れていないこと」は
 現在の仕様を満たすテストコードから確認できる 
 
 「新規仕様が実装されたこと」は
 落ちるテストが通ることで確認できる 


Slide 48

Slide 48 text

フェーズ5. 
 振る舞いを変更
 \さあ、コーディングの時間だ!/ 


Slide 49

Slide 49 text

フェーズ5. 振る舞いを変更
 49
 ここまで来たら安心安全に
 振る舞いを変更できる
 ようになっている


Slide 50

Slide 50 text

フェーズ5. 振る舞いを変更
 50


Slide 51

Slide 51 text

フェーズ5. 振る舞いを変更
 51
 フェーズ3で記述した 
 落ちるテストが
 通るように修正
 したら実装完了!


Slide 52

Slide 52 text

フェーズ5. 振る舞いを変更
 52
 全てグリーンで通過! 


Slide 53

Slide 53 text

メリット
 \こんないいことがあったよ/ 


Slide 54

Slide 54 text

メリット1. 


Slide 55

Slide 55 text

メリット
 55
 テストがない世界からの脱却!
 
 今後機能追加や改修をやるとなった 
 ときの開発基盤が整った 


Slide 56

Slide 56 text

メリット2. 


Slide 57

Slide 57 text

メリット
 57
 コードベースだけでなく 
 テストケースベースで
 レビューできる
 ので安心感があった 


Slide 58

Slide 58 text

メリット
 58
 特に一部関数には
 正規表現が使用されており
 修正前と後で目grepで挙動を 
 担保するのはつらぽよだった 
 
 修正後の挙動を
 テストケースという仕様書
 にできた


Slide 59

Slide 59 text

メリット3. 


Slide 60

Slide 60 text

メリット
 60
 関数群を切り出すことによって 
 スコープが明確になった
 関数がある
 
 副次的にその関数の 
 リファクタを推し進められた


Slide 61

Slide 61 text

まとめ
 \もうこんな時間/


Slide 62

Slide 62 text

レガシーな肥大化した
 アプリケーションを
 リファクタするのは
 難しい 


Slide 63

Slide 63 text

特にテストコードが
 ない場合はなおさら 


Slide 64

Slide 64 text

でもアプローチを
 工夫すれば必ず安全に
 やり遂げられる 


Slide 65

Slide 65 text

皆さんもテストを書いて
 安全にリファクタして
 いきましょう!


Slide 66

Slide 66 text

ご清聴ありがとう
 ございました