Zington logo

Den perfekta stub-servern

Stubbning är en variant av test doublesSystemer-sättningar för test avseende funktioner, integrationer eller data som underlättar decouplingIsärbrutna beroenden till andra system av system och systemkomponenter i testmiljöer. Detta möjliggör trygga tidiga tester utan att behöva vänta in utveckling, deploy och avlusning av system man har beroenden till.

DIREKT TILL ÖNSKELISTAN

Vad är egentligen stubbning?

Stubbning handlar om att ta bort beroenden till externa system genom att ersätta de externa systemen med något som svarar på anrop och förfrågningar i dess ställe. Konceptet kallas även avintegrering eller de-coupling och för att åstadkomma detta använder man s.k. stubbarPyttesmå låg-intelligenta tjänster som ersätter externa system och papegojar tillbaka de svar man förberett dem med som svarar på anrop i stället för de riktiga kringliggande systemen.

Det är viktigt att testa sina API:er både utifrån konsument- och producent-perspektivet. Det är oftast betydligt enklare att testa de API:er man är producent för eftersom det är lätt att använda ett verktyg som Postman eller ReadyAPI, eller något av alla webbläsar-plugins som finns för att testa REST-tjänster. Utmaningen kommer ofta när vi ska testa som konsument av ett externt API. Det är då vi måste stubba.

Varför stubba?

IT-landskapen har de senaste decennierna blivit alltmer komplexa. Många organisationer har tusentals IT-system och det blir allt svårare att genomföra kvalitetssäkringsaktiviteter i testmiljöer med alla system ihopkopplade med sammanhållet testdata.

Komplext organiskt nätverk av system
Komplext organiskt nätverk av system

Även om man gör det djärva antagandet att fel inte propageras i flera led mellan system blir det ändå många kringsystem att få i rätt version och konfiguration och rätt testdata för att kunna genomföra ett test.

Om man använder integrerade testmiljöer till att avlusa sitt system får vi räkna med att även andra system gör detsamma. Det betyder att vi inte kan lita på något av de omkringliggande systemen heller i dessa miljöer. Förtroendet för våra testers resultat blir lågt.

Endast de närmsta kringliggande systemen
Endast de närmsta kringliggande systemen

Genom att stubba de integrationer/samband vi behöver till andra system får vi kontroll över vår testmiljö. Vi får en långt lägre komplexitetsgrad och betydligt enklare att genomföra t.ex. negativa testfall.

Ju mer man kan testa av ett applikationssystem innan man behöver flytta det till en miljö med riktiga systemintegrationer, desto effektivare kvalitetssäkring blir det.
Förutsättningarna för att automatisera tester i en fullt integrerad testmiljö är närmast obefintliga på grund av testdata-hanteringen, och ibland även på grund av autentiserings- och auktoriseringsmekanismer.

Stubbade samband
Stubbade samband

Testautomatisering

Att exekvera automatiserade tester konsumerar testdata. Vid scriptutveckling eller debugging är det mödosamt och tidskrävande att arbeta i testmiljöer där man måste tillrättalägga testdata i andra system än sitt eget - och i ärlighetens namn kan det ibland bli övermäktigt att tillrättalägga testdata även i det system man faktiskt testar. Då kan man stubba bort databasen eller de extrna systemen.

Typer av integrationstester

Man brukar kunna dela upp integrationstesterna i flera komponenter som kan utföras separat för klok effektivitet:


System integration testing in the small Systemintern test av komponentintegration (vertikal integration eller mellan komponenter).
Samverkanstest Uppfyller vi sambandskontraktet? Ursprungligen ett begrepp från telecom där man testar nätverksutrustning och telefoner mot gränssnitts-compliance innan de sätts in i riktigt nätverk där de riskerar störa annan utrustning.
Sambandstest Når vi fram till det externa systemets gränssnitt. En form av smoketest för att säkerställa att fortsatta tester är givande.
Systemintegrationstest (system integration testing in the large) Kan vi genomföra verksamhetsprocesser end-2-end i fullt integrerad miljö och med produktionslikt data.

Att utföra alla typer av tester på de sista nivåerna blir hindrande för snabb time-to-market, försvårar debugging och felanalys och innebär att mycket testmöda och testtid läggs på testförberedelser snarare än testutförande.

Fördelar med stubbning

