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

到達可能性チェッカーを品質改善に活用する/use-ReachableChecker-for-frequent-refactoring

 到達可能性チェッカーを品質改善に活用する/use-ReachableChecker-for-frequent-refactoring

2023-04-16 freee技術の日 https://freee.connpass.com/event/274961/

t-mario-y

April 16, 2023
Tweet

More Decks by t-mario-y

Other Decks in Programming

Transcript

  1.   安⼼してリファクタリングしたい • どうやったら安⼼できるか ◦ ⾼頻度⼩変更で ◦ ⾃動テストとセットで ◦ 監視しながら

    • それでも怖い時がある ◦ 本番でしか起きないedge case ◦ 未使⽤かどうかが確信を持てないコード
  2.   到達可能性チェッカー module ReachableChecker class << self def execute(message: nil)

    raise UnexpectedReachedError.new(message) rescue UnexpectedReachedError => error raise if Rails.env.development? || Rails.env.test? ErrorReportService.report(error, :warning) end end class UnexpectedReachedError < StandardError end end
  3.   活⽤例:シンプルな未使⽤コード検知 def calculate(params) case params[:type] when 'new_pattern' NewModule.calculate when

    'old_deprecated_pattern' ReachableChecker.execute(message: '古いパラメータで処理します。') OldDeprecatedModule.calculate else raise '想定しないパラメータです。' end end
  4.   活⽤例:新規コードの後⽅互換性を本番環境で確認 def want_to_refactor_logic attendance_records = AttendanceRecord.where(date: dates) old_result =

    OldInnerProcess.execute(attendance_records) new_result = NewInnerProcess.execute(attendance_records) old_result .filter { |k, v| v != new_result[k] } .tap do |diff_hash| unless diff_hash.empty? ReachableChecker.execute(message: "#{diff_hash.keys}") end end old_result # 旧ロジックで処理を継続 end
  5.   前提2:必要⼗分な⾃動テストが書かれている • Code Coverage ◦ 到達可能性チェッカーはカバレッジ未通過になる ▪ 到達するとテスト失敗するため ◦

    ⾃動テストが担保する典型的かつ重要なケースをクリアしている ◦ そう確信を持てる程に既存のテストスイートが充実している ◦ outdatedなテストは勇気を持って書き直す 
  6.   前提3:開発環境のエラーが共有されている • 私/あなた が追加した到達可能性チェッカーで、あなた/私 がraiseした ◦ tail logしてgit blameして「rails

    serverでこういうエラーが出て〜」 ◦ 気楽に共有できている & 機敏に対応できている ◦ 本番環境より前に開発者が気付けてよかった