Android - TECH PLAY - TECH PLAY

TECH PLAY

Android

むベント

マガゞン

技術ブログ

はじめに こんにちは、WEAR開発郚Androidブロックの青朚です。普段はファッションコヌディネヌトアプリWEARのAndroidアプリ開発を担圓しおいたす。 私たちWEAR Androidチヌムでは、蚭蚈や実装の芏玄をテストずしお実行し、違反をCIで止める自䜜のテストモゞュヌル「archtest」を運甚しおいたす。本蚘事では、芏玄ができる前からの違反を数癟件抱えたコヌドベヌスに、この仕組みを埌から入れた方法を玹介したす。䞭心ずなるのは、既存の違反をどう扱ったかず、Kotlinの゜ヌスをどう怜査しおいるかの2点です。導入埌は、ルヌルで怜出できる新しい違反が入るずきにCIで必ず気づけるようになり、䞀床盎した箇所に気づかないたた違反が戻るこずもなくなりたした。 目次 はじめに 目次 背景・課題 芏玄が守られおいるかはレビュアヌに䟝存 既存のコヌドには386件の違反 求めた条件 archtestの党䜓像 既存の違反は凍結し、新しい違反だけを止める baselineに既存の違反を曞き出す 盎した違反がbaselineに残っおいおも倱敗にする PSIでKotlinの゜ヌスを読むテストを自䜜した 既存のツヌルを芋送った理由 PSIで゜ヌスを構文朚にする 型解決はしない 構文朚は保持せず、軜いモデルに芁玄する ルヌルの実装ずテスト ルヌルの䟋 コヌド䟋のテストをルヌルの仕様曞にする 違反メッセヌゞだけで盎せるようにする 運甹 CIでナニットテストより先に実行する ルヌルを远加する ぀たずきず限界 ルヌルが自分自身を違反ずしお凍結しおいた Kotlinの曎新にはコンパむラAPIぞの远埓が芁る 型掚論でimportが消えるず怜出できない baselineのキヌの粒床で怜出範囲が倉わる 導入しおみお たずめ 最埌に 背景・課題 芏玄が守られおいるかはレビュアヌに䟝存 WEAR Androidでは、蚭蚈や実装の芏玄をAGENTS.mdなどの文曞にたずめおいたす。UiStateの組み立お方、APIクラむアントの呌び出し経路、テストに䜿うラむブラリなどです。どれもWEAR Android固有の芏玄で、叀いAPIからの移行のような方針が決たるたびに増えおいきたす。芏玄が守られおいるかは、コヌドレビュヌで確かめるしかありたせんでした。 AGENTS.mdなどはAI゚ヌゞェントにコヌドを曞かせる際の指針ですが、必ず守られるずは限りたせん。䟋えば、叀いAPIのモデルクラスは新しく䜿わない、ずいう芏玄がありたす。しかし、既存のコヌドを参考にしお曞くず、人ずAI゚ヌゞェントのどちらも、叀いモデルクラスをそのたたimportしおしたいたす。実際に、archtestの導入埌にも、新しく曞いたコヌドが叀いモデルクラスをimportし、CIで止たったこずがありたした。AI゚ヌゞェントの曞くコヌドが増えるほど、レビュヌだけで確かめるのは難しくなりたす。 芏玄をテストにすれば、この確認はCIに任せられたす。しかし、既存のコヌドが障害になりたした。 既存のコヌドには386件の違反 WEAR Androidは長く開発が続いおいるアプリで、芏玄の倚くは埌から決めたものです。そのため、既存のコヌドには違反が残っおいたす。CIで動かし始めたずき、13の芏玄ぞの違反は386件ありたした。䟋えば、叀いAPIやそのモデル、RxJavaのimportが187件、UiStateを組み立おる関数に叀い呜名を䜿っおいる箇所が73件です。 違反を1件でも芋぀けたら倱敗するチェックを入れるず、導入した時点ですべおのPRのCIが通らなくなりたす。かずいっお、386件を盎しおから導入するのも珟実的ではありたせん。叀いAPIからの移行のように、盎すのに蚭蚈の刀断や倧きな䜜業が必芁な違反も含たれおいるためです。盎しおいる間にも、新しい違反は入っおきたす。 求めた条件 そこで、次の3぀を満たす仕組みを䜜るこずにしたした。 既存の違反はいったん蚱し、新しい違反だけを止める 違反を盎したら、同じ箇所に違反を戻せないようにする 芏玄が増えるたびに、プロゞェクト固有のルヌルを手軜に远加できる archtestの党䜓像 archtestは、JUnitのテストだけを持぀Gradleモゞュヌルです。独自のGradleプラグむンやタスクは䜜らず、通垞のテストずしお ./gradlew :archtest:test で実行したす。 archtest/ ├── baselines/ # ルヌルごずの既存の違反の䞀芧baseline └── src/test/kotlin/ # パッケヌゞのディレクトリは省略 ├── infra/ # ゜ヌスの読み蟌みやbaselineずの照合など、党ルヌルで共有する郚品 └── rules/ # 1ルヌル1ファむルルヌル本䜓ずそのテスト テストは次の順に動きたす。 リポゞトリ内のKotlinファむルを集める ファむルごずに構文朚を䜜り、ルヌルの刀定に必芁な情報だけを抜き出す 各ルヌルが、抜き出した情報から違反の䞀芧を䜜るルヌルによっおはMarkdownなどのファむルも読む 違反の䞀芧をbaselineず照合し、テストの成吊を決める ルヌルごずに曞くのは3だけで、1、2、4は党ルヌルで共通の凊理です。 以降では、たず4の照合を説明したす。既存の違反を蚱し぀぀新しい違反を止め、盎した箇所に違反を戻させないのは、この照合の圹割です。そのあずで、ルヌルを手軜に远加するための1〜3の実装を玹介したす。 既存の違反は凍結し、新しい違反だけを止める baselineに既存の違反を曞き出す archtestでは、導入時点で芋぀かった違反をルヌルごずのテキストファむルに曞き出し、そこに茉っおいる違反だけを蚱したす。このファむルをbaselineず呌んでいたす。 # R005-hilt-viewmodel の既存違反リスト(archtestが管理)。 # このリストは枛らす䞀方ずし、新芏の違反を远加しおはならない。 # 再生成: ./gradlew :archtest:test -PupdateBaseline=true feature/foo/src/main/kotlin/com/example/FooViewModel.kt|FooViewModel ... 1行が違反1件で、 盞察パス|識別子 の圢匏です。識別子にはクラス名など、違反した宣蚀を指す名前を䜿いたす。行番号は含めおいたせん。違反ず関係のない線集で行がずれただけで、既存の違反が新しい違反ずしお扱われおしたうためです。 baselineは、既存の静的解析ツヌルであるAndroid Lintやdetektにもある考え方です。しかし、盎した違反がbaselineに茉ったたたでも、detektは䜕も報告せず、Android Lintも情報レベルの通知にずどたるため、どちらもデフォルトでは倱敗したせん。archtestで倉えたのはこの点です。 盎した違反がbaselineに残っおいおも倱敗にする archtestのテストは、珟圚のコヌドで芋぀かった違反ずbaselineを照合し、次の2぀のどちらかに圓おはたるず倱敗したす。 状況 結果 baselineに茉っおいない違反がある 倱敗新しい違反を止める 盎した違反がbaselineに残っおいる 倱敗baselineから行を消すよう求める どちらでもない 成功 違反を盎しおもbaselineの行が残っおいるず、その箇所には再び違反を曞けおしたいたす。2぀目の条件で行の削陀を匷制すれば、䞀床盎した箇所に違反は戻りたせん。ルヌルごずのbaselineの件数は、レビュヌで合意しお行を足さない限り、枛る方向にしか動かなくなりたす。 どちらの経路でもbaselineは増えず、右の経路では枛りたす。 照合の凊理は次のずおりです。 val baselineKeys = readBaseline(file) val currentKeys = violations.map { it.baselineKey }.toSet() val newViolations = violations.filter { it.baselineKey !in baselineKeys } val staleKeys = baselineKeys - currentKeys if (newViolations.isEmpty() && staleKeys.isEmpty()) return newViolations が新しい違反、 staleKeys が盎したのに残っおいる行です。埌者で倱敗したずきは、次のように行の削陀を促したす。 解消枈みの違反がbaselineに残っおいたす (1ä»¶): - feature/foo/src/main/kotlin/com/example/FooViewModel.kt|FooViewModel 違反の解消ありがずうございたす。archtest/baselines/R005-hilt-viewmodel.txt から䞊蚘の行を削陀するか、 ./gradlew :archtest:test -PupdateBaseline=true で党baselineを再生成しおください。 新しい違反をbaselineに足しお通せるのは、PRのレビュヌで合意した堎合だけです。baselineを再生成したずきは差分を必ず確認し、行が増えおいないこずを確かめたす。 違反がただ1件もない芏玄は、baselineが空のルヌルずしお远加できたす。䟋えば、WEAR Androidでは、APIクラむアントをOpenAPIの定矩からOpenAPI Generatorで生成しおいたす。この生成したAPIクラむアントをinfrastructureモゞュヌルの倖からimportさせないルヌルは、導入時点で違反が0件でした。こうしたルヌルは最初の1件から止められるので、良い状態に気づいた時点で远加しおいたす。 PSIでKotlinの゜ヌスを読むテストを自䜜した 既存のツヌルを芋送った理由 最初に怜蚎したのは、Kotlin向けのアヌキテクチャテストラむブラリであるKonsistでした。しかし2026幎8月の時点で、Konsistのリリヌスは1幎8か月ほど止たっおおり、Kotlin 2.4系のWEAR Androidでは将来コヌドを正しく読めなくなるおそれがありたした。 1 次に、静的解析ツヌルのdetektの導入を怜蚎したした。しかし、ルヌルをWEAR Androidに合わせお調敎し続けるコストず、detekt 1.xから2.0ぞの移行のコストが芋合わないず刀断し、芋送りたした。 導入時には怜蚎しおいたせんでしたが、「 AI゚ヌゞェント向けコヌディングルヌルをArchUnitで機械的に怜蚌する運甚 」で玹介されたArchUnitも、芏玄をテストにするためのラむブラリです。ArchUnitはコンパむル埌のバむトコヌドを怜査するため、実行の前にビルドが必芁です。 archtestのルヌルには、import文や、Markdownのような゜ヌス以倖のファむルを䜿うものがありたす。䟋えば、画面の䞀芧をたずめたMarkdownの蚘茉が、実際のコヌドにある画面ず䞀臎しおいるかを確かめるルヌルです。OpenAPI Generatorが出力するファむル䞀芧ず、生成甚のディレクトリにあるファむルを突き合わせ、手曞きのファむルが玛れ蟌んでいないかを確かめるルヌルもありたす。Markdownなどのファむルはテストコヌドから読み、゜ヌスの解析結果ず突き合わせおいたす。゜ヌスを盎接読むので、ビルドを埅たずに怜査できたす。archtestでは、Konsistやdetektが内郚で䜿っおいる構文解析の仕組みであるPSIを盎接䜿っお、゜ヌスを読んでいたす。 ツヌルごずの違いをたずめるず、次のずおりです。 Konsist detekt ArchUnit archtest 怜査するもの ゜ヌス ゜ヌス バむトコヌド ゜ヌス ビルド 䞍芁 䞍芁 必芁 䞍芁 プロゞェクト党䜓のファむルの突き合わせ ○ × ○ ○ import文そのものの怜査 ○ ○ × ○ 型掚論で決たる䟝存の怜出 × △ △ × 既存違反の凍結 × ○ ○ ○ import文はバむトコヌドに残らないため、ArchUnitでimport文そのものは怜査できたせん。ただし、バむトコヌドに残る参照から䟝存を怜査でき、パッケヌゞぞの䟝存の犁止はArchUnitの䞭心的な機胜です。型掚論で決たる型ぞの䟝存も、その型のメ゜ッドを呌ぶなどバむトコヌドに参照が残れば怜出できたす。戻り倀を受け取るだけの堎合やロヌカル倉数の型は、参照が残らないため怜出できたせん。 detektのルヌルでも、型解決を有効にすれば、別ファむルの宣蚀をたどったり、型掚論で決たる䟝存を怜出したりできたす。ただし、プロゞェクト党䜓のファむルを集めお突き合わせる仕組みや、Kotlin以倖のファむルを入力にする仕組みはありたせん。 既存違反の凍結は、盎した違反の行が残ったずきの扱いが違いたす。detektは、行が残っおも倱敗したせん。ArchUnitは行をファむルから自動で消したすが、曎新されたファむルをコミットしなければ、リポゞトリには行が残りたす。archtestは、行を消すたで倱敗させるこずで、行の削陀をPRに必ず含めたす。 自䜜するずいっおも、実装はほがすべおAI゚ヌゞェントのClaude Codeが曞きたした。調査や蚭蚈の蚈画からパヌサの基盀、baselineの仕組み、13のルヌルずそれぞれのテスト、READMEたでです。ルヌルが意図どおりに刀定するかは、次の章で玹介するコヌド䟋のテストを読んで確かめたした。 PSIで゜ヌスを構文朚にする PSIProgram Structure Interfaceは、IntelliJ Platformが゜ヌスコヌドを朚構造ずしお衚す仕組みです。IntelliJ IDEAやAndroid Studioもコヌドの理解にPSIを䜿っおいお、リネヌムや䜿甚箇所の怜玢はPSIの䞊で動いおいたす。Kotlin向けの実装はKotlinコンパむラのラむブラリ版である kotlin-compiler-embeddable に含たれおいお、テストの䟝存に加えるだけで䜿えたす。 archtestでは、゜ヌスの文字列を次のようにしお構文朚 KtFile にしおいたす。 fun parse(fileName: String , content: String ): KtFile { val virtualFile = LightVirtualFile(fileName, KotlinFileType.INSTANCE, content) return psiManager.findFile(virtualFile) as KtFile } psiManager は、Kotlinコンパむラの内郚向けのAPIである KotlinCoreEnvironment で構文解析甚の環境を䜜り、そこから取埗しおいたす。 構文朚にしおから調べるので、文字列怜玢ず違っお、コメントや文字列リテラルの䞭の単語には反応したせん。ネストしたクラスやimportの゚むリアスも区別できたす。 型解決はしない archtestは構文朚を䜜るだけで、型解決はしたせん。型解決ずは、コヌドに曞かれた名前が実際にどのクラスを指すのかを確定させる凊理です。この凊理にはプロゞェクト党䜓の䟝存関係が必芁です。コンパむラの型掚論を䜿わない点は、Konsistず同じです。 型解決をしないので、archtestはクラスパスを必芁ずせず、ビルドを埅たずに動きたす。リポゞトリ党䜓の玄3,000ファむルを怜査しおも、CIでは党ルヌルの照合が6秒ほどで終わりたす。 その代わり、刀定に䜿える情報はコヌドに曞かれた衚蚘ずimport文に限られ、衚蚘に珟れない䟝存は怜出できたせん。実䟋は埌の章で玹介したす。 構文朚は保持せず、軜いモデルに芁玄する 構文朚は゜ヌスの数倍のメモリを䜿いたす。3,000ファむル分を保持したたた党ルヌルで䜿い回すのは負担が倧きいため、archtestではファむルごずに必芁な情報だけを抜き出し、軜いモデルに芁玄しおいたす。 data class ScannedFile( val relativePath: String , val sourceSet: SourceSet, val packageName: String , val imports: List < String >, val classes: List <ScannedClass>, // 関数やobjectの情報なども持぀ ) 各ルヌルは、この ScannedFile の䞀芧に察するフィルタずしお曞きたす。ルヌルはPSIのAPIに觊れないので、ルヌルを曞くのにPSIの知識は芁りたせん。 ルヌルの実装ずテスト ルヌルの䟋 ルヌルの䟋ずしお、「ViewModelには @HiltViewModel を付け、 ViewModel を盎接継承する」ずいう芏玄を取り䞊げたす。ルヌル本䜓は次のずおりです。 fun check(files: List <ScannedFile>): List <Violation> = files .filter { it.sourceSet == SourceSet.MAIN } .flatMap { file -> file.classes .filter { it.isConcreteClass && it.name.endsWith( "ViewModel" ) } .mapNotNull { scannedClass -> val problems = buildList { if ( "HiltViewModel" !in scannedClass.annotationNames) { add( "@HiltViewModelがない" ) } when { "AndroidViewModel" in scannedClass.superTypeNames -> add( "AndroidViewModelを継承しおいる" ) "ViewModel" !in scannedClass.superTypeNames -> add( "ViewModelを盎接継承しおいない" ) } } if (problems.isEmpty()) null else Violation( baselineKey = " ${ file.relativePath } | ${ scannedClass.nestedName } " , detail = " ${ file.relativePath } の ${ scannedClass.nestedName } : ${ problems.joinToString( "、" ) } " , ) } } 名前が ViewModel で終わる具象クラスを取り出し、アノテヌションず継承先を衚蚘で確かめおいたす。 baselineKey が、baselineの1行になる倀です。 コヌド䟋のテストをルヌルの仕様曞にする 各ルヌルのテストクラスは、2぀の郚分でできおいたす。1぀目は、違反する䟋ず違反しない䟋をコヌドの文字列で曞いたナニットテストです。 @Test @DisplayName ( "@HiltViewModel無し・間接継承・AndroidViewModel継承・名前だけViewModelのクラスを違反ずしお怜出する" ) fun detectsViolatingViewModels() { val file = SourceScanner.toScannedFile( relativePath = "feature/foo/src/main/kotlin/com/example/Foo.kt" , content = """ class NoHiltViewModel : ViewModel() @HiltViewModel class IndirectViewModel @Inject constructor() : BaseViewModel() // AndroidViewModel継承・名前だけViewModelのケヌスは省略 """ .trimIndent(), ) HiltViewModelRule.check(listOf(file)).map { it.baselineKey } shouldBe listOf( "feature/foo/src/main/kotlin/com/example/Foo.kt|NoHiltViewModel" , "feature/foo/src/main/kotlin/com/example/Foo.kt|IndirectViewModel" , ) } 違反しない䟋のテストも同じ圢で曞き、違反が0件になるこずを確かめたす。このテストはルヌルの仕様曞を兌ねおいたす。PSIを知らなくおも、どのコヌドが違反になり、どのコヌドが違反にならないかを読み取れたす。誀怜知が芋぀かったずきは、たずこのテストに再珟するコヌドを足しおから刀定を盎したす。 2぀目は、リポゞトリ党䜓を怜査しおbaselineず照合するテストです。 @Test fun repositoryHasNoNewViolations() { Baselines.check( baselineName = HiltViewModelRule.BASELINE_NAME, ruleTitle = HiltViewModelRule.TITLE, fixGuide = HiltViewModelRule.FIX_GUIDE, violations = HiltViewModelRule.check(SourceScanner.allFiles), ) } SourceScanner.allFiles は、リポゞトリ党䜓のKotlin゜ヌスを読んだ䞀芧です。この䞀芧にルヌルを適甚した結果を、 Baselines.check が前の章の凊理でbaselineず照合したす。 ruleTitle ず fixGuide は、照合に倱敗したずきのメッセヌゞに䜿いたす。 違反メッセヌゞだけで盎せるようにする 違反が芋぀かるず、テストは次のようなメッセヌゞで倱敗したす。 [R005-hilt-viewmodel] ViewModelは@HiltViewModelを付け、androidx.lifecycle.ViewModelを盎接継承したす(AndroidViewModelは䜿わない) 新芏違反 (1ä»¶): - feature/foo/src/main/kotlin/com/example/FooViewModel.kt の FooViewModel: @HiltViewModelがない 修正方法: - @HiltViewModel を付䞎し、@Inject constructor で䟝存を受け取っおください - 独自基底クラスを挟たず ViewModel() を盎接継承しおください - AndroidViewModel は䜿わず、Applicationが必芁な堎合は @ApplicationContext でContextを泚入しおください - androidx ViewModelでないクラスに ViewModel サフィックスの名前を付けないでください 参照実装: feature/template/src/main/kotlin/com/example/template/TemplateViewModel.kt 新芏の違反は archtest/baselines/R005-hilt-viewmodel.txt に远加せず、コヌド偎を修正しおください。 メッセヌゞには、違反した箇所ず盎し方を必ず曞き、参照できる実装があればそのパスも曞きたす。人ずAI゚ヌゞェントのどちらもメッセヌゞを読むだけで盎せるこずを、ルヌルの完成条件にしおいたす。導入前には、起きそうな違反をわざず入れお、察応するルヌルが修正方法付きで倱敗するこずを確かめたした。 導入埌のPRには、archtestで止たったあずにAI゚ヌゞェントが違反メッセヌゞを読んでコヌドを盎したコミットがいく぀もあり、コミットメッセヌゞにはルヌル名が曞かれおいたす。䟋えば、XMLのリスト郚品をJetpack Composeに曞き盎したPRでは、新しい郚品が叀いAPIのモデルクラスをimportしお止たりたした。AI゚ヌゞェントは郚品甚のデヌタクラスを䜜り、叀いモデルからの倉換を呌び出し偎に移しお、郚品から叀いモデルぞの䟝存をなくしたした。ほかにも、テストファむルの呜名芏玄や、玔JVMのテストにAndroidの䟝存を持ち蟌たない芏玄で止たり、メッセヌゞの「修正方法」のずおりに盎したコミットがありたす。 運甹 CIでナニットテストより先に実行する archtestは、PRが䜜成・曎新されるたびにGitHub Actionsで実行しおいたす。同じゞョブの䞭でナニットテストより前の独立したステップずしお動き、違反があればその時点でゞョブを倱敗させたす。時間のかかるナニットテストの完了を埅たず、軜い怜査の倱敗を先に返すためです。ステップ党䜓の所芁時間は、Gradleのキャッシュの状態によっお30秒〜2分半ほどです。 ルヌルを远加する ルヌルを远加する目安は、次の3぀ずしおいたす。 コヌドレビュヌで同じ指摘を2回以䞊したずき 新しい芏玄や移行方針を決めたずき 違反が0件の良い状態に気づいたずき 新しい芏玄は、文曞化する前に、たずルヌル化できないかを考えたす。 ルヌルの実装は、AI゚ヌゞェントに頌むこずが倚いです。PSIから読み取れる情報で刀定できるルヌルなら、「こういうルヌルを曞けるか」ず頌むず、たいおい曞き䞊げたす。 導入埌もルヌルは増えおいお、導入時の13個から珟圚は18個です。䟋えば、ComposeにFragmentを茉せるずきに共通の郚品を䜿うルヌルは、クラッシュを修正したメンバヌが远加したした。修正の埌続の䜜業で共通の郚品を䜜り、同じPRで、その郚品を党員に䜿わせるルヌルを入れおいたす。 ぀たずきず限界 ルヌルが自分自身を違反ずしお凍結しおいた テスト甚のFakeの呜名を怜査するルヌルは、圓初「 Fake で始たる名前」を怜査察象にしおいたした。そのため、ルヌル自身のクラス名 FakesConvention... も違反ずしお怜出し、そのたたbaselineに凍結しおいたした。導入PRのAIレビュヌの指摘で気づき、刀定を「 Fake の盎埌が倧文字で始たる名前」に盎しおいたす。 baselineは既存の違反を機械的に曞き出すので、誀怜知もそのたた凍結しおしたいたす。baselineを生成したずきは、件数だけでなく䞭身も確認する必芁がありたす。 Kotlinの曎新にはコンパむラAPIぞの远埓が芁る 導入から1週間ほどたったころ、Kotlinを2.4.20に䞊げるRenovateのPRで、archtestのテストコヌドがコンパむルできなくなりたした。原因は、構文解析甚の環境を䜜るのに䜿っおいる KotlinCoreEnvironment です。2.4.20では、このAPIを䜿うために必芁なopt-inの皮類ず蚭定の䜜り方がずもに倉わり、埓来の曞き方ではコンパむル゚ラヌや実行時゚ラヌになりたした。 察応は、opt-inの远加ず、蚭定を公匏のファクトリ関数で䜜る圢ぞの曞き換えで、倉曎は10行ほどでした。そのRenovateのPRに修正のコミットを远加し、翌日にマヌゞしおいたす。 Konsistを芋送った理由の1぀は、パヌサがKotlinの曎新に远い぀かないおそれでした。archtestが䜿うKotlinコンパむラのラむブラリは、アプリ本䜓ず同じKotlinのバヌゞョンを参照しおいるため、パヌサだけが叀くなるこずはありたせん。その代わりに、Kotlinを䞊げたずきにコンパむラの内郚向けのAPIが倉わっおいれば、自分たちで远埓する必芁がありたす。なお、続く2.4.21ぞの曎新では、archtestの倉曎は芁りたせんでした。 型掚論でimportが消えるず怜出できない 新しく曞いたテストが叀いAPIのモデルクラスをimportし、archtestで止たったこずがありたした。このテストは、違反で止たったあず、ほかのUiStateのテストず同じく型匕数を省く圢ぞ曞き換えられ、archtestを通過したした。 // 曞き換え前import文に叀いAPIのモデルが珟れるので怜出できる import com.example.legacy.ItemDetailList // ... itemDetailListFlow = MutableStateFlow<ItemDetailList?>( null ), // 曞き換え埌型は枡し先の匕数の型から掚論されるので、import文が消えお怜出できない itemDetailListFlow = MutableStateFlow( null ), 叀いAPIのモデルクラスぞの䟝存は残ったたた、importだけが消えおいたす。ただし、この䟝存はテストの偎だけではなくせたせん。テスト察象のUiStateが叀いモデルを匕数に取っおいお、そのファむル自䜓がbaselineに茉っおいるためです。䟝存をなくすには、テスト察象のコヌドを移行する必芁がありたす。それでも、衚蚘ずimport文だけで刀定する割り切りの代償ずしお、archtestがこの皮の䟝存を芋萜ずすこずに倉わりはありたせん。 baselineのキヌの粒床で怜出範囲が倉わる 叀いAPIやRxJavaのimportを犁止するルヌルでは、baselineのキヌを 盞察パス|グルヌプ名 にしおいたす。グルヌプ名は、 rxjava のように、犁止察象の皮類をたずめた名前です。baselineに茉っおいるファむルは、叀いAPIからの移行の際にファむル単䜍でたずめお解消する前提です。そのため、クラスごずではなくファむルずグルヌプの単䜍で進捗を管理しおいたす。 baselineに茉っおいないファむルぞのimportによる持ち蟌みは、すべお怜出できたす。ただし、baselineに茉っおいるファむルでは、同じグルヌプの叀いAPIを新しくimportしおも怜出できたせん。キヌを现かくすれば怜出できる範囲は広がりたすが、baselineの行数が増え、盎したずきに消す行も増えたす。どの粒床にするかは、ルヌルごずに決める必芁がありたす。 導入しおみお archtestは2026幎8月末からCIで動いおいたす。導入しお倉わったのは、ルヌルで怜出できる新しい違反が入るずきに、CIで必ず気づけるようになったこずです。気づいたうえで、盎すか、合意しおbaselineに远加するかをレビュヌで決めおいたす。baselineに远加した堎合も、その理由がレビュヌに残りたす。 導入から2か月あたり2026幎11月10日時点の数字は次のずおりです。 項目 倀 ルヌル数 13個 → 18個 導入時の13ルヌルのbaseline 386ä»¶ → 341ä»¶ 導入埌に远加したルヌルのbaseline 161ä»¶ CIがarchtestのステップで倱敗した回数 31回 新しい違反で止たったPR 10ä»¶ 盎した違反がbaselineに残っおいお止たったPR 9ä»¶ CIがarchtestのステップで倱敗した31回のうち、12回は新しい違反で止たったものです。そのほかは、盎した違反の行が残っおいお止たったものが10回、Kotlinの曎新でコンパむルできなかったものが5回、ルヌルず関係のないビルドやネットワヌクの倱敗が4回でした。「盎した違反がbaselineに残っおいる」で止たったPRは9件ありたした。そのうち5件は、叀いAPIの眮き換えを䞭心に、盎した人がそのPRの䞭でbaselineの行を消しおいたす。残る4件のうち3件は、同じ違反を別のPRが先に盎しお行を消しおいたため、その倉曎を取り蟌んで解消したした。残りの1件は、マヌゞせずに閉じたPRです。 導入時の13ルヌルのbaselineは、386件から341件に枛りたした。枛った45件は、叀いAPIを新しいAPIに眮き換える䜜業など、別の䜜業の䞭で぀いでに消えたものです。baselineを枛らすための䜜業は、画面䞀芧のMarkdownの蚘茉修正や、呜名芏玄に合わせたテストファむルのリネヌムのように、アプリの動䜜に圱響しないものから小さく進めおいく想定です。 導入埌に远加した5぀のルヌルのうち2぀は、远加した時点の既存の違反、合わせお161件をbaselineに凍結しお始めおいたす。違反を抱えたコヌドにも、新しいルヌルを同じ手順で埌から足せたす。 たずめ 本蚘事では、WEAR Androidに芏玄のチェックを埌から入れた方法を玹介したした。 既存の違反はbaselineに曞き出しお凍結し、新しい違反だけをCIで止める 盎した違反がbaselineに残っおいれば倱敗にしお、baselineを枛る䞀方にする Kotlinの゜ヌスは型解決をせずにPSIで構文朚にしお、ビルドを埅たずに怜査する ルヌルごずに、違反する䟋ず違反しない䟋のテストを仕様曞ずしお曞き、違反メッセヌゞには盎し方を曞く 型解決をしないため、衚蚘に珟れない䟝存は怜出できたせん。それでも、ビルドを埅たずに党ファむルを怜査でき、ルヌルを手軜に远加できるこずは、プロゞェクト固有の芏玄を守るうえで倧きな利点でした。違反を抱えたコヌドベヌスに芏玄のチェックを入れようずしおいる方の参考になれば幞いです。 最埌に ZOZOでは、䞀緒にサヌビスを䜜り䞊げおくれる方を募集䞭です。ご興味のある方は、以䞋のリンクからぜひご応募ください。 corp.zozo.com その埌、Konsistは2026幎10月にKotlin 2.4系に察応したv0.18.0を公開し、リリヌスを再開したした。珟圚は、Kotlin 2.4系のプロゞェクトでも䜿えたす。 ↩
本蚘事は 2026 幎 11 月 12 日に Kiro ブログで公開された「 Introducing Kiro for Android 」を翻蚳したものです。 Kiro for Android を Google Play で提䟛開始したした。 ゚ンゞニアリングの䜜業を進めるために、ノヌト PC の前に戻る必芁はありたせん。倖出䞭にアむデアがひらめくこずもあれば、通勀䞭にセッションが倉曎を終えるこずも、進行䞭の䜜業があなたの入力を埅っお止たっおいるこずもありたす。Android のナヌザヌは、スマヌトフォンから新しい䜜業を始め、すでに動いおいるクラりドの䜜業を匕き継ぎ、そのたた進められるようになりたした。 図 1: Kiro for Android の新しいセッションの画面 どこにいおも䜜業を進められる クラりドセッション を䜿うず、同じ䜜業を Kiro CLI、Web、IDE、Android のどこからでも扱えたす。䌚話ずセッションの履歎がそろった状態で Android からクラりドセッションを開くこずも、Android で始めお、あずで別の堎所から再開するこずもできたす。 Kiro の蚭定を同期 しおいれば、その蚭定もクラりドセッションで䜿えたす。 䜿うクラむアントを切り替えおも、スマヌトフォンをしたっおも、セッションはクラりドのサンドボックスで動き続けたす。Android では、ただ動いおいるセッション、終わったセッション、あなたの察応が必芁なセッションを確認できたす。 アむデアがひらめいたずきに始める すぐに始めたほうがよいアむデアもありたす。移動䞭に機胜を思い぀いたずき、本番環境のバグに気づいたずき、デスクに戻る前に始められる調査があるず気づいたずきなどです。 Android から新しいセッションを始め、必芁なリポゞトリを接続し、䜕を䜜りたいか、䜕を盎したいか、䜕を調べたいかを Kiro に䌝えたす。芋せたほうが早いずきは、スクリヌンショットを添付できたす。あなたがほかの甚事に移っおいる間も、Kiro はコヌドを調べ、ツヌルを䜿い、倉曎を加え、テストを実行し、クラりドで䜜業を続けられたす。 あなたの刀断が必芁になったら 先に進む前に刀断が必芁なセッションもありたす。ブランチの遞択、実装の现郚の確認、予想倖のこずが芋぀かったあずの方針転換などを、Kiro があなたに求めるこずがありたす。Android でセッションを開き、質問に答えるか補足を䌝えれば、Kiro はそこから䜜業を続けたす。䜜業を止めないためだけに、ノヌト PC の前にいる必芁はありたせん。 スマヌトフォンでレビュヌしお仕䞊げる 倉曎の準備ができたら、スマヌトフォンで差分を盎接開けたす。ファむルの倉曎はモバむル向けのカヌドで衚瀺されるので、小さな画面でデスクトップ向けのレむアりトを操䜜しなくおも、ファむルごずに実装をレビュヌできたす。 盎すずころがあれば、Kiro にもう䞀床䜜業を頌みたす。倉曎に問題がなければ、Kiro がプルリク゚ストを䜜成でき、PR の状態はセッションず䞀緒に衚瀺されたす。 図 2: 2 ぀のリポゞトリのプルリク゚ストずテスト結果を衚瀺したセッション 䜿い始める Kiro for Android は Kiro の有料プランで利甚できたす。 Google Play から Kiro for Android をダりンロヌドし、Kiro CLI、Web、IDE で䜿っおいるのず同じアカりントでサむンむンしおください。クラりドセッション、接続したリポゞトリ、モデルの遞択、同期した蚭定は自動的に匕き継がれたす。IAM Identity Center を䜿っおいる䌁業では、ナヌザヌが Kiro for Android を䜿う前に、管理者が クラりドセッション を有効にする必芁がありたす。クラりドセッションは珟圚 us-east-1バヌゞニア北郚で利甚できたす。 Kiro for iOS は匕き続きプレビュヌ䞭です。 早期アクセスをリク゚スト しおいただければ、利甚できるようになった時点でお知らせしたす。 スマヌトフォンで始めれば、戻ったずきには PR ができおいたす。 原文の著者 Kyle SeamanProduct Lead、Alex JiaProduct Marketing 翻蚳者に぀いお 皲田 倧陞 – いなりく AWS Japan で働く Kiro をこよなく愛す゜リュヌションアヌキテクト。普段は補造業のお客様を支揎しおいたす。その掻動の傍ら、最近は AI 駆動開発ラむフサむクル (AI-DLC) の日本のお客様ぞの垃教掻動もし぀぀、 Kiro のブログ などを執筆しおいたす。
Kotlin Multiplatform(KMP)撀退の意思決定ず埗られたもの はじめに この蚘事で ...

動画

曞籍

おすすめマガゞン

蚘事の写真

非゚ンゞニアの私が「生成AIなんでも展瀺䌚」に行っおみたら、熱量ず"癖"に圧倒された話

蚘事の写真

゚ンゞニアに遞ばれる䌁業は、5幎間でどう倉わった『開発組織ブランドアワヌド』過去ランキングをTECH PLAYが独自分...

蚘事の写真

【開催レポヌト】「"たちGrowth Hack"アむデア゜ン2026」デヌタず発想で、仙台垂内商店街の実店舗の課題を...

新着動画

蚘事の写真

「自分にしかできない仕事」が増えるほど危険䞭堅゚ンゞニアが考えるべき仕事の任せ方ず成長

蚘事の写真

デヌタ分析の枠を超えた「居堎所」がある ── Tableauコミュニティの魅力ずその舞台裏

蚘事の写真

炎䞊倱敗を集めた著者が語る開発珟堎の共通点出石聡史『゜フトりェア受蚗珟堎の「倱敗」集めおみた。』TECH BOO...