skill: add Android skills
This commit is contained in:
69
.agents/skills/camerax/references/testing.md
Normal file
69
.agents/skills/camerax/references/testing.md
Normal file
@@ -0,0 +1,69 @@
|
||||
Automated testing for camera features is notoriously difficult because you
|
||||
can't easily mock physical hardware, lighting, or motion. This guide provides
|
||||
patterns for reliable, hermetic camera tests.
|
||||
|
||||
## Develop a testing mindset
|
||||
|
||||
| Challenge | Conventional approach | Camera technical approach |
|
||||
|---|---|---|
|
||||
| **Frameworks** | `Mockito` or `MockK` | **Fakes over mocks** |
|
||||
| **Assertions** | `assertEquals`, `assertTrue` | **Google Truth, `assertThat`** |
|
||||
| **Environment** | Implied environments | **Explicit `@RunWith` annotations** |
|
||||
| **Async operations** | `Thread.sleep` | **Explicit `timeoutMillis` or `IdlingResource`** |
|
||||
|
||||
*** ** * ** ***
|
||||
|
||||
## Follow the implementation guide
|
||||
|
||||
### Fakes over mocks
|
||||
|
||||
**Don't use Mockito.** Relying on mocks for complex, rapidly changing interfaces
|
||||
like `ImageProxy` or `CameraInfo` makes tests brittle. Instead, build "Fake"
|
||||
implementations that verify state rather than behavior.
|
||||
|
||||
|
||||
```kotlin
|
||||
// Create a Fake ImageProxy for ML Testing (Fakes over Mocks)
|
||||
val fakeImage = FakeImageProxy(w = 640, h = 480)
|
||||
|
||||
// Feed the fake buffer into your analyzer
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
### Mock camera capabilities
|
||||
|
||||
Use `FakeAppConfig` from `androidx.camera:camera-testing` to simulate specific
|
||||
hardware constraints in tests, such as a device without a flash.
|
||||
|
||||
|
||||
```kotlin
|
||||
// Use awaitInstance() extension function for coroutine-based provider retrieval
|
||||
val cameraProvider = ProcessCameraProvider.awaitInstance(context)
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
### Use Truth assertions
|
||||
|
||||
Use Google Truth, `assertThat`, instead of standard JUnit assertions. It
|
||||
provides more readable assertion chains and useful failure messages.
|
||||
|
||||
### Test asynchronous lifecycles
|
||||
|
||||
Camera initialization is asynchronous. Use `IdlingResource` to ensure
|
||||
your test waits for the `UseCase` to be bound before asserting.
|
||||
|
||||
To test asynchronous lifecycles, use the following pattern:
|
||||
|
||||
1. Wrap the `ProcessCameraProvider` initialization in a `CountDownLatch` or `IdlingResource`.
|
||||
2. Assert only after the `cameraControl` instance is non-null.
|
||||
|
||||
*** ** * ** ***
|
||||
|
||||
## Testing pitfalls
|
||||
|
||||
- **Resource leaks** : To prevent "Camera in Use" errors, in your `@After` block, call `cameraProvider.unbindAll`.
|
||||
- **The "flaky initializer"**: Camera tests often fail on CI because the "Virtual Camera" takes too long to warm up. Use a sufficient explicit timeout for the first initialization.
|
||||
- **Permission blockers** : To bypass the system permission dialogs, in your Espresso tests, use `GrantPermissionRule`.
|
||||
- **Resolution mismatch** : Tests on emulators often default to 640x480. Ensure your `ResolutionSelector` handles this low-res fallback correctly.
|
||||
Reference in New Issue
Block a user