Möjlighet till branschad utveckling Utan att kunna testa vårt system fristående blir det svårt att hålla flera utvecklingsbranschar igång samtidigt och samtidigt göra tester över enhetstestnivån.
Enklare med negativa tester med omöjligt data Genom att man kan preppa testdata själv blir det lättare att åstadkomma de konstiga och knasiga data-variationerna.
Icke-skakiga testmiljöer Med stubbar slipper man interagera med buggiga kringliggande system och mycket miljökonfiguration, knasiga testdata-lägen i test och sönderskrivna databaser. Man får därigenom ett enklare och stabilare sätt att testa sin egen systemfunktionalitet.
Incitament till att versionshantera API-specifikationer och applikationskod separat Samband och gränssnitt mellan system ändras mindre ofta än applikationskoden i sig. Det är värt att versionshantera dessa separat, men kräver förberedda repositoryn för detta.
Stubbning kan vara incitamentet som får till detta.
GDPR-säkert Med en begränsad mängd testdata är det lättare att själv konstruera data som är GDPR-säkert - och lättare att återanvända detta eftersom man inte behöver så mycket testdata eftersom man inte konsumerar upp det i testerna.

Det är mycket svårt att tillfredställande pseudonymisera produktionsdata så att det inte går att spåra baklänges tillbaka till en faktiskt personuppgift. Detta ger risker att råka sända ut testmeddelanden till fysiska personer, risker att röja personer med hemlig identitet och risker för integritet.
Slipper behörighetsstök Om man kan stubba tjänster slipper man mycket av den ofta tidskrävande behörighetsadministrationen kring behörigheter för test som kommer med att interagera med det riktiga systemet. Det gillar både säkerhetsavdelningen och utvecklingsteamet.
Felsökningsbart Felsökning av ett avintegrerat system är mycket enklare än felsökning i ett stort och integrerat system. Ju mindre kodbas som kan härbergera felet desto snabbare går det att identifiera och åtgärda detta – vilket dessutom som bonus minskar risken att man bygger vidare på ett buggigt system och får ännu mer komplexa felelimineringsåtgärder senare.
Agil-anpassat Att implementera en affärsförändring i t.ex. en SAFe-organisation kräver ofta insatser från flera olika team, och kanske flera olika agila tåg. Dessa olika konstellationer jobbar mot olika backloggar och det är troligt att inte alla inblandade hinner klart i samma sprint. Att då behöva vänta på andra för att kunna testa vår applikationskod gör kvalitetssäkringen ineffektiv och bygger både risk och kanske teknisk skuld.
Risk-minimerat för organisationen Tester mot fullt integrerade system innebär stor risk för buggar. Dessa buggar kan riskera förstöra testdata i andra systems databaser och krångla till testläget för hela organisationen. Med buggar kan man testa tidigt på sin egen kammare, utan risk att krånga till det för andra.
Sönderkört testdata kan ta lång tid att återladda.
Slipper testa med dåligt produktionsdata Produktionsdata kan tyckas vara idealiskt, men det är egentligen oftast väldigt dåligt för tester. Produktionsdata innehåller bara sådant som hänt historiskt och inte sådant som kan komma att hända framöver. Ofta är datamängderna så stora att det är tungt att rulla tillbaka till tidigare testdatalägen, tungt att söka fram relevant testdata för just mitt testfall.
Moln-anpassat Stubbar kan snabbt startas och stoppas – eller hållas igång kontinuerligt. Oavsett är de påfallande enkla för snabb miljö-setup inför tester i samband med CI/CD-pipelines.

Begränsningar med stubbning

När man stubbar är det svårt med tester som kräver stora datamängder; migreringstester, batch-jobb-driven funktionalitet, prestandatester samt tester av t.ex. machine learning (ML) och andra typer av artificiell intelligens (AI), business intelligence (BI), data-warehouse (DW) och liknande.

En del typer av Software-as-a-Service (SaaS) och COTS saknar väldokumenterade API:er vilket försvårar för stubbning.

Vi kan heller aldrig bli helt säkra på att affärsflöden fungerar i sammankopplade system om vi inte testar dessa under så produktionslika former vi kan. Vi kan bara bli tryggare med att det kommer att fungera när vi väl kopplar ihop systemen - och det är mycket värt i sig.

För system med stor komplexitet i datasamband kan man behöva spela in svaren till stubbarna för att det ska hänga ihop. Exempel på sådant data är inom bank- eller försäkringsbranschen.

För att effektiv stubbning ska fungera finns det visa förutsättningar som måste vara uppfyllda redan:

  • Kommunikationsarkitektur som bygger på API:er
  • Mekanism för versionshantering av API-specifikationer och access till dessa
  • Disciplin kring att säkerställa att API-specifikationer alltid är uppdaterade

Stubbing underlättas också av att man har en lös länkning mellan system så att man inte behöver kompilera om för att byta integrationsinställningar.

Visst går det att stubba Enterprise Java Beans (EJB), Remote Method Invocation (RMI), CopyBook, Kafka, DCOM, Remote Procedure Call (RPC), Stored Procedures och liknande också. Det kräver dock vanligen också att man utvecklar mer själv eller använder någon form av produkt för Service Virtualizaiton (se nedan).
Det vanligaste är att stubba REST- och SOAP-tjänster.

