« AV #74 - Hardcore Vista | Main | Microsoft Project Server Connector lanserat »

2006-10-24

Comments

Jimmy

Hej

Finns det någon anledning att inte använda Transactionscoops istället?

Med Transacstionscoops så görs en rollback på de ändringar man har gjort i databasen under ett unit test dessutom så kan man nästla dessa transactionscoops vilket är en fördel om man vill ha någon form av mer avancerad felhantering nere i DAL samtidigt som man vill kunna köra unit tests.

Martin

Som jag ser det, ska man inte blanda in infrastrukturen (ex databas, webservice mfl) i testerna av din domänmodell. Man skapar istället mock-objekt för att simulera infrastrukturen.

Testerna mot din databas borde ligga i en helt seperat test som har syftet att testa databasaccess (CRUD). Samma borde gälla för övrig infrastruktur.

Dag

Jimmy
Jag har hört de som gjort sådana tester, men jag vet inte riktigt hur det håller i längden? Och jag håller med Martin att testerna skall vara ämnade emot en komponent (eller skall vi säga ett lager?). Om man testar flera komponenter i ett test gör man mer ett integrationstest, vilket också skall göras. Men det är en annan typ av test.

Men man skulle då kunna anvämnda Transactionscoops för att testa databasaccessen (CRUD).

Det kan vara bra att ha det alternativet om man finner att det löser sina testproblem.

Men det kanske ändå inte är helt rätt. För det är skillnad på den komponenten som använder databasen och själva databasen. Så skall man hårddra det så skall även den komponenten (Data Access Layer) inte testa direkt emot databasen. Man kanske skall ha helt separate databastester. (Vilket förresten finns i ny Visual Studiorollen för Database Professional. Ja, ja, jag jobbar för Microsoft.)

Det var lite kanske flummiga tankar, skrivna i all hast.

Har jag rätt eller har jag hamnat bakom flötet. Eller som min måg säger: "Ekorhjulet snurrar men hamstern är död".

Jimmy

Hej!

Jag förstår vad ni menar och det låter så klart väldigt bra, frågan är hur det påverkar utvecklings tiden för ett projekt.

Säg att man ska utveckla en större flerskiktad lösning med Presentation Layer, Service Layer, Business Logic layer och Data Access Layer.

Vi skapar nu ett unit test project för varje skikt(4 st). I unite test projekten skapar vi vidare minst en unit test klass för varje klass som återfinns i skiktet(ifråga). Efter som det är sagt att man endast ska ha en Asset i en unit test funktion så kommer det bli en del test funktioner.

Jag kan tänka mig att detta resulterar i enorma mängder test kod vilket betyder en hel del utvecklings tid. Nu vet jag inte om det finns någon autogerering av mock klasser men om detta inte finns så kommer ytterligen en hel del utveckling tid försvinna här(vilket man slipper med transactions).

Jag är medveten om att unit test ska kunna köras i vilken ordning som hälst inne i ett test projekt men det borde vara helt okay att köra olika Test project i en viss ordning.

Säg att vi börjar med att köra Data Access Layer unit test projektet. Efter som vi använder transaction så modifieras inte databasen på något vis och samtidigt testas den kod som finns i databasen(ex storedpreccedures). Säg att unit testet för Data Access Layer går igenom utan problem vilket då säger oss att Data Access Layer och koden i SQL databasen är korrekt(om det uppstår fel så borde det inte vara så svårt att hitta). Nu går vi vidare med att testa Business Logic layer, säg att här uppstår ett fel, då vet vi med säkerhet(om unit testen är korrekta) att felet ligger i Business layer.

Självklart ställer detta höga krav på unit testen efter som översta lagret Presentation Layer antar att resterande lager under är korrekta.

Jag förstår mock objekts roll och kan förstå att man implementerar detta om man har oändligt med resurser/tid, men frågan är hur relevant det är att använda om man har begränsad resurs/tid? Man kanske uppnår väldigt säkra test trotts att man endast använder transacions på ovan nämnda vis?

Martin

Dag,
Jag förstår inte riktigt hur du menar. Hur testar man DAL utan databas?

När jag skriver mina databastester gör jag som Jimmy Nilssons föreslår i sin bok Applying Domain-Driven design and Patterns. Dvs, inför varje test genererar jag upp databasen (en separat databas som bara används för testerna) med NHibernate och får då samma utgångsläge inför varje test. Baksidan med detta är att det tar lång tid att köra testerna och då drar jag mig för att köra dem. Och det är ju inte bra.

Är väldigt intresserad att höra hur andra gör. Ska kolla på Transactionscoops.

Jimmy,
Jag tror att många som använder TDD inte kommer att hålla med dig i ditt resonemang. Test-driven utveckling är mer om design än om själva testerna, testerna får man på köpet. Tiden som det tar att skriva testerna tjänar man in varje gång man hittar en bugg med hjälp av testerna. Om du också behöver ändra något i framtiden, vilket är fallet i nästan alla utvecklingsprojekt, kan detta göras säkrare och snabbare med dina tester i ryggen. Men visst finns det både fördelar och nackdelar med testdriven utveckling.

Jag har inte hållit på med TDD tillräckligt för att verkligen kunna argumentera, men jag känner att jag skriver bättre kod när jag använder TDD. Jag känner dessutom att min kod är stabilare pga att allt är testat. Avvek kanske lite från ämnet där ville bara dela med mig lite...

Tack för en riktigt skön pod(d)cast Dag!

Dag

Martin: Du kan ha rätt. Jag försökte bara sätta på mig den "extrema TDD-hatten" och då ser jag att det ändå är en skillnad mellan DAL-komponenten och själva databasen. Men detta kan naturligtvis också bero på vilken typ av arkitektur som man använder sig av. Inom O/R så finns inte ens DAL med, men om man tar andra arkitekturer så är det en viktigt del. Sedan är det vissa som gör DAL väldigt tunt, medan andra lägger in fler funktioner i den, typ transformationer och dylikt.
Det var så jag tänkte när jag skrev mitt föregående inlägg.
Vad Jimmy Nilsson skriver i sin bok, tyvärr har jag inte hunnit till det kapitlet än, har jag stor respekt för. Det är säkert något som funkar och som han själv har erfarenhet av. Det är säkert ett bra sätt, men precis som du säger så tar det lång tid att köra testerna och detta motsäger en av de grundläggande principerna i TDD. (Tycker i alla fall jag.)

The comments to this entry are closed.

Become a Fan