Add a recipe for testing composables that use Hilt - #321
DanielJette wants to merge 2 commits into
Conversation
AndroidTestifyBot
left a comment
There was a problem hiding this comment.
Changes requested
Two fixes, plus a standing caveat about verification.
1. Step 3 contradicts itself — use the debug source set
In your
androidTestsources, create a subclass ofComposableTestActivity[…]
Declare it in the manifest of yourdebugsource set,src/debug/AndroidManifest.xml
Those are different APKs — an androidTest class compiles into the test APK, while src/debug/AndroidManifest.xml merges into the app APK's manifest.
The src/debug/AndroidManifest.xml instruction is the correct half and matches the house convention (extensions/compose/1-setup.md and Samples/Flix). Please change step 3 to put HiltComposableTestActivity in the debug source set, not androidTest.
2. Drop the kapt fallback
If your project uses kapt instead of KSP, use
kaptAndroidTest.
AGP 9 removed kapt, so this is a trap rather than a fallback. Please remove the sentence. The <hilt version> placeholders are fine as-is — better than pinning a version that will go stale.
Verified correct
ComposableTestActivityisopen, so the subclass compiles. Worth stating explicitly because the whole recipe depends on it.ComposableScreenshotRulegenuinely can't be used with Hilt — it hardcodesactivityClass = ComposableTestActivity::class.javain its superclass call. The:::notesteering readers toComposableScreenshotScenarioRuleis correct and well-reasoned.setCompose { },withScenario(scenario),@Rule(order = …)and theHiltTestRunnersnippet are all right.- "The Testify Gradle Plugin reads this setting" — true,
TestifySettings.createfalls back toandroid.defaultConfig.testInstrumentationRunner. @style/Theme.AppCompat.NoActionBarmatches what1-setup.mdandSamples/Flixalready use forComposableTestActivity, so the Hilt host is visually consistent and existing baselines shouldn't move.- The error string is already introduced with "an error like this", which is the right hedge for a message we can't reproduce in-repo.
Standing caveat
This is the least-verified page in the batch: there is no Hilt screenshot test anywhere in this repo, so the end-to-end sequence has never been run here. The individual claims check out; the sequence has no working example behind it. Unlike #318, which lifts its examples from FullscreenCaptureExampleTests.kt, nothing here compiles in CI. A minimal Hilt sample would convert this from plausible to proven — worth considering as a follow-up.
Reviewed by Claude on behalf of @DanielJette.
AndroidTestifyBot
left a comment
There was a problem hiding this comment.
Approved
Both requested changes are in, and the source-set move surfaced something I hadn't thought through.
The contradiction is resolved
Step 3 now says "In your debug source set, src/debug/java", matching the manifest it tells you to edit and the house convention in extensions/compose/1-setup.md and Samples/Flix. The kapt sentence is gone. <hilt version> placeholders kept.
The new debugCompileOnly section is correct
This is the part I'd have missed, and it follows directly from moving the activity out of androidTest:
Code in the
debugsource set can't see yourandroidTestdependencies […]
Both are needed, becauseComposableTestActivityimplements an interface from the coretestifylibrary.
Verified against the published coordinates. ComposableTestActivity is in Ext/Compose, published as dev.testify:testify-compose (artifact: 'testify-compose'), and it's declared open class ComposableTestActivity : AppCompatActivity(), TestifyResourcesOverride — where TestifyResourcesOverride lives in Library/src/main/java/dev/testify/resources/, published as dev.testify:testify (artifact: 'testify'). So subclassing it genuinely does need both artifacts on the compile classpath. Precisely argued.
compileOnly being sufficient is the right call too: the classes come from the test APK at runtime, exactly as they already do for ComposableTestActivity under the existing documented setup.
Re-verified
ComposableTestActivityisopen, so the subclass compiles.ComposableScreenshotRulehardcodesactivityClass = ComposableTestActivity::class.java, so the note steering readers to the scenario rule is correct.@style/Theme.AppCompat.NoActionBarmatches what1-setup.mdandSamples/Flixalready use, so baselines shouldn't move.- The error string is introduced with "an error like this" — the right hedge.
Docs build verified locally: exit 0, zero warnings, individually and combined.
Standing caveat, unchanged
There's still no Hilt screenshot test in the repo, so the end-to-end sequence has never been run here. Every individual claim checks out and the reasoning is sound — but this remains the one page in the batch with no executable example behind it. A minimal Hilt sample would close that gap. Approving on the strength of the reasoning and the verified parts; flagging it so it's a known, deliberate risk rather than an unexamined one.
Reviewed by Claude on behalf of @DanielJette.
|
Filed #325 to track the follow-up noted in the approval: a Hilt screenshot test in the sample suite, so this recipe has an executable example behind it the way #318 has
The issue lists the six steps from this page that are currently unverified, including the |
|
Added the worked-example section now that #334 provides the compiled sample this was waiting on — that PR adds It also records the two ways the sample departs from the steps here, since they would otherwise read as contradictions:
Rebased onto current |
e13c832 to
b70a14c
Compare
AndroidTestifyBot
left a comment
There was a problem hiding this comment.
Changes requested
The earlier approval was for the page without the worked-example section. That section was added afterwards, so this replaces it. Steps 1–4 are unchanged and still check out; the docs build is clean. The new section is the problem.
1. Three links are dead until #334 merges
The worked example links to blob/main/Samples/Flix/FlixHilt/.... Those files exist only on #334's branch. If this merges first, all three 404. Either merge strictly after #334 or hold the section back until then. The PR description still says "the cross-link to the sample test will land with #325 so this page has no dependency on it", which is no longer what the diff does.
2. The link to the blank-screenshots recipe sidesteps the link checker
Per your own comment, the relative link to recipe 25 was rejected by onBrokenLinks: throw because that page is still in #317, so it became https://testify.dev/docs/recipes/blank-or-incomplete-screenshots. That makes the build pass and the link broken on the live site until #317 ships. Use the relative link and merge after #317, or drop the sentence.
3. "The FlixHilt sample module is this recipe, compiled and running in CI"
It isn't this recipe. Step 3 here is the debug source set, debugCompileOnly, and src/debug/AndroidManifest.xml; the sample uses main and compileOnly. The section goes on to say so, but the opening sentence claims more than the sample delivers, and steps 1–4 of #325's checklist remain unverified by anything compiled. I've asked on #334 for the sample to move to src/debug + debugCompileOnly; if that happens this sentence becomes true and the first "does differently" bullet can go.
Also on #334: the sample's activity works equally well from src/androidTest with an androidTest manifest and no compileOnly at all (I ran it; same baseline). So "there is no shipping build to keep the activity out of" is a reason for the choice, not the only arrangement that works.
4. "running in CI"
Only on Bitrise test_flix, once #334 lands. flix_sample.yml doesn't build FlixHilt.
Housekeeping
The description needs a refresh: "the diff is still the single new file" and the no-dependency sentence predate the worked-example commit.
|
Agreed on all four. The section is rewritten and the description corrected. 1 and 3 — the sample now is this recipeRather than keep qualifying the claim, I changed the sample. #334 moves Your The three file links are updated to the new paths. They still require #334 to merge first, which is now noted in the description. 2 — relative link restored, and my reasoning for dropping it was wrongSwitched back to Worth recording why I had reached for it: the relative link does resolve, and my earlier conclusion that So the link is correct and this branch's docs build fails standalone purely because recipe 25 is still in #317 — the merge-order dependency you identified, not a bad link. 4 — "running in CI"Corrected to just "runs on CI", and #334's description now states that Bitrise Merge order#317 → #334 → #321. #317 for the relative link, #334 for the three file links. Noted at the top of the description so it does not get lost. |
AndroidTestifyBot
left a comment
There was a problem hiding this comment.
Approved — merge after #317 and #334
All four points are resolved.
- With #334 now putting the activity in
src/debugwithdebugCompileOnly, "follows these steps exactly" is true, and the "does differently" bullet is rightly gone. - The link to recipe 25 is relative again, so
onBrokenLinks: throwguards it. I checked your stale-cache explanation: this branch alone fails the docs build on that one link, and with #317's recipe 25 dropped in andnpm run clearfirst, it builds clean. The only problem is merge order. - "runs on CI" is accurate once #334 lands (Bitrise
test_flix). - The
:::cautionabouttestInstrumentationRunnerbeing per module is a better home for the Flix finding than the old bullet.
Merge order: #317 → #334 → #321, as the description now says. Merged earlier, this breaks the docs build (recipe 25 link) and leaves four 404ing blob/main/Samples/Flix/FlixHilt/... links.
Important
Merge after #317 and #334. This page links to recipe 25, which is still in #317, and to three
files in
Samples/Flix/FlixHilt, which #334 adds. Both are relative/blob/mainlinks on purpose —the alternative was absolute URLs that pass the link checker while being broken on the live site.
What does this change accomplish?
Composables that use
hiltViewModel()fail underComposableTestActivity(#207), andhiltreturns no results in docs search.Fixes #207
How have you achieved it?
recipes/27-hilt.md: Hilt testing dependencies, aHiltTestApplicationrunner, an@AndroidEntryPointsubclass ofComposableTestActivityin thedebugsource set and its manifest, and a test usingHiltAndroidRulewithComposableScreenshotScenarioRule.testify-composeandtestifyon the debug compile classpath. The recipe usesdebugCompileOnly:testify-composepublishestestifyas a runtime-only dependency, so both are needed for theTestifyResourcesOverridesupertype, anddebugImplementationpulls Testify's test dependencies into the app, which broke dependency resolution in Flix (androidx.test.ext:junit1.1.5 vs 1.3.0).ComposableScreenshotRulealways launchesComposableTestActivity, so it can't be used with Hilt.Scope of Impact and Testing instructions
Documentation only; no library or plugin changes, so no CHANGELOG entry. Built locally with
yarn buildfromdocs/. No broken links. The setup was run in the Flix sample (Hilt 2.60.1, KSP) on an API 37 emulator: a composable callinghiltViewModel<NavigationViewModel>()recorded successfully with the Hilt host activity, and the same test withComposableTestActivityfailed with the #207 exception. After moving the host activity tosrc/debugwith thedebugCompileOnlydependencies, the same test recorded withscreenshotRecordand then passed withscreenshotTest. That test code was not committed.Each commit includes
[skip ci]so CI doesn't run for this docs-only change.Why this was reopened
Closed on 2026-09-25 after approval, pending an executable example — tracked as #325. #334 now
provides it, and the worked-example section at the bottom of the page points at it step by step.
Every claim in steps 1–4 still holds against
main:ComposableScreenshotRulestill hardcodesactivityClass = ComposableTestActivity::class.java(
Ext/Compose/.../ComposableScreenshotRule.kt:54), so the note about it remains correct.ComposableTestActivityis stillopen class ... : AppCompatActivity(), TestifyResourcesOverride,which is why both
debugCompileOnlyartifacts are needed.android.defaultConfig.testInstrumentationRunner(
Plugins/Gradle/.../TestifyExtension.kt:119), so step 2's claim aboutscreenshotTestholds.Rebased onto current
main. The worked-example section was reviewed separately and rewritten: thesample in #334 now uses
src/debuganddebugCompileOnly, so it matches these steps exactly ratherthan departing from them.
Notice
Warning
This change must keep
mainin a shippable state; it may be shipped without further notice.