Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[2021/12/16]テストコードのないレガシーアプリケーションとの向き合い方

tosite
December 16, 2021

 [2021/12/16]テストコードのないレガシーアプリケーションとの向き合い方

ソフトウェアテストシンポジウム 2021 九州
https://www.jasst.jp/symposium/jasst21kyushu.html

tosite

December 16, 2021
Tweet

More Decks by tosite

Other Decks in Programming

Transcript

  1. テストコードのない

    レガシーアプリケーション

    との向き合い方

    in JaSST'21 Kyushu

    2021-12-18 Sat


    View full-size slide

  2. はじめまして

    \の方もそうでない方も/ 


    View full-size slide

  3. はじめまして

    3


    View full-size slide

  4. はじめまして

    4

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


    View full-size slide

  5. はい

    \会社紹介/


    View full-size slide

  6. はじめまして

    6


    View full-size slide

  7. はじめまして

    7

    ドメイン・レンタルサーバー

    ご用命の際はぜひ弊社サービスを

    よろしくお願いいたします!


    View full-size slide

  8. はじめまして

    8


    View full-size slide

  9. はじめまして

    9

    コミュニティでステッカーやファングッズ・

    ノベルティなどを作成したい場合は

    ご利用ください!


    View full-size slide

  10. ここから本題

    \いい仕事した/


    View full-size slide

  11. 突然ですが皆さん

    テストは

    書いていますか?

    \かの有名な方もこうおっしゃっていますよね/ 


    View full-size slide

  12. 突然ですが皆さん

    テストは

    書いていますか?

    著者: @mty_mno 「テスターちゃん番外編『ヤツが来る!!』の巻&メイキングオブジョジョ風の絵 」


    View full-size slide

  13. と言っても

    テストが不十分な

    アプリケーションが

    あるのも現実…

    \理想と現実ってやつ/ 


    View full-size slide

  14. 前提

    14

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


    View full-size slide

  15. 前提

    15

    歴史の話をしよう


    View full-size slide

  16. 前提

    16


    View full-size slide

  17. 前提

    17

    ホスティング事業部のサービスは

    20年もの長い歴史があります


    今も一部リポジトリでは

    次のようなレガシーな構成を

    目にすることがあります

    \今回担当したのはムームードメインのPHPで書かれたアプリケーションコードでした/ 


    View full-size slide

  18. 前提

    18

    レガシーなアプリケーションではまれに

    次のような構成を目にすることがあります

    \ちなみに案件はPHPでした/ 


    View full-size slide

  19. 前提

    19

    コントローラーロジック(数百行) 

    関数群(数百〜数千行) 

    ビューファイル(数百〜数千行) 


    View full-size slide

  20. 前提

    20

    コントローラーロジック(数百行) 

    関数群(数百〜数千行) 

    ビューファイル(数百〜数千行) 

    1ファイルで全ての処理を実行している


    コントローラー・ビュー・

    ビジネスロジックが密結合している

    ためテストが難しい


    当然、既存のテストコードは

    ほとんどない状態


    View full-size slide

  21. 前提

    21

    1ファイル(数千行)

    コントローラーロジック(数百行) 

    関数群(数百〜数千行) 

    ビューファイル(数百〜数千行) 

    ・1ファイルで全ての処理を実行

    ・コントローラー・ビュー・

     ビジネスロジックが密結合

     しているためテストが難しい

    ・当然、既存のテストコードは

     ほとんどない状態


    View full-size slide

  22. 前提

    22

    リファクタリングしたいが 

    テストコードも仕様書もなく 

    「動いているコードが正しい」

    という状態


    View full-size slide

  23. 前提

    23

    要件は

    振る舞いを変えつつ

    変更後の挙動を担保した状態で

    かつバグが混入しないこと

    というもの


    View full-size slide

  24. 前提

    24

    つまり

    リアーキテクティング

    した上で振る舞いを変える

    必要があるということ


    View full-size slide

  25. 前提

    25

    リアーキテクティングするための

    テストがない


    コードが密結合しているため

    ユニットテストが書けない

    \鶏卵問題ですね/

    View full-size slide

  26. 前提

    26

    その状況でいきなり

    振る舞いを変えるのは

    自殺行為


    View full-size slide

  27. 前提

    27

    リファクタリングするためのテストがなく、

    テストを書こうにも密結合しているため

    そのままではテストできない


    とは言えいきなりリファクタリングするのも

    エンバグする危険性が極めて高い

    \鶏卵問題ですね/ 


    View full-size slide

  28. 皆さんなら

    どうしますか?

    \一緒に考えてみましょう/ 


    View full-size slide

  29. 私は次のような

    アプローチを取りました

    \一例ですが/


    View full-size slide

  30. フェーズ1. 

    ロジックの分離

    \ローマの道も一歩から/ 


    View full-size slide

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

    31


    View full-size slide

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

    32

    これを


    View full-size slide

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

    33

    index.php

    functions.php


    View full-size slide

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

    34

    こう


    View full-size slide

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

    35

    まずはファイルから

    ビジネスロジックを

    切り出すだけの作業

    を行った

    😅

    View full-size slide

  36. フェーズ2. 

    既存の関数に対して

    テストを記述

    \リファクタリングらしくなってきました/ 


    View full-size slide

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

    37


    View full-size slide

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

    38

    既存の仕様を満たす 

    テストケースを記載


    View full-size slide

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

    39

    ファイルを分割したので 

    テストが書ける!!

    😃

    View full-size slide

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

    40

    とは言え全ての関数にテストを 

    追加する工数はなかったので 

    リアーキテクティング対象

    のみに留めた


    View full-size slide

  41. フェーズ3. 

    リアーキテクティング

    \テストがあるので安全だね/ 


    View full-size slide

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

    42


    View full-size slide

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

    43

    気になる部分を

    リファクタ


    View full-size slide

  44. フェーズ4. 

    落ちるテストを記述

    \赤より始めよ/


    View full-size slide

  45. フェーズ3. 落ちるテストを記述

    45

    修正する関数のテストケース 

    既存の仕様を満たすテスト郡 

    リファクタリング後に 

    仕様を満たすようになるテスト郡 

    リファクタリング前にレッドにな
    ることを確認しておく
    リファクタリング後は
    グリーンになることを確認
    することで安全に仕様を
    変えることができる
    脆弱性が混入されていないことを 

    確認するテスト郡


    View full-size slide

  46. フェーズ4. 落ちるテストを記述

    46

    振る舞い変更前 => レッド


    振る舞い変更後 => グリーン


    View full-size slide

  47. フェーズ4. 落ちるテストを記述

    47

    「既存仕様が壊れていないこと」は

    現在の仕様を満たすテストコードから確認できる 


    「新規仕様が実装されたこと」は

    落ちるテストが通ることで確認できる 


    View full-size slide

  48. フェーズ5. 

    振る舞いを変更

    \さあ、コーディングの時間だ!/ 


    View full-size slide

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

    49

    ここまで来たら安心安全に

    振る舞いを変更できる

    ようになっている


    View full-size slide

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

    50


    View full-size slide

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

    51

    フェーズ3で記述した 

    落ちるテストが

    通るように修正

    したら実装完了!


    View full-size slide

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

    52

    全てグリーンで通過! 


    View full-size slide

  53. メリット

    \こんないいことがあったよ/ 


    View full-size slide

  54. メリット1.

    View full-size slide

  55. メリット

    55

    テストがない世界からの脱却!


    今後機能追加や改修をやるとなった 

    ときの開発基盤が整った 


    View full-size slide

  56. メリット2.

    View full-size slide

  57. メリット

    57

    コードベースだけでなく 

    テストケースベースで

    レビューできる

    ので安心感があった 


    View full-size slide

  58. メリット

    58

    特に一部関数には

    正規表現が使用されており

    修正前と後で目grepで挙動を 

    担保するのはつらぽよだった 


    修正後の挙動を

    テストケースという仕様書

    にできた


    View full-size slide

  59. メリット3.

    View full-size slide

  60. メリット

    60

    関数群を切り出すことによって 

    スコープが明確になった

    関数がある


    副次的にその関数の 

    リファクタを推し進められた


    View full-size slide

  61. まとめ

    \もうこんな時間/


    View full-size slide

  62. レガシーな肥大化した

    アプリケーションを

    リファクタするのは

    難しい

    View full-size slide

  63. 特にテストコードが

    ない場合はなおさら

    View full-size slide

  64. でもアプローチを

    工夫すれば必ず安全に

    やり遂げられる

    View full-size slide

  65. 皆さんもテストを書いて

    安全にリファクタして

    いきましょう!


    View full-size slide

  66. ご清聴ありがとう

    ございました


    View full-size slide