A következő címkéjű bejegyzések mutatása: egységtesztelés. Összes bejegyzés megjelenítése
A következő címkéjű bejegyzések mutatása: egységtesztelés. Összes bejegyzés megjelenítése

2009. május 27., szerda

Unit test módszer az adatmanipulációhoz

Egy régebbi MSDN cikkben akadtam rá erre a nagyszerű módszerre, amivel a System.EnterpriseServices névtérben fellelhető tranzakciós eszközökkel szépen egységtesztelhetjük az adatbázisműveleteket, anélkül, hogy a tesztadatok elborítanának bennünket vagy mindenféle trükkös mocking és egyéb mókázásokra lenne szükség.
Persze néha az is hasznos lehet, arra is találtam egy jó módszert. Legközelebb majd leírom azt is :)

Vártam, hogy többen belém kötnek, miszerint ez integrációs teszt. Ha senki nem tette meg, akkor én kötök bele magamba. Persze a lényegen nem változtat, hogy minek nevezzük.

[TestFixture]

public class DBTest

{

    [SetUp]

    public void Setup()

    {

        // Enter a new transaction without inheriting from ServicedComponent

        Console.WriteLine("Attempting to enter a transactional context...");

        ServiceConfig config = new ServiceConfig();

        config.Transaction = TransactionOption.RequiresNew;

        ServiceDomain.Enter(config);

        Console.WriteLine("Attempt suceeded!");

    }

 

    [Test]

    public void Insert()

    {

        // Perform your magic against the database

        CategoriesManager mgr = new CategoriesManager();

        int newID = mgr.InsertCategory("MyCategory");

        Assert.IsTrue(newID != 0, "returned ID should be more than zero");

    }

 

    [TearDown]

    public void Teardown()

    {

        Console.WriteLine("Attempting to Leave transactional context...");

        if (ContextUtil.IsInTransaction)

        {

            // Abort the running transaction

            ContextUtil.SetAbort();

        }

        ServiceDomain.Leave();

        Console.WriteLine("Left context!");

        // Trying to access ContextUtil now will yield an exception

 

    }

 

}

2008. november 23., vasárnap

Levélküldés tesztelése SMTP nélkül

A legtöbb webes alkalmazásban van egy-két olyan sztori, amikor levelet szándékozunk kiküldeni a rendszerből. A végleges változatban általában SMTP szerver felhasználásával tesszük ezt, de fejlesztés közben meglehetősen kényelmetlen minden tesztfuttatás alkalmával ellenőrizni egy postaládát. Ráadásul korántsem biztos, hogy rendelkezésre áll a megfelelő szerver, a fejlesztői gépre sem feltétlenül tudunk vagy akarunk telepíteni.
Ilyenkor az SmtpClient osztály beállításával megtehetjük, hogy a saját fájlrendszerünkkel "levelezünk".
Fentiekhez a web.config állományban a következő beállítások szükségesek:

<system.net>

<mailSettings>

<smtp deliveryMethod="SpecifiedPickupDirectory">

<specifiedPickupDirectory pickupDirectoryLocation="c:\temp\mailpickup"/>

</smtp>

</mailSettings>

</system.net>


Így azonnal ellenőrizhetjük, hogy az üzenet a megfelelő tartalommal előállt-e.

[Test]

public void SendMailTest()

{

SmtpClient smtpclt = new SmtpClient();

MailMessage message = new MailMessage("from@server.com", "to@server.com");

message.Body = "Body";

message.Subject = "subject";

smtpclt.Send(message);

}


A kliensnek egyébként futás közben is megmondhatjuk, hogy a levelet ebbe a könyvtárba küldje:

smtpclt.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;

smtpclt.PickupDirectoryLocation = "c:\\temp\\mailpickup";

2008. május 21., szerda

Adatbázis tesztelése tranzakciók használatával

Ez az iromány valahogy piszkozatban ragadt úgy egy hónapja és csak most vettem észre. Sebaj, jobb későn mint soha.