Alternativ till stubbning

Mockning

Det vanligaste alternativet till stubbning vid tidiga och utvecklarnära tester är mockning. Vid mockning byter man ut delar av programkoden mot annan kod som tjänar testet väl.

Det råder en viss begreppsförvirring kring begreppen mockning och stubbning, och ibland kan uppdelningen kännas akademisk. Det är bra att veta att begreppen stundom används synonymt.

Mockade samband
Mockade samband där man bytt ut delar av sin applikation för att komma åt att testa

För mockning kan man t.ex. byta ut hela sin Authenticate-klass för BankId mot en annan som bara returnerar att man är autentiserad.

Det finns massor av olika mockningsramverk och mockningshjälpmedel.

Stubbning på enterprise-nivå: Service Virtualization

Åtskilliga leverantörer för testverktyg tillhandahåller även verktyg för Service Virtualization. Det är verktyg som hjälper till att underhålla och samordna stubbar för hela organisationer.

På liknande sätt finns det åtskilliga leverantörer av integrationsplattformar som tillhandahåller möjligheter till att virtualisera tjänster. I deras fall kallas det ofta för mockar eftersom de byter ut en del av programbeteendet i sin egen produkt (se definition ovan).

Dessa lösningar är ofta kompetenta men omgärdas av begränsningar eftersom de kräver licenser och specialistkunskap vilket gör att det alltid verkar bli linjefunktioner som managerar dessa, och ingen vill vänta på att tillrättalägga testdata så de blir oanvända.

Hur kommer man igång?

Stubbning är inte ett okänt koncept bland utvecklare. De senaste åren har det dessutom blivit mycket lättare att stubba.

Initiativet till att börja stubba kommer ofta från DevOps-intresserade tekniska testare eller seniora utvecklare. För dem är fördelarna ofta väldigt tydliga och man ser stubbning som en självklar strategi för effektiv utveckling.

Om man sitter med ett gammalt legacy-system med en massa integrationer och systemsamband upplevs stubbning lätt som betydligt krångligare.
I de fallen kommer man ofta igång eftersom man upplevera att man har testdatautmaningar, och generellt börjar de då med samband/integrationer till organisationsexterna system, eftersom dessa ofta anses som de krångligaste och mest tidsödande.

Många organisationer har publika API:er i samband med t.ex. Open Banking eller myndigheternas direktiv för öppet data.
Har man publika API:er vill man också tillhandahålla sandbox-miljöer till de organisationsexterna organisationer som använder dessa så att de kan bygga lösningar och testa lösningar mot dessa. I det sammanhanget är stubbar ovärderliga.

Numera är det många verktyg som kommer med egna stubbar. Det går t.ex. att stubba direkt i SwaggerUI - verktyget för att grafiskt utforska och testa API:er.

Verktyg som Postman och ReadyAPI kommer med egna stubbmekanismer och alla de större verktygsleverantörerna har inbyggda stubbningslösningar i sina testautomatiseringsverktyg.
Om man sträcker sig efter enterprise-lösningar kommer flera integrationsplattformar och API Management-lösningar inkluderade med lösningar för stubbning, som dock i deras fall ofta kallas för mockar.

Som tidigare nämnts tillhandahåller större mjukvaruleverantörer, som t.ex. CA, MicroFocus och IBM, verktygslösningar för Service Virtualization på enterprise-nivå. Sådana lösningar kan användas för större mockningsinitiativ.

Egenskaper hos den perfekta stubbservern

Då kommer vi till pudelns kärna. Vad önskar jag mig av det perfekta stubbhjälpmedlet?
Följande kravlista är en början:



Önskelista

Litet smidigt verktyg för att kunna checkas in/användas jämte applikationskoden.
Integreringsmöjlighet med eventuell testautomatiseringslösning.
Full kontroll av testdata från API-konsumentens sida (mandat, behörigheter, förståelse).
Kunna startas och stoppas i CI/CD-pipeline i samband med tester.
Kunna förses med svarsdata (förberedda responses) via ett eget API för mångsidighet vid testautomatisering.
Kunna hantera att simulera alla relevanta transportmekanismer för data över företaget (MQ, HTTP(S), FTP, WCF o.s.v.).
Kunna hantera att simulera alla relevanta transportmekanismer för data över företaget (MQ, HTTP(S), FTP, WCF o.s.v.).
Stöd för att hantera använda säkerhetslager som inte kan abstraheras bort (klientcertifikat, basic auth, OAuth2 o.s.v.).
Inspelningsförmåga för att kunna skapa testdatastubbar, eller generering från API-specifikationer (=Swagger-filer/OpenAPI, XSD, XSLT o.dyl.).
Inbyggd validering av JSON-data och XML-data mot schema, och av tjänster mot XSLT-beskrivningar.
Dynamisk run-time-substituering av data i svaren från stubben, för t.ex. timestamps och korrelerade sessionsvärden.
Flertal metoder för att identifiera vilket svar den skall skicka. T.ex. genom att kombinera en eller flera av följande:
  • Skicka tillbaka senaste mottagna meddelande.
  • Välj svar att skicka beroende på URL-endpoint.
  • Välj svar att skicka beroende på URL-parametrar.
  • Välj svar att skicka beroende på vilken server som ställer frågan (HTTP Origin header).
  • Välj svar att skicka beroende på innehåll i HTTP Request (HTTP body, HTTP verb, Header-värden o.s.v.).
  • Välj svar att skicka beroende på tid på dygnet.
