1
/
5

【TECH BLOG】ZOZOTOWN Androidチームにおけるコードメトリクスとビルド時間計測の取り組み

はじめに

ZOZOTOWN開発本部 ZOZOTOWNアプリ部 Android2ブロックの高橋です。

ZOZOTOWN Androidチームでは、リファクタリングやビルド速度改善の取り組みを継続的に行なっています。本記事では、それらの取り組みの効果を可視化するために導入した、コードメトリクスやビルド時間計測の方法について紹介します。

ZOZOTOWN Androidチームにおけるリファクタリングやビルド速度改善の取り組み

ZOZOTOWN Androidチームでは以前から、長いビルド時間や保守性の低いコードによって、チームの生産性が低下していることが問題となっていました。

そこで、保守性の高いコードを実現するためのリファクタリングや、ビルドの高速化に取り組んできました。しかし、それらの取り組みと並行して新機能の実装や既存機能の改修なども行なわれていたため、実際の改善度合いを把握することが難しい状況になっていました。

上記のような状況を鑑み、リファクタリングの効果・進捗とビルド時間を計測できる仕組みを検討し、導入しました。

コードメトリクスの計測

リファクタリングの効果・進捗を管理するための方法として、コードメトリクス計測の仕組みを導入しました。

メトリクス

計測するメトリクスは下記の目的に対応するものを選定しました。

  • リファクタリングの効果が高いファイルの検出
  • リファクタリングの進捗管理
  • チームのリファクタリングへの意識向上
  • 属人化しているコードの把握

コードメトリクス計測の導入目的に対応するメトリクスを検討した結果、下記のメトリクスを計測することになりました。

メトリクス               説明
Cyclomatic Complexity(循環的複雑度) メソッド単位でのコードの複雑度
LOC                  ファイルの行数
Author数                ファイルに対して変更を加えたメンバーの数

メトリクスの検討段階では、上記の他にも「構造複雑度」や「他ファイルからの被参照数」なども有効なメトリクスとして候補に挙がりました。しかし、それらのメトリクスは既存のツールでの計測が難しい、あるいはメトリクスそのものの理解が難しいなどの問題がありました。そこで、比較的スムーズに導入可能かつ理解が容易な「Cyclomatic Complexity」「LOC」「Author数」から計測を始めました。


Cyclomatic Complexity(循環的複雑度)

Cyclomatic Complexityは、メソッドの複雑度を示すメトリクスです。大まかにはif文やfor文などの分岐やループによって数値が増えます。数値の目安には決められたものはありませんが、一般的には下表のように言われています。

数値   複雑度とバグの混入リスク
〜10 シンプルな構造でバグの混入のリスクは低い
11〜20 やや複雑で中程度のバグの混入リスクがある
21〜50 複雑でバグの混入リスクが高い
51〜 テスト不可能な状態でバグの混入リスクが非常に高い

Cyclomatic Complexityを計測することで、バグの混入リスクが高いメソッドを検出できます。以上から、Cyclomatic Complexityは効果的なリファクタリングやリファクタリングの進捗管理に利用できると考え、計測対象としました。また、継続的にメトリクスを監視することで、チームのリファクタリングへの意識向上にも役立つと考えました。


LOC(ファイルのコード行数)

LOCは1ファイルあたりのコード行数を示すメトリクスです。LOCはいくつかの種類があります。

名称            説明
physical LOC(物理LOC) 空行やコメントの行数を含む、テキストファイルとしての行数
logical LOC(論理LOC) 空行やコメントの行数を含まない、実際の処理が記述されている行数

ZOZOTOWN Androidチームでは、空行やコメントを除いた実際の処理部分のリファクタリングにメトリクスを活用するため、logical LOCを計測対象のメトリクスとしました。

LOCを定期的に計測することで、削除予定となっているファイルや既に巨大になっているファイルに対する変更(追加)を把握できます。以上から、LOCはCyclomatic Complexityと同様に効果的なリファクタリングやリファクタリングの進捗管理に利用できると考え、計測対象としました。また、チームのリファクタリングへの意識向上についてもCyclomatic Complexityと同様に、継続的なメトリクスの監視によって達成できると考えました。


