Magical Thinking - Part 1: Cargo Cult Automation.

Cargo cults

During WWII, the US armed forces created a presence on pacific islands where the local population had little previous contact with foreigners. The soldiers built various military installations and airplanes would land with supplies. The vast amounts of military equipment and supplies that both sides airdropped (or airlifted to airstrips) to troops on these islands meant drastic changes to the lifestyle of the islanders.

With the end of the war, the military abandoned the airbases and stopped dropping cargo. In response, charismatic individuals developed cults among remote Melanesian populations that promised to bestow on their followers deliveries of food, arms, Jeeps, etc. The cult leaders explained that the cargo would be gifts from their own ancestors, or other sources, as had occurred with the outsider armies. In attempts to get cargo to fall by parachute or land in planes or ships again, islanders imitated the same practices they had seen the soldiers, sailors, and airmen use. Cult behaviours usually involved mimicking the day-to-day activities and dress styles of US soldiers, such as performing parade ground drills with wooden or salvaged rifles. The islanders carved headphones from wood and wore them while sitting in fabricated control towers. They waved the landing signals while standing on the runways. They lit signal fires and torches to light up runways and lighthouses.

In a form of sympathetic magic, many built life-size replicas of airplanes out of straw and cut new military-style landing strips out of the jungle, hoping to attract more airplanes. The cult members thought that the foreigners had some special connection to the deities and ancestors of the natives, who were the only beings powerful enough to produce such riches.
 
And yet, despite the islanders doing everything right, the planes didn’t return and the cargo didn’t drop. The physicist Richard Feynman drew parallels to pseudosciences like parapsychology and homeopathy in his 1974 commencement speech at the California Institute of Technology: They're doing everything right. The form is perfect. It looks exactly the way it looked before. But it doesn't work. No airplanes land. So I call these things cargo cult science, because they follow all the apparent precepts and forms of scientific investigation, but they're missing something essential, because the planes don't land.
 
I believe there is similar magical thinking in testing, where the appearance of good testing is strong, but the results are not. I’ll try a few examples.
 

Cargo cult automation

 A common statement is something like this:
 
"We can improve system quality with automated tests."
 
There are many problems with this statement. First of all, we’re probably not employing Weinberg-style whole systems thinking and talking about automated document reviews to make the requirements and design documents better. By "system quality", we’re using a much narrower definition which for all practical purposes equals code.
 
"We can improve program code with automated tests." 
 
is therefore a much more correct statement. But what about the word "automated"? Don’t we just mean programmed? Our statement now becomes:
 
"We can improve program code with programmed tests."
 
Which just means
 
"We can improve program code by writing more code."
 
And we’re not going to waste our programmers time on testing, are we? No. So we’re really saying:
 
"We can improve our code by having non-programmers write more code."
 
Somehow, I feel that the initial line is more convincing than the last one, while the last one is far more like what we are actually doing. This does not mean that automation is not useful, only that you need to get all the things right for it to work and not only the appearance of it all. For instance, it can be useful to figure out why you automate. Is it to repeat tests you’ve already done, or because you’re using the computers ability to do many things fast and repetitively? These are fundamentally different purposes.
 
Another thing is precision, accuracy and frequency. Unit tests typically have high precision in that they point at one line that is returning a wrong result. They also have high accuracy in that (at least if we’re using TDD) they usually point at something that is actually undesirable. Since they are written and used during periods of development, they are run with high frequency, usually on every build which is probably several times a day.
 
On the other extreme, we have full system tests. Such tests typically have fairly low precision; they would typically point to a large block of code that is not doing what we expected and much investigation is necessary before we can find out what is actually wrong. They also have low accuracy in that we usually don’t know if the problem is in the test, the test framework, the test data, or if the test fails because of a change that we actually want and the test is just out of sync with the system.
 
Then there is cost.
Those of you who learned to program in the seventies or early eighties, you may remember an idea called literate programming. This was introduced by Donald Knuth who is one of the great minds of computer science. The basic idea is that you write comments in a natural language, explaining what you are doing, why you are doing it, what alternatives you have considered and discarded and why. Then you add a few lines of compilable code that does what you have described and go on to explaining the next bit. This was a fantastic idea because it forced the programmer to think before coding which, in my personal opinion, is something that should be considered more often.
 
Sadly it was discarded because all the thinking and writing took time away from coding. Even though programmers who did take the time were more productive than the ones who did not.
TDD and unit tests have much the same effects in that by writing the test first, the programmer is forced to think explicitly through what he wants a function to do before writing the actual code.
Therefore automated tests on the unit level have negative cost.
Automating a complex, system-level test that has previously been performed by a thinking person does not have negative cost.

 
Coming up:

Cargo cult risk analysis

Cargo cult metrics

Gledene ved å ha en betagruppe!

