Integration testing
Skill almasumdev/awesome-mobile-testing-agent-skills/.github/skills/integration/integration-testing
Expert guidance on integration tests that exercise the seams between layers (repo → network → DB → mapper) without the UI. Use when unit tests pass but a feature still breaks, or when a bug is only visible when multiple collaborators interact.From its SKILL.md
npx -y skills add almasumdev/awesome-mobile-testing-agent-skills --skill integration-testingAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.1 KB, ~1.2k tokens by cl100k_base, as published. Nobody here has run it
Integration Testing (Non-UI)
Instructions
Integration tests sit between unit tests and UI/E2E tests. They wire up real collaborators for one slice — typically repository + network client + DB + serialization — while keeping the UI, device platform, and remote services out of the picture. They catch mapper, transaction, and protocol bugs in milliseconds, not minutes.
1. What Counts as "Integration"
A good integration test:
- Spans more than one production class.
- Uses real implementations where they are cheap (JSON parser, SQL driver, HTTP stack against a local mock server).
- Uses fakes only for things that are genuinely external (auth server, push, analytics).
- Runs on the host runtime (JVM / host Swift / Node / Dart VM), not a device.
2. Local HTTP Mock Servers
Prefer a real HTTP server over in-process interception — it catches serialization and header bugs that interceptors skip.
- Kotlin / Java —
okhttp3.mockwebserver.MockWebServer. - Swift —
URLProtocolsubclass, orSwifter/Embassyfor a real socket. - Dart —
package:shelfin a local server orhttp_mock_adapterfor Dio. - TypeScript —
msw(preferred), ornockfor low-level Node interception.
Kotlin example with MockWebServer + Retrofit + Room:
class OrdersSyncIntegrationTest {
private val server = MockWebServer()
private lateinit var db: AppDatabase
private lateinit var sut: OrdersRepository
@Before fun setUp() {
server.start()
db = Room.inMemoryDatabaseBuilder(ctx, AppDatabase::class.java).build()
val api = Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(MoshiConverterFactory.create()).build().create(OrdersApi::class.java)
sut = OrdersRepository(api = api, dao = db.orderDao(), clock = FixedClock(T0))
}
@After fun tearDown() { server.shutdown(); db.close() }
@Test fun sync_persists_and_deduplicates() = runTest {
server.enqueue(MockResponse().setBody(readFixture("orders/list_v1.json")))
sut.sync()
sut.sync() // second call: same payload
val stored = db.orderDao().all()
assertEquals(3, stored.size) // no duplicates
}
}
3. MSW for React Native
import { setupServer } from 'msw/node';
import { http, HttpResponse } from 'msw';
const server = setupServer(
http.get('https://api.example.com/orders', () =>
HttpResponse.json([{ id: 1, totalCents: 1999 }]))
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test('sync persists orders', async () => {
const repo = new OrdersRepository(api, db);
await repo.sync();
expect(await db.orders.count()).toBe(1);
});
4. Time, Retries, and Flakiness
- Inject a clock / ticker so retry tests do not actually sleep.
- Drive any exponential-backoff retry with a virtual scheduler (
TestDispatcher,RxJS TestScheduler,fakeAsync). - Never put real
Thread.sleep/Task.sleep/Future.delayedin integration tests.
5. Seams Worth Integration-Testing
- Repository + remote + local cache — "fetch, cache, offline read, refresh".
- DTO → domain → DTO round-trips — serialization edge cases (nullable fields, enum unknowns, ISO-8601 timezones).
- Migration + data-access — run a real migration, then a real query.
- Token refresh flows — auth interceptor on 401 → refresh → retry.
6. Avoid Over-Integration
If the same thing can be verified by a unit test, write the unit test. Integration tests cost more to maintain:
- Slower by orders of magnitude.
- Harder to pinpoint failures (multiple suspects).
- More setup scaffolding to keep in sync.
Rule of thumb: one happy-path integration test per seam; everything else goes in unit tests unless it genuinely requires the seam.
7. Test Data Shared Across Layers
Commit JSON fixtures under testdata/ and reuse them in unit mappers, integration flows, and contract tests. Drift is the enemy — one fixture per shape, referenced everywhere.
8. Error-Path Integration
Exercise at least these error paths per seam:
- Network 5xx with and without
Retry-After. - Malformed JSON.
- Empty body / 204.
- Timeout.
- Disk-full / SQL constraint violation (in DB integration).
9. Checklist
- Uses real HTTP server (MockWebServer / msw / shelf), not in-process interception only.
- Uses in-memory DB where applicable; no real filesystem outside temp dirs.
- Clock and dispatchers are injected; no real sleeps.
- Happy path and at least one network error, parse error, and DB error are covered.
- Fixtures are shared with unit and contract tests via
testdata/. - Test runs on the host runtime, not a device or emulator.
- Setup and teardown leak no state (server shutdown, DB closed, pending jobs cancelled).
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.