Integratietesten controleren de correctheid van interactie tussen componenten van een mobiele applicatie — modules, services, databases en externe API’s. In tegenstelling tot unittesten die elke component isoleren, detecteren integratietesten fouten op de raakvlakken: incompatibiliteit van dataformaten, storingen bij parameteroverdracht en onjuiste verwerking van serverreacties. Volgens Martin Fowler, 2018 dekken integratietesten tot 40% van de kritieke defecten die door unittesten worden gemist en geven ze vertrouwen in de stabiliteit van het systeem voor release.
Belangrijkste punten
Integratietesten — is de fase van softwareverificatie waarin de correctheid van interactie tussen afzonderlijke modules of subsystemen van de applicatie wordt geëvalueerd. Terwijl unittesten elke component geïsoleerd controleren, brengen integratietesten deze componenten samen en controleren ze hoe ze in combinatie werken. Typische scenario's omvatten gegevensoverdracht tussen de netwerklaag en repository, schrijven naar de database via ORM en verwerking van reacties van externe API's.
In de context van mobiele ontwikkeling dekken integratietesten de interactie tussen de UI-laag, bedrijfslogica en gegevensbronnen. Een test kan bijvoorbeeld controleren of de applicatie na het indrukken van de knop 'Inloggen' een verzoek naar de server stuurt, een token ontvangt en dit in de lokale opslag bewaart. Een dergelijke verificatie bevestigt dat de componentketen zonder storingen werkt.
Volgens het World Quality Report 2023 verminderen bedrijven die regelmatig integratietesten toepassen het aantal productie-incidenten met 35% in vergelijking met projecten die alleen op unittesten vertrouwen. Dit maakt integratiecontroles een verplicht onderdeel van de kwaliteitsborgingsstrategie in commerciële ontwikkeling.
Mobiele applicaties bestaan uit vele onderling verbonden componenten: netwerkverzoeken, lokale databases, pushmeldingen, systeemservices en externe SDK's. Elk van deze componenten wordt afzonderlijk ontwikkeld, maar tijdens runtime wisselen ze in realtime gegevens uit. Integratietesten detecteren defecten die niet kunnen worden gevonden bij geïsoleerde modulecontrole.
Tot de typische problemen die door integratietesten worden ontdekt, behoren type-incompatibiliteit tussen API en applicatiemodel, JSON-serialisatiefouten, onjuiste verwerking van netwerk-timeouts en storingen bij parallelle databasetoegang via Room of Core Data. Zonder integratiecontroles komen dergelijke defecten in productie terecht en manifesteren ze zich alleen bij echte gebruikers.
Onderzoek van Google Testing Blog (2021) toont aan dat de kosten van het herstellen van een defect dat in de integratietestfase wordt ontdekt, 5 keer lager zijn dan na release. Dit komt doordat de ontwikkelaar in een vroeg stadium de volledige foutcontext heeft en deze kan herstellen zonder een urgente hotfix-cyclus. Tijd investeren in het schrijven van integratietesten betaalt zich terug door lagere onderhoudskosten en meer gebruikersvertrouwen.
Er zijn drie hoofdbenaderingen voor het organiseren van integratietesten: Big Bang, Bottom-Up en Top-Down. De keuze van strategie hangt af van de projectomvang, applicatiearchitectuur en beschikbaarheid van componenten op het moment van testschrijven. Elke benadering heeft zijn voor- en nadelen die belangrijk zijn om te overwegen bij het plannen van testdekking.
Big Bang — een benadering waarbij alle systeemcomponenten tegelijkertijd worden verbonden, waarna een algemene testrun wordt uitgevoerd. Deze methode is eenvoudig te implementeren: het vereist geen stubs of emulatie van afzonderlijke modules. Bij het detecteren van een fout is het echter moeilijk te bepalen welke component de bron is. Big Bang is gerechtvaardigd in kleine projecten met een eenvoudige architectuur, waar het aantal modules niet meer dan vijf bedraagt.
Bottom-Up — een strategie waarbij integratietesten beginnen met laagwaardige componenten: database, netwerklaag, systeemservices. Na controle van elk niveau verbinden tests geleidelijk hogere modules — repositories, Use Case-klassen en ViewModel. Het belangrijkste voordeel is vroege detectie van defecten in fundamentele applicatielagen, wat het risico op cascadefouten in latere ontwikkelingsfasen vermindert.
Top-Down — een benadering waarbij testen begint met componenten op hoog niveau — UI-schermen en navigatie, terwijl modules op lager niveau worden geïmiteerd met stubs of mocks. Dit maakt het mogelijk om gebruikersscenario's te controleren voordat de serverkant of database volledig zijn geïmplementeerd. Top-Down is vooral nuttig bij parallelle ontwikkeling van client en server, wanneer de backend nog niet klaar is voor echte integratie.
Voor integratietesten van mobiele applicaties wordt een reeks gespecialiseerde tools gebruikt die in drie categorieën vallen: bibliotheken voor serveremulatie, frameworks voor databasewerk en middelen voor systeemservicecontrole. De keuze van een specifieke tool hangt af van het platform — Android of iOS — en de technologiestack van het project.
Laten we praktische voorbeelden van integratietesten voor Android en iOS bekijken. Voor het Android-platform gebruiken we MockWebServer in combinatie met JUnit, voor iOS — XCTest met de OHHTTPStubs-bibliotheek. Beide voorbeelden controleren het scenario van het ophalen van gegevens van een API en het opslaan ervan in een lokale repository.
Deze test controleert of een Retrofit-verzoek naar de geëmuleerde server correcte JSON retourneert en de repository het antwoord omzet naar een domeinmodel. MockWebServer onderschept het verzoek en retourneert de opgegeven JSON, waarna de test het verwachte resultaat met het werkelijke resultaat vergelijkt.
class UserRepositoryTest {
private val mockServer = MockWebServer()
@Before
fun setup() {
mockServer.start()
}
@Test
fun fetchUser_returnsCorrectData() {
val json = "{ \`"id\`": 1, \`"name\`": \`"Alice\`" }"
mockServer.enqueue(MockResponse()
.setBody(json)
.setResponseCode(200))
val repository = UserRepository(
createRetrofit(mockServer.url("/").toString()))
val user = repository.fetchUser(1)
assertEquals(1, user.id)
assertEquals("Alice", user.name)
}
@After
fun tearDown() {
mockServer.shutdown()
}
}
Voor iOS gebruikt een vergelijkbare test OHHTTPStubs voor het onderscheppen van URL-verzoeken. De bibliotheek vervangt het serverantwoord op het niveau van het systeemframework URL Loading System, waardoor elke netwerkbibliotheek kan worden getest — URLSession, Alamofire of Moya.
import XCTest
import OHHTTPStubs
import OHHTTPStubsSwift
class UserRepositoryTests: XCTestCase {
func testFetchUser_returnsCorrectData() {
stub(condition: isPath("/users/1")) { _ in
return HTTPStubsResponse(
jsonObject: ["id": 1, "name": "Alice"],
statusCode: 200,
headers: nil
)
}
let repository = UserRepository()
let expectation = expectation(description: "fetch user")
repository.fetchUser(id: 1) { user in
XCTAssertEqual(user.id, 1)
XCTAssertEqual(user.name, "Alice")
expectation.fulfill()
}
waitForExpectations(timeout: 2.0)
}
}
Effectief integratietesten vereist het naleven van een aantal praktijken die de stabiliteit van tests verhogen en de onderhoudskosten verlagen. Isoleer externe afhankelijkheden: gebruik in-memory databases in plaats van productie-instanties en emuleer externe API's via teststubbibliotheken. Dit elimineert niet-deterministische storingen veroorzaakt door netwerkbeschikbaarheid of de status van externe services.
Handhaaf testonafhankelijkheid: elke integratietest moet geïsoleerd werken, zonder afhankelijkheid van resultaten van andere tests. Gebruik @Before- en @After-annotaties in JUnit of setUp en tearDown in XCTest voor het voorbereiden en opschonen van de testomgeving. Dit voorkomt wederzijdse beïnvloeding van tests en vereenvoudigt foutdiagnose.
Dek grensvallen af: integratietesten moeten niet alleen succesvolle scenario's (happy path) controleren, maar ook foutafhandeling — timeouts, HTTP-codes 4xx en 5xx, lege antwoorden, beschadigde JSON. Volgens Google Testing Blog (2022) houdt 60% van de productie-incidenten verband met onjuiste afhandeling van grensvallen die niet door tests werden gedekt.
Veelgestelde vragen
Unittesten controleren één klasse of functie in isolatie, waarbij afhankelijkheden worden vervangen door stubs. Integratietesten controleren de interactie van meerdere echte componenten — bijvoorbeeld de netwerkverbinding en database tegelijkertijd.
Het uitvoeren van integratietesten duurt meestal 2 tot 15 minuten, afhankelijk van het aantal tests en de complexiteit van de omgeving. Voor grote projecten wordt aanbevolen tests op te splitsen in parallelle jobs in het CI-systeem om de totale controletijd voor merge te verkorten.
In de eerste plaats worden integratietesten geschreven voor de netwerklaag, database en systeemservices — meldingen, camera, geolocatie. API-verzoeken naar de backend en bewerkingen met lokale opslag geven de hoogste ROI, omdat deze componenten het vaakst bronnen van regressies worden.
Voor één scherm zijn unittesten van ViewModel en UI-tests voldoende. Integratietesten voor één scherm zijn alleen gerechtvaardigd als het scherm met meerdere gegevensbronnen interageert — bijvoorbeeld antwoorden van twee verschillende API's combineert of gegevens tegelijkertijd naar het netwerk en de lokale database schrijft.
Integratietesten worden uitgevoerd bij elke pull request in de CI-pipeline en voor belangrijke releases. Ook wordt aanbevolen de volledige set integratietesten 's nachts uit te voeren (nightly build) om defecten gerelateerd aan wijzigingen in afhankelijkheden of testomgeving te detecteren.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook