Integration testing
Skill almasumdev/awesome-mobile-testing-agent-skills/.github/skills/integration/integration-testing
Agent skills for unit, widget, UI, and end-to-end testing of mobile apps across platforms.
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.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
5.1 KB, 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).