Klassificering av testdata

Testdata är ett kärt ämne så jag tänkte vi kunde prata lite om olika typer av testdata och hur man kan klassificera och hantera dessa. Jag tänkte begränsa mig till persistent data.

Ett grundkriterie för robusta tester är att man har kontroll över systemets tillstånd. Ett och samma test kan ge olika resultat om systemets tillstånd skiljer sig åt mellan testkörningar. Än värre är om testerna har ett inbördes beroende. T.ex. om man byter exekveringsordning på två tester så får man ett annat resultat. Det kan t.ex. bero på att testerna delar data och det ena testet förändrar datan. Det är dock inte praktiskt möjligt att helt kontrollera systemets tillstånd – iallafall inte för systemtester – men man bör eftersträva att ha så stor kontroll som möjligt.

Vad är det som påverkar systemets tillstånd? All data som inte återställs eller rensas förändrar tillståndet hos systemet. Denna data kan komma i en uppsjö av olika varianter, ex ; cache, fil, kö, databas, klassvariabler etc. För att vara helt säker på att systemet är återställt måste man starta om det, samt rensa alla persistenta källor mellan varje test. Det kan man sällan göra av praktiska skäl – då skulle testerna ta för lång tid att exekvera. Dock brukar det finnas möjlighet att kontrollera den persistenta datan (icke-dynamiska data) – som jag här tänkte representera med en databas.

Den persistena datan kan klassificeras i tre huvudkategorier; ”färsk”, ”oföränderlig” och ”delad”.

”Färsk”, är data som endast existerar under livstiden av ett oberoende test. Det kan vara en förutsättning för testet eller data som skapas av testet. Efter testet så återställs systemet genom att rensa bort den nya datan. Ex:

Tänk er ett system med möjlighet att registrera unika kunder – inte helt ovanligt. Vi testar att registrera ”Nils” vilket genererar nya rader i diverse tabeller i databasen. För att kunna köra exakt samma test igen måste datan knuten till kunden ”Nils” tas bort – då systemet endast tillåter unika kunder. Det gör man förslagsvis i någon post-metod (tearDown) med hjälp av lämplig systemmetod (deleteCustomer). Om dylik systemmetod saknas (låg testabilitet) blir det knepigare. Ska man skriva specifik testkod för att ta bort denna data? Inte helt självklart. Då kan det vara bättre att undersöka möjligheterna till att göra en ”transaction rollback”.

”Oföränderlig”, är data som inte förändras under sin existens. Existensen definieras som livstiden av alla tester. Det kanske vanligaste exemplet på denna typ av data är konfigurering Då denna data inte förändras för någon av testerna blir den lätthanterlig. Förslagsvis laddar man denna data innan första testet körs. Det finns ingen anledning att rensa eller återställa denna data mellan testerna.

Slutligen kommer vi till den mest komplexa datatypen – ”delad”. Precis som ovan typ existerar denna data under livstiden av alla tester. Skillnaden ligger i att datan kan förändras. Ex:

Tänk er att vi förladdar databasen med ett förutbestämt set av kunder. Vi hämtar sedan en kund från detta set inför varje specifikt test och använder som testdata. Problem uppstår när ett test modifierar någon egenskap hos en specifik kund och ett annat test återanvänder just den kunden. Säg att vi har ett test som markerar en kund som obsolet. Om ett annat test återanvänder den kunden kommer det testet att fallera då kunden inte är brukbar.

Man bör eftersträva att endast använda ”färsk” och ”oföränderlig” data. I praktiken kan det dock vara svårt pga låg testabilitet etc. Då kan man försöka att bryta upp sin ”delade” data i ovan två typer. Det ger mer kontroll och bättre robusthet. Om vi använder ovan exempel så skulle vi åstadkomma detta genom att göra kundens egenskaper till ”färska”. Huruvida det är praktiskt lämpligt beror på hur systemet är implementerat.