Author数

Author数は、ファイルに変更を加えた人数を示すメトリクスです。ZOZOTOWN Androidチームでは全てのコードの変更に対してコードレビューを実施しています。しかし、Author数が1の場合、該当ファイルを直接変更した人が1人しかおらずコードが属人化している状態である可能性が示唆されます。

Author数を計測することで、属人化したコードの内、特に重要な処理が記述されたコードの詳細をチームで共有できます。コードの属人化を解消することで、チームメンバーの仕様・実装理解が促進され、生産性の向上が期待できると考えました。Author数は、コードではなくGitのコミットログを解析して計測するため、一般的なコードメトリクスの文脈とは異なります。しかし、Author数はコードメトリクス計測の目的である「属人化しているコードの把握」に対応する指標であるため、計測することを決定しました。

計測方法

各メトリクスはそれぞれ異なるツールを使用して計測しました。いずれのツールも、継続的なメトリクス計測を目的として、GitHub ActionsのWorkflowに組み込みました。

ここでは、各メトリクスの計測方法とGitHub Actionsへの組み込みについて紹介します。


Cyclomatic Complexityの計測方法

Cyclomatic Complexityの計測には、KotlinとJavaで異なるツールを使用しました。

Java

Javaで記述されたコードのCyclomatic ComplexityはJava用の静的コード解析ツールであるcheckstyle/checkstyleを使用して計測しました。

checkstyleではCyclomatic Complexityのthreshold(許容最大値)がデフォルトでは3になっています。そこで、全てのメソッドのCyclomatic Complexityを検出するため、設定ファイルでthresholdを0に変更しました。

GitHub Actionsでcheckstyleを実行するJobは下記のようになります。


java-complexity:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v3
    - name: Setup Java
      uses: actions/setup-java@v2
      with:
        distribution: 'zulu'
        java-version: '11'
    - name: Install checkstyle
      run: curl -sSLO https://github.com/checkstyle/checkstyle/releases/download/checkstyle-10.1/checkstyle-10.1-all.jar
    - name: Run checkstyle
      run: find . -name "*.java" | xargs java -jar ./checkstyle-10.1-all.jar -f xml -c .github/checkstyle_rule.xml -o checkstyle_result.xml || true
    - name: Archive
      uses: actions/upload-artifact@v2
      with:
        name: result
        path: checkstyle_result.xml


このJobでは、checkstyleを実行し、出力結果を保存します。checkstyleは静的解析によって発見されたエラーの数がexitコードとなります。stepを正常終了させるため、ここではcheckstyleのexitコードを無視しています。出力結果はGitHub ActionsのArtifactsとして保存します。

レポートファイルは下記のようなXMLで出力されます。


<?xml version="1.0" encoding="UTF-8"?>
<checkstyle version="10.1">
<file name="/path/to/File.java">
<error line="18" column="5" severity="error" message="Cyclomatic Complexity is 1 (max allowed is 0)." source="com.puppycrawl.tools.checkstyle.checks.metrics.CyclomaticComplexityCheck"/>
<error line="25" column="5" severity="error" message="Cyclomatic Complexity is 1 (max allowed is 0)." source="com.puppycrawl.tools.checkstyle.checks.metrics.CyclomaticComplexityCheck"/>
</file>
...
</checkstyle>


fileタグのnameerrorタグのlinecolumnmessageを見ることで、計測対象のファイルに含まれるメソッドのCyclomatic Complexityを確認できます。


Kotlin

Kotlinで記述されたコードのCyclomatic Complexityは、Kotlin用の静的コード解析ツールであるdetekt/detektというツールを使用して計測しました。detektはコマンドラインツールやGradle Pluginとして利用できます。

detektではCyclomatic Complexityのthresholdがデフォルトでは15になっています。そこで、checkstyleと同様に全てのメソッドのCyclomatic Complexityを検出するため、設定ファイルでthresholdを0に変更しました。

続きはこちら

株式会社ZOZO's job postings
1 Likes
1 Likes

Weekly ranking

Show other rankings
Invitation from 株式会社ZOZO
If this story triggered your interest, have a chat with the team?