Forfatter: Haavard Gulbrandsen, Promis Qualify

Innledning

Betagruppe, for mange ukjent, for noen bejublet! Det å definere hva man legger i begrepet "betagruppe" kan være vrient, men i utgangspunktet så er det at "vanlige folk" tester produktet ditt før det går i produksjon. Veldig ofte blir det da et fokus på å finne feil og ikke på hvordan produktet faktisk fungerer og om funksjonaliteteten gir verdi. Tilnærmingen kan forklares med et praktisk eksempel.

Praktisk eksempel

I et prosjekt som nå er over i forvaltning så besluttet vi å koble på sluttbrukere så tidlig som mulig i testprosessen i den tro at vi kunne luke ut feil så tidlig som mulig. Det å finne feil var i utgangspunktet det eneste målet da man tidligere i prosessen hadde sjekket ut at funksjonalitet o.l. var på linje med det kundene ønsket. Prosjektet gjennomførte en systemtestfase og slapp det til en betagruppe med sluttbrukere samtidig som vi tok det inn i akseptansetestfasen. Ved gitte intervaller så ble da produktet sluppet ut i produksjon. Den ansvarlige for betagruppene ble utpekt til å være Testleder med ukentlige statusmøter med kun fokus på Beta.

Testfaser 

De skjulte gledene ved en betagruppe

Etter kort tid fant vi ut at vi ikke bare fikk inn rapporter med feil men også forslag til endringer, forslag til nye features, rapporter om feil som ikke var relatert til selve appen men til feil som baksystemene våre ga. På grunn av dette endret vi målsetningen til det å ha betagruppe. Responsen vi ga på disse henvendelsene var å koble på spørreundersøkelser, release av features som vi var klare på at kanskje aldri kom i produksjon samt å sikre at vi hadde enda tettere dialog med brukerne enn før. Dette betyr at vi gikk fra intensjonen om å kun behandle feil på en smidig måte til å kunne utfordre resten av den interne organisasjonen vår på design, utforming av baksystemene og nye features.

Rekruttering

Måten vi rekrutterte sluttbrukere på var gjennom å annonsere på LinkedIn og ved å bruke facebookannonse. Dette sikret oss et godt utvalg brukere med forskjellige innfallsvinkler til vårt produkt og vi sikret at de var frivillige (ubetalte) og engasjerte. Vi hadde på forhånd ikke definert hvor mange sluttbrukere vi ønsket men siden dette var en app så ønsket vi Android og iOS brukere og helst da med et godt utvalg av forskjellige telefontyper og versjoner av operativsystemet. vi endte i første omgang på ca. 100 Android brukere og ca. 150 iOS brukere. Administrasjon Vi organiserte distribusjonen av Betaversjonene av appen via Testflight (iOS) og Playbutikken (Android), vi koblet også på et produkt som heter Instabug hvor brukerne kunne rapportere inn feil direkte fra appen til oss. I tillegg opprettet vi separate Google+ grupper for Android og iOS. 

Suksesskriterier

Jeg vil egentlig kun trekke frem ett kriterie, TETT DIALOG med sluttbrukerne! Dersom du oppretter arenaer hvor det er lett å kontakte selskapet direkte samt at man svarer på henvendelsene jevnlig og innbyr til dialog så blir brukerne hos oss. En annen fordel er at vi i vår dialog kan være løsere i snippen enn hva selskapet selv kan være i sin dialog med sine kunder. Vi har bl.a. oppnådd å få en grinete bruker til å bli vår ambassadør bare ved å ha dialog og samtidig levere og besvare henvendelsene på en konstruktiv måte.

Bidraget til Betagruppen

Betagruppen har bidratt jevnlig med feilrapportering, noe som har økt kvaliteten i produksjon. De har blant annet funnet en feil som gjorde at vi ved oppgradering av app ikke lenger hadde støtte for Instabug, vi ga feilmelding ved reisesøk ved hjelp av "mine steder" i enkelte sære tilfeller. tilfellene ble rettet og vi hadde fortløpende kontakt underveis. Medlemmene har selvjustis f.eks. ved å hjelpe andre medlemmer som "tror" de har funnet en mangel ved å fortelle hvor funksjonen faktisk ligger. De har gitt oss konkrete innspill som har resultert i at vi har endret linjefarger på fremkomstmidler, vi har gitt de muligheten til å prioritere i hvilken rekkefølge to funksjoner skulle bygges. Betagruppen har også gitt oss innsikt relatert til kartfunksjonen og dennes tidvis mangelfulle nøyaktighetsgrad. Til slutt så vil jeg trekke frem det å kunne hjelpe brukere som før var negative til produktet til å bli ambassadører ved at de har en følelse av tilhørighet og at deres stemme teller! Avslutning Betagruppen jeg har beskrevet er tilhørende appen Ruterreise (Ruter). Vi begynte med betagrupper for ca. 2 år siden og gruppen fortsetter å gi oss verdi den dag i dag. Verdien måler vi på flere felt:

  • Rapportering av feil i app
  • Rapportering av feil i fysiske reiseforslag
  • Endringsønsker
  • Tilbakemelding på spørreundersøkelser i Google+
  • Kommentarer på flyt i app