Az adatbázis kommunikációval is foglalkozó alkalmazások esetében örök probléma, hogy mit is tegyünk, hogy ki is legyen tesztelve a megfelelő osztály, de lehetőleg azonosak legyenek a feltételek, ne is szemeteljük tele az adatbázist, pláne ne kelljen "kézimunkázni".
Szégyen ide, szégyen oda, de csak nemrégiben, egy neten talált példa alapján esett le a tantusz, hogy a legkézenfekvőbb megoldás, ha tranzakciót használunk, így a tesztadatok nem zavarják köreinket amikor nem kell. Hiába, az újszülöttnek minden vicc új.

A megoldás lényege röviden leírható:

Vagyis a setupban elindítjuk a tranzakciót, a teardown-ban pedig szépen eltüntetjük, a tesztadatokkal együtt, mintha ott se lettek volna.

Ne feledkezz meg a a System.Transactions.dll referenciába tételéről és persze a System.Transactions névtér usingolásáról!

(Egyben be szeretném mutatni a csodálatos új dark színösszeállításomat, amire itt tettem szert :))

2008. május 15., csütörtök

Fájlműveletek tesztelése

A piszkozatok között kallódott egy marék forráskód, megnézegettem mi lehetett ez.
Nos hát...
Egy időben problémám volt az egységteszteléssel fájlokat használó metódusok esetén, erre találtam egy megoldást. Lehet, hogy van ennél jobb is, de a célnak megfelelt.
Bár ha jobban belegondolunk lehet róla vitatkozni, hogy egységtesztelésről vagy inkább integrációs tesztről van-e szó, hiszen a programunknak a fájlrendszerrel való együttműködését teszteljük. De a talált maréknyi kód szempontjából ez nem is érdekes :)

Az alkalmazás valami képeket méretezett és nevezett át, aztán lementette az átméretezett képeket.

A probléma ott volt, hogy úgy lehessen tesztelni, hogy lehetőleg ne kelljen semmi spéci beállításokat csinálni, ne kelljen rendszergazdai jog stb., de a tesztállományokat kiírni, majd a futás végén letörölni gond nélkül tudjam bármelyik gépen. A program a DirectoryInfo osztályt használta, amit az én szintemen lehetetlennek tűnt mockkal vagy bármi más módon kiváltani. Így jött az ötlet, hogy az aktuális felhasználó profilja alatti temp könyvtárba fogom pakolni az tesztállományaimat. A temp könyvtár elérését a  .NET prímán támogatja, a Path osztályon keresztül.

DirectoryInfo d = new DirectoryInfo(Path.GetTempPath());

A Path osztály további finomságokkal is szolgál, például elegánsan fűzhetünk össze vele útvonalakat. Ráadáasul ha ezt a módszert szokja meg az ember, akkor elvileg MONO alatt azonnal fordíthatja a kódját, nem lesz probléma az oprendszerek különböző szeparátoraival. (Azért mondom, hogy elméletben, mert ezt én még sosem próbáltam, de működnie kellene.)

DirectoryInfo d2 = new DirectoryInfo(Path.Combine(d.FullName, "backup"));

A teszteléshez használt fájlokat egyszerűen resource-ként belefordítottam a tesztprogramba, így már szépen létrehozhatom a tesztállományaimat a teszt indításakor:


        [TestFixtureSetUp]

        public void SetUpDir()

       {

            ...

            ...

            ...

            TestResource.Image1.Save(Path.Combine(d2.FullName "23817_2_01.jpg"));

            TestResource.Image1.Save(Path.Combine(d2.FullName, "23817_2_02.jpg"));

            ...

            ...

            ...

        }

A teszt után pedig, visszaállítandó az eredeti állapotot törölhetem a tesztállományokat. A megoldás nem túl szofisztikált, de a célnak megfelel, tesztelni lehet a programot. Ha valaki tud erre jobb megoldást írja meg ;)

2008. április 9., szerda

Hatékonyságnövelő tippek a Visual Studio 2008-hoz

Az egyik MSDN blogban megjelent egy bejegyzés, 10 tippel, ami a kódolás hatékonyságát növelheti Visual Studioban.
Ki ne szeretne hatékonyabb lenni, hát átolvastam, itt most továbbadom, a saját véleményemmel kiegészítve. Amit jónak tartok így jelölöm: (!), amit nem azt így (?), ahol ezek a jelek nem szerepelnek azt döntsd el magad :)

1. tipp: Tanuld meg a gyorsbillentyűket.

Ez nem túl fantáziadús javaslat, mondhatnám, hogy triviális, de tény ami tény, valóban hatékonyságnövelő tényező, ezért is hívják úgy, hogy GYORSbillentyű.
A legfontosabbakat felsorolja a cikk, bár SZVSZ ezeket mindenki ismeri, hacsak nem ma látott először Studiot.
  • Build: CTRL + SHIFT + B
  • Word completion: CTRL + SPACE
  • Start with debugging: F5
  • Start without debugging: CTRL + F5
2. tipp: Automatikus dokumentációgenerálás GhostDoc segítségével (?)
Ez a tipp erősen vitatható. Egyetlen esetben van értelme használni, ha valaki olyan cégnél dolgozik, ahol a dokumentációt "kilóra" mérik. Ugyanis egyedül ilyen esetben csinál épeszű ember ilyen "dokumentációt":

Vagy ilyet:
A magam részéről úgy gondolom, hogy ennek semmi értelme. Ugyanis a függvény, property, osztály neve ha "önleíró", mint fent, akkor gyakorlatilag csak szószaporítás az ilyen típusú dokumentáció, ha azonban nem az, akkor semmilyen automatikus eszköz nem tudja értelmesen dokumentálni, csak a programozó.

3. tipp: Használd az automatikus tulajdonságokat
Ezt én inkább így írnám:
Használd ki a nyelvi újdonságokat (!)

Az automatikus tulajdonságok egy hasznos újítás a C# 3.0-ban. Mindenkit bátorítanék ennek az anyagnak az átolvasására, aki még nem tette, itt minden újdonság, szépen jól magyarul olvasható el.
A hatékonyságnövelő újdonságok bajuszokban, rövid példával:

Automatikus tulajdonságok


Új lehetőség az objektumok inicializálására



Lokális típusfeloldás


Lambda kifejezések


Erről itt írtam egy szemléletes példát.

4. Tipp: Használd a Refactort

Ha nem tudsz vagy nem akarsz automatikus tulajdonságot alkalmazni, hasznos lehet a Refactor menü Encapsulate field... menüpontja.
Így kezded:


..és ez lesz belőle:

A Rename is igen hasznos lehet, bár néha igen lassúcska, illetve kétségtelenül hasznos és (általam) gyakran használt tool az Extract interface..., ami nem meglepő módon interfészt állít elő az osztályunk alapján pikk-pakk módon.

Az 5. tipp (egyéni parancsok) részben emlegetett PowerCommands toolt ki fogom próbálni, mert a projekt oldalán látok néhány ígéretes dolgot (Copy/Paste Class, Copy/Paste References).

6. tipp: a build testreszabása

Egy nagyobb projekt esetében perceket vehet el az életünkből fölöslegesen, ha olyan dolgok is be vannak kapcsolva a projekt fordítása során, amelyekre például csak a végső változatban lesz szükség. Példaként a post az XML dokumentáció generálását hozza. Érdemes ezekre odafigyelni.



7. tipp: használd a VS unit test generáló funkcióját (??)

Hát ez nálam erősen kérdőjeles. Nem tudom mennyit ér egy ilyen automatikusan generált teszt. Érzésem szerint ez ugyanaz a kategória, mint a fentebb tárgyalt automatikus dokumentálás, vagyis csak kilóra van haszna, érdemben nem nagyon. Emgem ez azért sem érint különösebben, mert az NUnit és a Testdriven.NET használata mellett köteleztem el magam egyelőre, így a VS saját teszteszközeit nemigen használom.

A következő két tipp valóban hasznos, azonban a C#-hoz, de főleg a Studiohoz társítani némileg erős, hiszen mindkettő iknább módszertani kérdés, bár a szükséges eszközök valóban rendelkezésre állnak VS2008-hoz, ha másképp nem, hát külső fejlesztésként.

8. tipp: Interfész-központú tervezés

Az interfész alapú tervezés az én olvasatomban az agilis módszertanok fegyvertárába tartozik. A cikk arra mutat rá, hogy ennek a módszernek jelentős hatékonyságnövelő hatása lehet, főleg teamek esetében. A lényeg röviden annyi, hogy a többrétegű alkalmazások fejlesztésekor legelőször a kommunikációs felületek kialakítása a célszerű, mert így a csapat tagjainak nem kell egymásra várniuk, hiszen például az üzleti logika készítői elkészíthetik a saját - nyilván egyszerűsített - adathozzáférési objektumaikat vagy a következőben emlegetett mocking technikát alkalmazhatják, így párhuzamosan tud zajlani a fejlesztés szorosan kapcsolt rendszer esetében is. Jah igen, ami a Visual Studiot illeti, az objektumtervező lehetőséget ad minimális erőfeszítéssel az interfészek előállítására



9. tipp: A függőségek kiiktatása mock objektumok segítségével

A tipp kétségtelenül hasznos, bár ez nem a Studio vagy a C# fejlesztőinek érdeme :)
Mivel jómagam is newbie vagyok a tesztvezérelt fejlesztésnek nevezett metodológiában, ezért nem szeretnék itt mélyen belemenni a dolog taglalásába. A lényeget már majdnem le is írtam az előző pontban. Gyakorlatilag arról van itt szó, hogy az álobjektumokat egy eszköz segítségével úgy állítjuk elő, hogy azok megvalósítsák azokat a függvényeket, tulajdonságokat, amelyeket a tesztek során használni szeretnénk (lehetőség szerint CSAK azokat). Így egyrészt valóban függetlenítjük a programrészünket a többitől, másrészt a tesztjeink jelentősen gyorsulhatnak is, ha ezzel a módszerrel kiiktatunk például adatbázisműveleteket vagy más idő és erőforrásigényes eljárásokat. A cikk írója által ajánlott rendszer a RhinoMocks névre hallgat, jómagam is ennek használatába kezdtem bele a közelmúltban, az elterjedtsége és nem utolsó sorban az ingyenes volta miatt.
A cikk szerzője hoz egy rövid példát is, amit idelinkelek:



10. tipp: Adatvezérelt egységtesztek

Ismét röviden arról van itt szó, hogy X darab teszt írása helyett egyetlen tesztet írunk, amelyet a VS segítségével egy adatbázis X sorára lefuttathatunk. Ez a tesztek írását valóban gyorsítja, ellenben a futtatáskor - az előző pontban írottal szemben - éppen, hogy megterhetljük a tesztet egy kvázi fölösleges adatbázis és/vagy fájlolvasással. Én kis adatmennyiség esetében (és hogy ne kelljen megválnom a jó öreg NUnittól ;)) inkább az NUnit egyik kiegészítőjét használom (RowTest Extension for NUnit). Ki-ki döntse el, hogy melyiket akarja szeretni.

2008. április 8., kedd

VS2008 probléma: Cannot copy file because it is being used by another process

Unit tesztek esetében nálam is rendszeresen előfordul VS2008 alatt az a probléma, aminek a megoldását most olvastam. Még nem próbáltam ki, remélem használ...

2008. március 5., szerda

Unit testing loaded...

Eljött a nagy nap. A gyakorlatban is elkezdem elsajátítani a tesztvezérelt fejlesztés fortélyait. Amennyire időm engedi itt is fogok erről írni időről időre.
Előzményként annyit tettem, hogy végigolvastam egy kitűnő könyvet a témában, hogy kellőképpen átlássam a dolog mikéntjét valamint néhány móricka példán végigküzdöttem magam. Mindenki tudja viszont, hogy a puding próbája az evés, így hát ma letöltöttem az NUnit és a RhinoMocks legújabb verzióit és nekiálltam élesben. Most már semmi sem állhat az utamba. :)

2008. február 22., péntek

Egységtesztelés SQL -ben

Mostanában munkából és hobbiból kifolyólag is foglalkozom az egységtesztelés finomságaival. Mivel a három- és többrétegű alkalmazások esetében én a tárolt eljárások híve vagyok így ezen a területen is kutakodtam egy kicsit. A gugli ezeket dobta ki:

http://spunit.sourceforge.net/
http://tsqlunit.sourceforge.net/tsqlunit_documentation.htm
http://sqlunit.sourceforge.net/
http://www.tsqltest.org/

Amint lesz érkezésem megnézem őket közelebbről, egyelőre eltettem őket a fincsibe. Addig is kommentben szívesen látnék esetleges tapasztalatokat.