Testing Strategy & Pyramid Flashcards
TESTING › Strategy
- What is the testing pyramid and why is it shaped that way?
- A guideline to write many fast, isolated unit tests, fewer integration tests, and the fewest UI/E2E tests. Unit tests are cheap, fast, and stable; UI tests are slow and flaky, so you minimize them while still covering critical flows.
- What is the difference between a local test and an instrumented test?
- Local tests run on the host JVM (no device), so they are fast and isolated but lack framework fidelity. Instrumented tests run on a device or emulator with the real Android framework, giving higher fidelity at the cost of speed.
- How do you unit-test a ViewModel?
- Construct it directly with fake/test dependencies (e.g., a fake repository), inject a test CoroutineDispatcher via StandardTestDispatcher/UnconfinedTestDispatcher, drive its functions, and assert on the exposed StateFlow/UiState. No device needed; it runs as a local JVM test.
- What is the difference between a fake and a mock?
- A fake is a working lightweight implementation (e.g., an in-memory repository) you call normally. A mock is a configured stub created by a framework where you script return values and verify interactions. Prefer fakes for state-based tests; mocks for verifying behavior/collaborations.
- What should you generally NOT write tests for?
- Framework or library code you do not own (Android SDK, Room, Retrofit internals), trivial code with no logic (plain getters/setters, data classes), and auto-generated code. Test your own logic, state transitions, and edge cases instead.
- How do you unit-test a repository that uses coroutines and a Flow?
- Replace its data sources with fakes (in-memory DAO, fake remote source), run the test with runTest, collect or use Turbine on the returned Flow, and assert emitted values, caching behavior, and error mapping. Keep it a local test with no real network or DB.
- Why does decoupled architecture matter for testing?
- Keeping business logic out of Activities/Fragments and away from the Android framework (no Context in ViewModels) lets you swap dependencies via interfaces/DI and test units in isolation as fast local tests, instead of being forced into slow instrumented tests.
- When are UI/end-to-end tests worth the cost despite being at the top of the pyramid?
- When you must verify integration across layers and the real framework: critical user journeys, navigation, screen state wiring, and regressions that unit tests cannot catch. You keep them few and focused on high-value flows.
- What makes a good unit test (the key properties to balance)?
- Scope (how much it covers), speed (how fast it runs), and fidelity (how close to real). Good unit tests are narrowly scoped, fast, deterministic, independent, and readable; you trade some fidelity for speed and stability.