初めに
こんにちは、Androidエンジニアの冨田です。今回はAndroidのソースコードのリファクタリングをGithub Copilot(Enterprise版)を活用しながら進めていきます。
まだ少しJavaをKotlin化する部分が残っているため、それを例にしていきたいと思います。
この記事は、株式会社asken (あすけん) Advent Calendar 2024 の1日目の記事です。
やらないこと
アーキテクチャの変更
対象ファイル選定
ファイル間の参照関係を考慮し、被参照の数より参照数を優先しました。参照数が少ない方を優先して対象とする方法です。例えばファイルAがファイルBを参照している場合(A→B)、Bからリファクタリングを開始します。
Bのリファクタリング時に単体テスト(UT)を作成し、動作を保証。こうすることでその後Aをリファクタリングする際は、Bの挙動を気にせずAに集中できます。
Kotlin化の前に
まずUTを作成、補強します。以下の内容のファイルがあったとします。
※内容は仮で、あすけんの仕様とは無関係です
public class CalcUtil { public static double calculateBMI(double weight, double height) { if (height == 0) { return 0; } return weight / (height * height); } public static boolean validBMI(double bmi) { return !(bmi < 5); } }
この関数に対して、GitHub Copilotを用いてテストを生成します。
Github Copilotはコードを自動生成するだけでなく、テストの作成も支援してくれます。例えば、次のような入力を行うだけでテストコードを提案してくれます。
Kotlin化限定のTipsですが、そのまま生成するとJavaファイルでUTが出力されてしまうので、Kotlinを指定する必要があります。
/tests kotlinで出力
それで生成されたUTが以下です。
import org.junit.Assert.* import org.junit.Test class CalcUtilTest { @Test fun calculateBMI_returnsCorrectValue() { val weight = 70.0 val height = 1.75 val expectedBMI = 22.86 val actualBMI = CalcUtil.calculateBMI(weight, height) assertEquals(expectedBMI, actualBMI, 0.01) } @Test fun calculateBMI_handlesZeroHeight() { val weight = 70.0 val height = 0.0 val actualBMI = CalcUtil.calculateBMI(weight, height) assertEquals(0.0, actualBMI, 0.0) } @Test fun validBMI_returnsTrueForValidBMI() { val bmi = 22.0 assertTrue(CalcUtil.validBMI(bmi)) } @Test fun validBMI_returnsFalseForLowBMI() { val bmi = 4.0 assertFalse(CalcUtil.validBMI(bmi)) } @Test fun validBMI_returnsTrueForBoundaryValue() { val bmi = 5.0 assertTrue(CalcUtil.validBMI(bmi)) } }
場合によっては調整が必要なケースもありますが、閾値も加味してUTを生成してくれます。
※今回は閾値を小数点以下まで加味したものに置き換えるべきかと思います。
このようにUTで動作を保証した状態からリファクタリングを進めていきます。
補助手段
コードが複雑で理解が難しい場合、Github Copilotに説明コメントを生成してもらうのも効果的です。また、単体テストだけでカバーできない部分があれば、結合テストなどの後続工程で検証する計画を立てましょう。
/doc 日本語で
public class CalcUtil { /** * 体重と身長に基づいてBMI(ボディマス指数)を計算します。 * * @param weight 体重(キログラム) * @param height 身長(メートル) * @return 計算されたBMI、身長が0の場合は0を返します */ public static double calculateBMI(double weight, double height) { if (height == 0) { return 0; } return weight / (height * height); } /** * 指定されたBMIが有効かどうかをチェックします。 * * @param bmi チェックするボディマス指数 * @return BMIが5以上の場合はtrue、それ以外の場合はfalse */ public static boolean validBMI(double bmi) { return !(bmi < 5); } }
Kotlin化
Android StudioのKotlin変換機能を用いてファイルをKotlin化します。
ファイル右クリックから「Convert Java File to Kotlin File」で変換します。
object CalcUtil { fun calculateBMI(weight: Double, height: Double): Double { if (height == 0.0) { return 0.0 } return weight / (height * height) } fun validBMI(bmi: Double): Boolean { return !(bmi < 5) } }
その後、作成済みのUTおよび必要に応じて結合テストを実行し、問題がなければ作業は完了です。
まとめ
今回は、GitHub Copilotを活用したリファクタリングの初歩的な手法を紹介しました。このアプローチはシンプルながら効果的で、手作業でのテスト記述やリファクタリングに比べ、大幅に効率を向上させることが可能です。ぜひ、このプロセスを参考にして、日々の開発にGithub Copilotを活用してみてください!
askenでは新しい仲間を募集しています!
カジュアル面談などを通して是非お話しませんか?
お気軽にご連絡ください!