Måten vi har dialog på i dag kontra oppstarten er at vi i dag benytter Google+ gruppene oftere, samt at vi har endret fokus slik at vi nå ser på rapportering av feil som en bonus og konsentrerer oss om å sikre engasjementet internt i selve gruppen.

P.S kontakt oss på Denne e-postadressen er beskyttet mot programmer som samler e-postadresser. Du må aktivere javaskript for å kunne se den. for å bli med på reisen!

Utnytt testpotensialet i utviklingsteamet!

Forfatter: Pål Berg, Promis Qualify

Skal man lykkes med prosjektet, så må man lykkes med testingen. Og skal man lykkes med testingen, så må man engasjere alle de gode kreftene man har til rådighet.

Men det viktigste er tross alt å få inn kvalitetsmentaliteten i det daglige arbeid, slik at at dette blir en integrert del av måten å jobbe på gjennom hele sprintforløpet / utviklingsløpet.

Jeg vil i denne artikkelen beskrive en smidig setting, men overnevnte setning gjelder for de fleste, kanskje alle, typer utviklingsmetodikker og -prosesser. Jeg har også valgt å benevne teamet i entall, men dette er selvfølgelig også relevant i prosjekter med flere utviklingsteam. Man kan etterstrebe denne måten å jobbe på i ett, flere eller alle teamene i prosjektet.

Det finnes mange måter å rigge et smidig prosjekt på, men i alle tilfellene legges det et visst testansvar på utviklingsteamet. I virkelig autonome team har teamet ansvaret til og med systemtest innenfor hver sprint. Dette er ofte en krevende øvelse, spesielt når det som oftest er fokus på å levere flest mulig brukerhistorier. Dermed er det fort gjort at man i løpet av sprinten setter av for lite tid til test. Men det man da ofte erfarer, er at man leverer med for høy risiko og ender opp med å bruke mye av utviklingskapasiteten i de kommende sprintene til feilretting.

Tradisjonelt sett er det vanlig å ha en testleder som planlegger, skriver og gjennomfører testingen. Testleder gjør dermed testingen, mens utviklerne lager løsningene. Det er ganske vanlig at man kjører såkalt testdrevet, ved at utviklerne lager automatiserte enhetstester som skal verifisere at implementert kode er riktig. Men testing etter det overlates til testleder. 

Ansvar

Hvor bør så testansvaret plasseres?

I utgangspunktet så er det utviklingsteamet som har ansvaret for den kvaliteten de leverer. Test lead er den i teamet som har testansvaret. I noen tilfeller så er dette en utvikler som, i tillegg til sine utviklingsoppgaver, har testansvaret i inneværende sprint. Test lead-ansvaret kan gå på omgang mellom utviklerne.

Ønsker man testfokus fra en som har test som første prioritet kan man tildele test leadansvaret til en testleder. En testleder er en som har test og testledelse som hovedfokus. En testleder er også ofte involvert i det funksjonelle arbeidet og å definere testbetingelser.

Men selv med en testleder i teamet så må hele teamet bidra i testarbeidet. Mange utviklere er med sitt analytiske og nøyaktige tankesett også gode testere, og de kan bidra med å:

  • Skrive systemtestcaser
    • Og dermed bruke test design for ytterligere å øke forståelsen for funksjonaliteten
  • Kjøre testcaser
  • Automatisere tester
    • Automatisere enhetstester
    • Systemtester/ende-til-ende-tester som automatiseres og inngår i regresjonstestene
  • Gjøre løpende utforskende testing
  • Lage testverktøy og simulatorer
  • Administrere testmiljøer og slippe testversjoner

Så hvordan får man til dette?

Man må få til en holdning i teamet slik at hele teamet er med på test. Og at man begynner å jobbe med test helt fra starten av i hver sprint. Det gjelder alle testoppgaver innenfor mandatet til teamet. Test lead påser at alt testarbeid blir gjort, men gjør på ingen måte alt testarbeid selv.

Test må inn i sprintestimeringen og sprintplanleggingen. Testaktiviteter må få egne lapper pr brukerhistorie, f.eks.:

  • Skrive systemtestcaser
    • Basert på brukerhistorier, testbetingelser og akseptansekriterier. Ofte så vil det her være behov for avklaringer som igjen gir øket forståelse for hva som ønskes levert. Til nytte i både test og utvikling.
  • Gjøre løpende utforskende test i sprinten etterhvert som funksjonaliteten legges i testmiljøet for utvikling. 
  • Kjøre systemtestcaser i systemtestmiljøet.
    • Dette er den formelle systemtesten i slutten av hver sprint som danner grunnlaget for suksessen til sprintdemo og er med i underlaget for kontrollpunktstestingen.
  • Kjøre regresjonstester. Det beste er at man har et automatisert opplegg for dette. Men det kan likevel være nyttig i slutten av hver sprint å kjøre en begrenset manuell regresjonstest av den aller viktigste funksjonaliteten.

 

Disse lappene må opp på sprinttavla og kan plukkes blant alle medlemmene i teamet. Man må derfor få formidlet tydelig at det ikke er bare test lead som skal plukke disse lappene. Når de henger på tavla blir det veldig synlig hvilke oppgaver som må gjøres som neste. Bl.a. "skrive testcaser" gjør seg ikke så godt i kolonnen for ikke påbegynte saker etterhvert som tiden går.

 

Det er min erfaring at hvis test lead setter i gang med utforskende testing, med mål om å fjerne de fleste feil før brukerhistorien går inn i systemtest, så er det en oppførsel som har en tendens til å spre seg. I de tilfellene så blir systemtesten først og fremst formelt å verifisere at funksjonaliteten fortsatt virker når man skal kjøre demo. Fordi de fleste feilene er allerede funnet og rettet før systemtesten har begynt. Rapportering og retting av feil funnet i den utforskende testingen gjøres vha et en tabell på en wiki-side.

 

Eksempel på wiki-tabell brukt til å rapportere og følge opp bugs og avvik som oppdages i uformell test før systemtest:

Sakene som ikke rettes og verifiseres før systemtest er startet, må rapporteres som bugs i feilrapporteringssystemet.

Team Dream - Sprint 5

#
Beskrivelse
Rettet
Verifisert
Jira-sak
Kommentar
1 Får ikke logget på (huk av) (huk av)    
2 Får timeout ved førstegangssøk (feil)   SOL-1456  
3 Inkonsistens mellom app og baksystem (huk av) (feil) SOL-1477 Fortsetter feilrettingen i systemtest
4 Feil farge på alarmknapp (huk av) (huk av)    

Det er viktig få opp bevisstheten for at det å skrive systemtestcaser er med på å øke forståelsen for den brukerhistorien man skal implementere. Så denne aktiviteten kan, allerede før man begynner implementeringen, være med på å øke kvaliteten på både krav og implementasjon.

I en organisasjon der det finnes testleder både på kunde og leverandørsiden er det meget viktig at kundens testleder backer leverandørens testleder i arbeidet med å bevisstgjøre og engasjere hele teamet i kvalitetsarbeidet.

Ekstraservice - testaktiviteter som kan arrangeres på utsiden av sprintene

I tillegg til det pågående iterative arbeidet kan man arrangere eventer og arrangementer der man ønsker å oppnå at man dykker enda dypere ned i kvaliteten, f.eks. ved å gjøre det lystbestont.

Man kan arrangere "testcamp"eller  "bughunt", f.eks. en halv dag hvor designere tester hverandres design, android utvikler tester iOS og motsatt. Kundefront tester usability, prosjektleder gis et område av scope som skal testes, marked får beskjed om "make it break".

Man kan med fordel legge det opp som en konkurranse. Med heder, ære og premier.

Etter at alle utviklingssprintene i en delleveranse er fullført, kan man planlegge inn en "herdingssprint". Dette er en sprint for å fullføre feilretting og gjøre en helhetlig regresjonstest av ny og gammel funksjonalitet. En fare med slike herdingssprinter er at man bruker den til å øke scopet og levere ny funksjonalitet. Det er viktig at dette unngås. Dette er kun et kvalitetshevende tiltak etter at all kontrollpunktstesting er kjørt, men før akseptansetesten skal i gang.

Avslutningsvis

Testcamps og lignende tiltak fungerer bra til bl.a. å promotere testing, men bør helst være et tillegg til et vellykket testopplegg, ikke en kvikkfiks for å bøte på manglende testarbeid underveis i sprintene. Det kan være et vellykket avbrudd i det daglige arbeidet, men det er viktig at det ikke gir deltagerne inntrykk av at dette på noen måte er et tilstrekkelig bidrag. Men det kan f.eks. skape en konkurransesituasjon mellom utviklingsteam som kan gi økt fokus på å levere god kvalitet. Ingen liker at et annet team finner feil i den delen av løsningen man selv skal være ekspert på.

Bilder fra Unsplash

GDPR og hvorfor vi ikke kan bruke skarpe testdata

Forfatter: Richard Rostad, Promis Qualify

Bilder hentet fra: https://unsplash.com/photos/