Möjlighet att sätta en delay innan svar skickas.
Möjlighet att själv designa svarsmeddelande (t.ex. HTTP svarskod, headers och body) på returnerade meddelanden.
Möjlighet till slip-through - att om man inte har ett registrerat svar att skicka går frågan vidare till bakomliggande system.


Av dessa är slip-through-funktionalitet det jag själv använt minst eftersom användning av sådan kommer med en risk att få korrupt data-läge mellan olika system i testmiljöerna.




Vad tycker du själv är viktiga krav på en stubbningslösning?

Meddela mig dina tankar.




Avslöja tidigare dolda tankar om testansvar för API:er

Ansvar och ägarskap för stubbar

Det går inte att säga något generellt, men ett allmänt förslag på uppdelning av ansvar kan te sig enligt nedan.

Centralt ägt och managerat i organisationen

Agilitet hindras lätt av centralstyrning. Den centralstyrning som kan vara motiverad handlar om storskalighet genom Center-of-EnabelmentEn central organisationsfunktion med ansvar att se till att andra kan arbeta effektivt.

Centralt ansvar utgörs av att tillhandahålla/samordna/koordinera centralt tillhandahållna lösningar för Service Virtualization och kommunicera till tåg, team och andra intressentgrupper inom organisationen hur dessa ska användas (utbildningar, guider och liknande handledningar). Om man har centralt hanterade verktyg för stubbning eller service Virtualization bör man även ha centrala testmiljöer för dessa verktyg så att de kan testa patchning av dessa verktyg utan att störa övrig testverksamhet inom organisationen emedan detta verktyg är en central infrastruktur för många inom organisationen. Centralt ansvar inkluderar även att tillse att backup tas av verktyg för stubbning/mockning.
I ansvarsområdet ligger även att ta fram riktlinjer för versionshantering av API:er.
I detta ansvar inkluderas även att tillhandahålla möjlighet till validering av data mot en viss version av ett APIs specifikation.

API-producent

När det gäller avintegrering måste ansvaret för att hålla gränssnittskontraktet (Swagger/OpenAPI specification/XSLT osv) uppdaterade och korrekta ligga hos producenten. Versionshantering av specifikationer är en viktig komponent för effektivitet. Det producerande systemet har också ett ansvar att hålla reda på vilka konsumenter som finns för ett visst API för att kunna kommunicera när uppdateringar av specifikationer skett samt producera eventuella release-notes/incheckningskommentarer för sådana ändringar. Product Owner för producerande system har som ansvar att kommunicera status för önskade ändringar som är initierade av konsumerande system tillbaka till dessa. Om ett konsumerande system önskar exempeldata för ett API åligger det producerande system att tillhandahålla sådant.

API-konsument

Om ett konsumerande system har behov av förändringar av ett API de konsumerar åligger det dem att påtala detta för producerande systems Product Owner. En API-konsument har ansvar över testdata i ett stubbat API. Tidiga tekniska tester i utvecklingsteamen Det finns flera sorters tidiga utvecklartester. Enhetstester testar minsta möjliga enhet som är lämpligt för att kunna verifiera funktionalitet. Det kan t.ex. utgöras av klasser eller metoder – eller hela program. För att kunna testa klasser eller icke-statiska metoder behöver de instansieras, och för detta kan det krävas ytterligare objekt av helt andra klasser; klasser som då enklast mockas för att få fristående tester med bara det nödvändigaste tillrättalagt enkelt för testerna. Det finns gott om olika utvecklarverktyg för mockning och de underlättar förståelse för testerna samt underhållet av dessa. På en högre abstraktionsnivå är det ofta lämpligt att utvecklare även implementerar tekniska tester av t.ex. API endpoints. Då testas vanligen hela systemet i en form av systemtest. För att klara detta kan man behöva både en REST-server att skicka frågor mot, men också en HTTP-klient som skickar frågor till vårt system.
Båda dessa kan anses vara stubbar.

Fortsatt läsning: