Szoftvertechnologia gyakorlat Dr. Johanyák Zsolt Csaba http://johanyak.hu
1. Dependency Injection (függőség befecskendezés) tervezési minta A tervezési minta alapgondolata az, hogy egy konkrét feladatot megoldó komponens/osztály (Szolgáltató) és az azt használó osztály (Ügyfél) között laza kapcsolatot valósítsunk meg annak érdekében, hogy megkönnyítsük a későbbi esetleges változtatásokat (pl. a feladatot megvalósító komponens/osztály lecserélése) és kódkarbantartást. Az Ügyfél csak a Szolgáltató által nyújtott (ISzolgáltató) interfészt ismeri, a Szolgáltató osztály neve nem szerepel az Ügyfél kódjában. Három lehetséges megoldással találkoztunk előadáson, ezek az alábbiak konstruktor befecskendezés, tulajdonság befecskendezés, metódus befecskendezés.
1.1. Konstruktor befecskendezés A konstruktor befecskendezés azt jelenti, hogy az Ügyfél objektum létrehozásakor, a konstruktornak bemenő paraméterként átadjuk a szolgáltatást ténylegesen megvalósító objektum referenciáját. Példaként készítsünk egy konzol alkalmazást, amiben valós számok listáját kell növekvő és csökkenő sorba rendezni Első lépésként hozzunk létre egy osztálykönyvtár projektet Rendezo néven, és a megoldás neve legyen DIPelda. A projektben az egyes rendezési módszereket külön-külön osztályként fogjuk implementálni. Elsőként definiáljuk az a szolgáltatás által nyújtott interfészt.
Az interfész egy metódust határoz meg, ami átvesz egy listára irányuló referenciát és egy logikai adatot. Ha ez utóbbinak értéke true, akkor növekvő, különben csökkenő sorba kell rendezni a számokat. A rendezés eredményeképpen egy új listát kell előállítani. Készítsük el a Buborék osztályt, ami megvalósítja az IRendez interfészt.
1
public class Buborék:IRendez { public List<double> Rendez(List<double> Eredeti, bool Növekvő) { var új = new List<double>(Eredeti); for (var i = 0; i < új.Count; i++) for (var j = 1; j < új.Count; j++) if ((Növekvő && (új[j - 1] > új[j])) || (!Növekvő && (új[j] > új[j 1]))) { var m = új[j - 1]; új[j - 1] = új[j]; új[j] = m; } return új; } }
Készítsünk egy konzolalkalmazás projektet a megoldáson belül Pelda néven. Jelöljük ki indító projektként. Helyezzünk el egy hivatkozást a References részben a Rendezo projektre. Hozzunk létre egy Ügyfél nevű osztályt.
Az osztály konstruktora átvesz egy referenciát egy IRendez intefészt megvalósító objektumra, és egy adattagban tárolja azt. Itt valósítjuk meg a függőség befecskendezést. A Feltölt metódus létrehoz egy lista objektumot, és véletlenszerűen előállított valós számokat helyez el benne. A számok darabszámát paraméterként kapja meg. A Kiír metódus egy lista elemeit jeleníti meg a konzolon. A Munka metódus gondoskodik egy 10 elemű lista előállításáról, növekvő és csökkenő sorrendű új listák előállításáról és ezek megjelenítéséről a konzolon. public class Ügyfél
2
{ IRendez Rendező; List<double> Adatok; public Ügyfél(IRendez R) { Rendező = R; } void Feltölt(int db) { Adatok=new List<double>(); var r = new Random(); for(var i=0;i
Számok ) { foreach (var sz in Számok) Console.Write("{0,5:F3}, ",sz); Console.WriteLine(); } public void Munka() { Feltölt(10); Console.WriteLine("Az eredeti számsor:"); Kiír(Adatok); var Növekvő = Rendező.Rendez(Adatok, true); Console.WriteLine("Növekvő sorba rendezve:"); Kiír(Növekvő); var Csökkenő = Rendező.Rendez(Adatok, false); Console.WriteLine("Csökkenő sorba rendezve:"); Kiír(Csökkenő); } }
Az alkalmazást indító Program osztály a következő. Létrehozunk egy Ügyfél objektumot és a konstruktornak átadjuk paraméterként a rendezési feladatot megvalósító Buborék típusú objektum referenciáját. class Program { static void Main(string[] args) { var u = new Ügyfél(new Buborék()); u.Munka(); Console.ReadLine(); } }
1.2. Önálló feladat Válasszon ki egy másik rendezési módszert, implementálja azt egy IRendez interfészt megvalósító osztály formájában, majd próbálja ki a használatát a Main metódus módosításával. A feladatot megvalósító teljes projektet töltse fel a CooSpace-re
3
2. Kód lefedettség vizsgálata dotCover segítségével A dotCover segítségével alapvetően két forgatókönyv szerint végezhetünk kód lefedettség vizsgálatot. Ezek a következők: Visual Studio-ba betöltött projektre/alkalmazásra megvizsgáljuk, hogy a használat során mely forráskód utasítások/metódusok hajtódnak végre. Visual Studio-ba betöltött tesztprojektre megvizsgáljuk, hogy a benne szereplő egységtesztek milyen mértékben fedik le a vizsgált projektet (mely forráskód utasítások/metódusok hajtódnak végre.
2.1. Betöltött (StartUp) projekt vizsgálata A módszer bemutatása során az előzőekben létrehozott Pelda projektet fogjuk használni. A Visual Studio DOTCOVER menüjében válasszuk ki a Cover Startup Project menüpontot. Ennek hatására a VS lefuttatja a programot. Lépjünk ki a programból (Enter). Megjelenik a Coverage Result Browser ablak.
Nyissuk ki a bal oldalon a két projekt elemeit, és láthatjuk, hogy 100%-os a lefedettség. Az Ügyfél osztály kódjában tegyük megjegyzésbe azokat a sorokat, amelyek meghívják a Kiír metódust. public void Munka() { Feltölt(10); Console.WriteLine("Az eredeti számsor:"); //Kiír(Adatok); var Növekvő = Rendező.Rendez(Adatok, true); Console.WriteLine("Növekvő sorba rendezve:"); //Kiír(Növekvő); var Csökkenő = Rendező.Rendez(Adatok, false); Console.WriteLine("Csökkenő sorba rendezve:"); //Kiír(Csökkenő); }
4
Próbáljuk ki újból a lefedettség vizsgálatot.
A lefedettség vizsgálat kimutatta, hogy a Kiír metódus nem lesz meghívva az alkalmazás végrehajtása során. Ha duplán kattintunk a Kiír metóduson, az meg fog jelenni a kódszerkesztőben. Láthatjuk, hogy míg pl. a Munka metódus minden utasítása zöld háttérrel jelenik meg, addig a Kiír metódus blokkja rózsaszín hátterű. A színes kiemelés utasításszinten jelzi a lefedett és nem lefedett kódrészleteket.
2.2. DotCover használata tesztprojektekben Töltsük be a 8. gyakorlaton létrehozott Egységteszt projektet a Visual Studioba. A projekt elérhető a t:\info\Johanyák Csaba\Szoftvertechnologia\EgysegTeszt\ útvonalon. Nyissuk meg a KomplexTeszt.cs állományt. Rendeljük a dotCover-hez a teljes KomplexTeszt osztályt
5
Elindul az egységtesztek végrehajtása. A végrehajtást követően a Unit Test Sessions ablak tartalma az alábbi lesz.
Ebből láthatjuk, hogy az op_Equality egységteszt csak 71%-os lefedettséget biztosít a vizsgált egyenlőség operátor esetén. Valamint a nem-egyenlőség operátor lefedettsége 0%. Nézzük meg az érintett forráskód részletet.
6
Rózsaszín háttérrel jelennek meg azok az utasítások, amelyeket nem fed(nek) le azt adott operátorhoz/metódushoz írt egységteszt(ek).
7