NAV lagrer og vedlikeholder sensitiv personinformasjon om nesten alle mennesker i Norge. Å bevege seg bort fra å bruke skarpe date i utviklingsmiljø handler litt om verktøy, metoder og teknologi, men aller mest om organisasjonsstruktur og finansiering. NAV beveger seg bort fra den gamle fossefall-tankegangen (med kontrakter på anbud), til å bli å bruke smidig utvikling med egne utviklere og syntetiske data. Denne artikkelen handler derfor om to (litt ulike) sider av samme sak: Hvordan skal man organisere seg for å lykkes i en smidig verden, og hvordan kom vi fram til brukbare syntetiske testdata for utviklingsteamene våre?

Syntetiske testdata har flere potensielle fordeler: Bedre kontroll over uvanlige datakombinasjoner, hurtig generering av testsett for ytelsestest, samt spesifikke testsett som bestilles av andre konsumenter, og på toppen av det hele har du innbakt samsvar med GDPR. Selv om disse fordelene slår et godt slag for syntetiske testdata, er det ingen som har påstått at det var lett å få til. For å få til dette må man ta hensyn til kjente problemstillinger, ukjente problemstillinger, samt problemstillinger som viste seg å ikke være problemstillinger en gang, i dette nye regimet. Første delen av artikkelen tar for seg de administrative delene, del to ser på de tekniske løsningene vi fant, samt utfordringene vi fant underveis. Flesteparten av de tekniske problemstillingene finnes fordi NAV IT er skrudd sammen av over 200 forskjellige IT-systemer fra de siste fem tiår.

Tekniske grunner til ikke å bruke skarpe data

Forbruk av testdata

Testing med skarpe data representerer flere tekniske problemer. Først og fremst forbruk av testdata, i NAVs tilfelle betyr det forbruk av personinformasjon. En gitt person når pensjonsalder kun én gang, og når denne hendelsen er saksbehandlet i et testmiljø er det vanskelig å tilbakestille personen til en tilstand før pensjonsalder. Ytelsestester forbruker eksepsjonelt store mengder skarpe data, dette begrenser mengden testing som kan foretas.

Videre vil det brukes store mengder tid til å søke opp spesialtilfeller og disse grensetilfellene blir enda raskere brukt opp enn normale testdata. Ved å kunne produsere persondata til spesielle behov blir det betydelig enklere å finne en person med påkrevde kriterier for testing av grenser og kompliserte saksbehandlingstilfeller.

Testautomatisering

Testautomatisering med skarpe data blir fort avhengig av systemets tilstand i produksjon slik at man ikke får adskilt test og testdata. Det betyr som over at automatiserte tester ofte kan kjøres kun én gang mellom hver gang det lastes nye data fra produksjon over de eksisterende, noe som gjør gevinsten av automatisering betydelig mindre. Videre får man problemer når data i produksjon endrer seg og alenemoren plutselig er gift. Hvis man kan generere data som passer til testen ved behov forsvinner alle disse problemene.

Mange testmiljøer som må være synkronisert

NAV har over 200 forskjellige systemer som i særs stor grad forholder seg til det samme datasettet, som er Norges befolkning. Saksbehandling / endringer av personer i ett miljø kan forårsake at testdata for et annet system blir invalidert slik at tester feiler. Dette forårsaker unødvendig mye tid brukt på feilsøking. Igjen forsvinner problemet ved muligheten for å generere data som passer testen ved behov, istedenfor å basere seg på eksisterende produksjonsdata.

Test Doubles blir avhengig av produksjonsdata

Man har også problemer ved forsøk på mocking og stubs av perifere systemer der stub'en også må speile eksisterende produksjonsdata. Dette gjør testgrensesnittene betydelig mindre fleksible og vanskeliggjør isolering av problemer og feilsøking.

Totalt i NAV ser man at omkring to tredjedeler av innsatsen som kunne blitt benyttet til faktisk testing blir benyttet til søking, flytting og annen preparering av produksjonsdata. En enkel og lett tlgjengelig metode for ad-hoc generering av relevante data ville ha enormt potensiale for innsparinger eller heving av kvaliteten på NAVs systemer.

Motforestillinger

Den største motforestillingen mot syntetiske data er at de ikke er "levende", i den forstand at det ikke blir født nye barn, personer blir ikke eldre etc. Dette er enkelt å komme rundt ved å ha skedulerte jobber som genererer hendelser og om ikke det minste problemet med syntetisering, så ihverfall blant de enkleste.

 

Behov

Syntetiseringsprosjektet hos NAV har identifisert fire distinkte behov som må stilles til et godt syntetisert testmiljø.

                   1: Data for basis testing og ad-hoc exploratory testing

Så produksjonslike data som mulig for testformål

Dette betyr en statistisk representativ basisbefolkning som på alle måter speiler de signifikante aspektene av en reell befolkning. Siden de fleste av testene blir basert på behovene nedenfor, trenger denne befolkningen ikke å være i fullskala, noe som også reduserer ressursbehovet i form av CPU, stormaskintid, disk, minne etc. NAV baserer seg på en basisbefolkning på 100 000 som vil vokse i tilnærmelsesvis samme rate som den reelle befolkningen.

                   2: Grensetilfeller for spesifikk testing

Dette behovet dekker det meste av den spesifikke testingen av grensetilfeller og vanskelige saker. Eksempelvis en funksjonshemmet person som er adoptert av sin yngre søster og derfor har en mor som er yngre enn seg. Disse personene vil opprettes umiddelbart før testen og så saksbehandles gjennom systemene til en gitt endetilstand. Vi ønsker ikke å slette / resette personer til utgangstilstanden, så ved neste kjøring av testen vil man opprette en ny person med utgangstilstanden. Siden dette gjøres på den samme databasen som inneholder basisbefolkningen vil denne over tid langsomt endre seg fra den statistisk representative speilingen av virkeligheten som var utgangspunktet. Dette er akseptabelt fordi:

a)    Det er ønskelig at mest mulig av disse testene gjøres gjennom test-doubles av ytelse og reproduserbarhetshensyn slik at den statistiske effekten blir relativt liten.

b)    Basistesting vil i alle tilfelle gjøre endringer på testbefolkningen slik at vi uansett vil ha en glidning vekk fra realiteten. Dette må enten løses ved resetting av befolkningen til utgangspunktet eller ganske enkelt aksepteres. Kun utstrakt bruk av syntetdataene over tid vil vise hvilken løsning som er ønskelig.

                   3: Store datasett for ytelsestesting

Det vil fra tid til annen være behov for store datasett med et begrenset utvalg av signifikante variable for ytelsestesting. Eksempelvis en morgen med 15000 ferske mødre for test av automatisk saksbehandling av engangsstønad.

                   4: En levende testbefolkning

Det vil være et kontinuerlig behov for hendelser som skjer "av seg selv" for test av automatiske innslag i systemene ved passering av aldersgrenser, fødsler, dødsfall etc. Disse hendelsene må foregå kontinuerlig og i en frekvens som både gjenspeiler en statistisk virkelighet og er av tilstrekkelig omfang til å kunne forårsake nødvendig testing.

 

Hindringer

Enorm kompleksitet

Det største problemet med syntetisering av et helt land er den enorme kompleksiteten, både i virkeligheten og NAVs systempark. Siden den statistiske analysejobben vil vokse eksponensielt med antall analyserte variable er det ekstremt viktig å foreta et fornuftig utvalg av parametere som er relevante for syntetiseringen. Eksempelvis har vi ved generering av innvandringsmeldinger identifisert at både statsborgerskap og opprinnelsesland er relevante, men at kombinasjonen ikke er relevant. Det betyr at en svensk statsborger som er innvandret fra Azerbaijan er OK og analysen ser derfor på de to landene uavhengig slik at vi har et "riktig" antall svensker og et tilsvarende riktig antall innvandringer fra Azerbaijan, men kombinasjonen er ignorert.

Mange platformer og 6 tiår med løsninger

Det eldste systemet på NAV er skrevet i 1968 og er optimalisert for batch prosessering av hullkort. Det nyeste systemet er fra 2018 og bygget på Apache Kafka og json events. I mellom disse to ytterpunktene har vi alle tenkelige varianter av UNIX RPC kall, Java, Javascript, Visual Basic og Oracle Forms. Syntetisering av data for alle disse systemene er en utfordring

Avhengigheter til forretningslogikk som ligger i andre systemer

Problemet over blir forsterket av at systemene er avhengig av at dataene har blitt gjenstand for transformering gjennom eksisterende forretningslogikk gjennom andre systemer slik at en Oracle forms applikasjon forutsetter at en batchprosess har sendt data over UNIX RPC til et COBOL program før dataene kan benyttes til saksbehandling.

 

Løsning

1: Syntetisering av basispopulasjon

Syntetiseringsprosessen består av fire distinkte ledd; Ekstrahering av produksjonsdata, maskering, analyse og generering av syntetiske data på grunnlag av analysen. Nøkkelen til suksess er å ikke basere seg på innholdet i databasene, men fokusere analysen på flyten av data mellom systemer og dermed generere data gjennom eksisterende forretningslogikk.

Ekstrahere

I NAV er vi så heldige at vi har meldingshistorikk både på eksterne og interne data. Det er flere grunner til at vi har slik historikk, deriblant hensyn til sporing og validering av historiske hendelser som har dannet grunnlaget for saksbehandling og vedtak. Ekstraktet blir dermed bare en "dump" av meldingshistorikken for en gitt tidsperiode. Dette er fremdeles skarpe data og er således gjenstand for de samme sikkerhetsregler som online produksjonsdata.

Maskere

Neste skritt er en maskering og anonymisering av datagrunnlaget. Dette skrittet er overflødig dersom personellet som arbeider med syntetiseringen fra før har tilgang til produksjonsdata, men koster lite og har den fordelen at man kan redusere sikkerhetskravene til tilgangen til datagrunnlaget. Maskeringen i dette tilfellet fjerner også all informasjon som ikke er statistisk relevant, slik som navn og adresse, noe som gjør maskeringen sterkere enn en ukritisk maskering av hele produksjonsdatasettet hadde blitt.

Analysere

Deretter foretas en statistisk analyse av det maskerte datasettet. Denne analysen er skrevet i R og baserer seg på teknikker fra SDV - Synthetic Data Vault og Synthpop, begge utviklet for lignende formål ved MIT. Det er viktig å merke seg at det beregnes statistikk for sammensatte variable slik at man ikke bare får riktig antall 42-åringer, men også riktig antall skilte 42-åringer med 3 barn hvorav to er gutter, etc. Denne analysen er ressurskrevende og bør fortrinnsvis kjøres på dedikert hardware med tilstrekkelige ressurser. I forkant av den statistiske analysen har det blitt gjort en analyse av hvilke variable som er relevante å se i sammenheng. Eksempelvis er det relevant for systemene i NAV hvilket statsborgerskap en utlending har og også hvilket land han har innvandret fra. Imidlertid er kombinasjonen av opprinnelsesland og statsborgerskap ikke viktig, så systemet tar ikke hensyn til det, slik at vi har svenske statsborgere som innvandrer fra Azerbaijan. Siden tidsbruken for analysering stiger eksponensielt med antallet variable er en slik analyse viktig.

Generere

Det siste skrittet i prosessen er å generere "realistiske" hendelser og legge dem i et mellomlager. En systemprosess plukker så meldinger fra lageret og distribuerer til de forskjellige systemene. Vi genererer opp et langt større antall hendelser enn det vi initielt trenger, slik at systemet kan plukke meldinger over tid. Dette både av hensyn til belastning på systemer under genereringen og slik at vi kan simulere hendelser og endringer i befolkningen over tid. En interessant detalj er at vi har begynt med å simulere innvandringer siden systemet ikke har noen andre måter å skape personer ex nihilio; en fødsel forutsetter en mor etc. Dette er i praksis en simulering av folkevandringen etter istiden bare med andre datoer.

2: Randtilfeller og spesifikke testdata

Som testere har vi til stadighet behov for ekstreme, urealistiske eller på andre måter vanskelige data for testing av grensetilfeller og negativ testing. Eksempelvis barn som er eldre enn sine mødre. Genereringen av slike data vil ikke bli ivaretatt av basispopulasjonen. Både fordi vi har valgt å kjøre syntet-Norge med en lavere befolkning enn det virkelige og fordi sannsynligheten for slike tilfeller er statistisk lik null.

Selv om vi hadde generert nok personer til å få alle mulige slike varianter hadde vi allikevel endt opp med samme problemet vi tidligere hadde ved bruk av reelle data, nemlig problemet med å finne frem til slike personer. Det ville også være en mangel på umulige tilfeller.

Slike problemer løses best av et system der man kan spesifisere nøyaktig hva slags personer man ønsker testet og så genererer et lite antall slike spesifikt for sine tester. Ulempen med en slik løsning er at disse sære personene over tid vil forskyve den statistiske balansen i basispopulasjonen. Dette er delvis løst ved å legge mye randtilfeller i dedikerte testgrensesnitt som ikke er koblet mot de sentrale systemene, såkalte test-doubles. Dette er ikke en fullgod løsning og der det kreves en flyt gjennom mange systemer vil den statistiske representasjonen til basispopulasjonen endres vekk fra virkeligheten over tid. Dette problemet er ikke fullgodt løst ennå.

3:  Store antall "like" personer for ytelsestesting.

Systemene må fra tid til annen ytelsestestes. I slike tilfelle trenger vi mange personer som har et sett med parametre, men der øvrige egenskaper ikke er viktige for testen. Eksempelvis 15 000 nybakte mødre samme tirsdag for stresstesting av systemet for utbetaling av engangsstønad. Dette har vi løst ved at systemene i pkt. 2 også kan generere mange personer relativt enkelt. Løsningen er at man bare spesifiserer de relevante verdiene og så genererer systemet opp tilfeldige verdier for resten av de påkrevde parametrene. I eksempelet over spesifiserer man kvinne over 16 og under 50 og lar systemet håndtere resten. Vi har valgt å legge systemene opp slik at blanke felt gir en tilfeldig gyldig verdi, mens et spenn gir en tilfeldig verdi innenfor maks / min verdier.

Slike personer har en enda større innvirkning på basispopulasjonen enn randtilfellene og det er derfor ønskelig å ha mest mulig slik testing i test-doubles. Eventuelt drepe syntet-personene etter at man er ferdig med testen, noe som også gir en "gratis" ytelsestest av systemene for gravferdsstønad.

4:  En levende populasjon

I virkeligheten skjer det hendelser med befolkningen jevnlig. Folk blir født, dør, giftes og skilles. For at dette skal foregå også i syntet-Norge har vi laget en prosess som kontinuerlig plukker syntetiske hendelser fra lageret av genererte hendelser og propagerer dem ut i systemene gjennom eksisterende forretningslogikk. Teknisk er det ikke noen forskjell på denne og engangsgenereringen over.

App-releaser er ikke som andre releaser

Forfatter: Pål Berg, Promis Qualify

Apper er ikke bare apper.

Denne artikkelen tar kun for seg native apper. Release av web apper og hybrid apper behandles ikke her.

 

Det som er spesielt når man skal ha apper ut til folket, er at det ikke bare er ên release. 
Som oftest så er det flere, da de fleste apper har både iOS-versjoner (iPhone) og Android-versjoner (Samsung, LG, Sony og alle de andre). Noen har sågar også en WindowsPhone-versjon. Appene spiller sammen med baksystemene, altså de delene av funksjonaliteten som ligger på servere.

Man kan dermed få alle mulige kombinasjonene av koordinerte releaser av alt fra én til alle av disse:

Android iOS Baksystemer

 

Det varierer hvor tett baksystemutviklerne jobber med app-utviklerne. Og hvor tett app-utviklerne på ên plattform jobber med app-utviklerne på de andre app-plattformene. I noen tilfeller kan f.eks. Android-appen "stikke avgårde" og få inn ny funksjonalitet lenge før iPhone-appen. Eller omvendt.

Det betyr, at selv om avhengigheten mellom app-plattformene ikke er stor, så vil det som regel være avgjørende at release av apper og baksystemer koordineres.

Ved koordinerte releaser av både apper og baksystemer er det mest hensiktsmessig at baksystemene rulles ut før nyeste app-versjon fordi:

  • De nye appene kan ha avhengigheter til endringer eller ny funksjonalitet i baksystemene.
  • Det oppdaterte baksystemet skal fungere med de app-versjonene som allerede er i omløp. Skulle det dukke opp alvorlige problemer under eller rett etter prod-releasen av baksystemet, så kan man utsette app-releasene til baksystemene har nådd ønsket tilstand. Dette kan være problemer med baksystemet som sådan eller kompabilitetsproblemer mot en eller flere av de eldre versjonene av appene.
  • Appene testes mot den relevante versjonen av baksystemene. Det er avgjørende at den versjonen av baksystemet som appene er testet mot, ligger i prod når appene slippes. Man må derfor allerede når man planlegger testingen av appene, vite hvilke versjoner av baksystemene man skal forholde seg til.
  • Man får litt tid til å teste ut de nye versjonene av app'ene i prod mot det nyeste baksystemet før app'ene gjøres tilgjengelige i app-butikkene. Heri inkludert oppgraderingstester. Man kan bl.a. involvere betagrupper. Betagrupper er et antall frivillige brukere som får prodversjon av appene litt før planlagt release.

Native apper rulles ut gjennom Google Play Store og Apple's App Store. Dette kan gjøres gradvis:

  • For Android ved at man først f.eks. tilgjengeliggjør den nye appen for 10% av brukerne, deretter de neste 40% dagen etter osv. Man har dermed mulighet til å stoppe utrullingen før alle har tilgang, hvis det skulle vise seg å være nødvendig.
  • For iOS kan man ha gradvis utrulling i faser (phased release) til de som har på automatisk oppdatering. Det skjer etter et fast mønster, som starter på 1% første dag og via en tilnærmet dobling pr dag (1%-2%-5%-10%-20%-50%-100%) ender opp på 100% automatisk oppdatering i løpet av 7 dager. Den manuelle oppdateringen påvirkes ikke av dette, så alle vil kunne se den nye versjonen i App Store og kunne laste ned denne fra dag 1. Man kan sette den gradvise utrullingen på pause, men fortsatt vil manuell oppdatering være tilgjengelig.

For apper er det aldri snakk om tilbakerulling. Man kan i krisesituasjoner kun ta appen ut av app-butikken, og så fort som mulig komme med en ny og bedre versjon.

Når man planlegger releasedato så må man også ta høyde for at appen skal godkjennes av "butikksjefen" før den legges i Google Play Store og Apple's App Store. Apple er noe mer rigide og deres godkjenningsprosess tar lenger tid, i verste fall opp mot en uke. Mens det for Google vanligvis tar 2 minutter.

Flere artikler …