Web programozás és haladó fejlesztési technikák

Slides:



Advertisements
Hasonló előadás
C# nyelvi áttekintő A „Programozás C# nyelven (Illés Zoltán)”
Advertisements

Osztály leszármaztatás
Felhasználói felületek és üzleti logika Bollobás Dávid ASP.NET
Rendszerfejlesztés gyakorlat - © Fülöp Lajos
Programozás III KOLLEKCIÓK 2..
A webes tesztelés jövője
2 Forrás: The Standish Group International, Extreme Chaos, The Standish Group International, Inc., 2000.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Adatbányászati technikák (VISZM185)
Hibakezelés és Tesztelés a Visual Studio.NET-ben
Junit testing.
© Kozsik Tamás Beágyazott osztályok A blokkstrukturáltság támogatása –Eddig: egymásba ágyazható blokk utasítások Osztálydefiníciók is egymásba.
Szabó Tamás Károly G6HT12 A Ruby programozási nyelv.
Bevezetés a Java programozásba
Osztályok Garbage collection.  általában minden osztálynak vannak adattagjai és/vagy metódusai ◦ adattagok megadása:  [láthatóság] [static] [final]
Programozás II. 3. Gyakorlat C++ alapok.
UNIVERSITY OF SZEGED D epartment of Software Engineering UNIVERSITAS SCIENTIARUM SZEGEDIENSIS Programozás II. 6. Gyakorlat const, static, dinamikus 2D.
Tömbök ismétlés Osztályok Java-ban Garbage collection
A CLIPS keretrendszer CLIPS "C" Language Integration Production System.
Mutatók, tömbök, függvények
Az objektum-orientált tervezési alapelvek kritikai vizsgálata
Ellenőrző kérdések a)Auto-indexing enabled b)Auto-indexing disabled c)Nem eldönthető 1.
Java programozási nyelv 3. rész – Osztályok I.
C# tagfüggvények.
C# tagfüggvények.
SPRING FRAMEWORK bemutatása
OE-NIK HP Haladó Programozás WCF kivételkezelés. OE-NIK HP Haladó Programozás Windows Communication Foundation A szolgáltatás, a hoszt és az ügyfél elkészítése.
C++ Alapok, első óra Elemi típusok Vezérlési szerkezetek
Delphi programozás 8. ELŐADÁS ADO ActiveX Data Objects.
A JAVA TECHNOLÓGIA LÉNYEGE Többlépcsős fordítás A JAVA TECHNOLÓGIA LÉNYEGE Platformfüggetlenség.
PHP I. Alapok. Mi a PHP? PHP Hypertext Preprocessor Szkriptnyelv –Egyszerű, gyors fejlesztés –Nincs fordítás (csak értelmező) Alkalmazási lehetőségek:
Rendelkezésre álló erőforrások pontos ismerete Kiosztott feladatok közel „valósidejű” követése Átláthatóság Tervezési folyamatok támogatása.
Szoftvertechnológia alapjai Java előadások Förhécz András, doktorandusz tárgy honlap:
1 Add az APK-t! Add az APK-t! Automatizált apptesztelés 2013/10/13.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
Hernyák Zoltán Programozási Nyelvek II.
1 Hernyák Zoltán Web: Magasszintű Programozási Nyelvek I. Eszterházy.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
A D programozási nyelv Angeli Dávid. Nagy vonalakban  C++  
Javascript Microsoft által készített kiegészítése Statikus típusosság Nagy projektek Windows 8 fejlesztésénél WinRT egy részét ebben írták Nyílt forráskódú,
Android alkalmazások tesztelése
Java programozási nyelv Metódusok
Generics Krizsán Zoltán. Bemutató A.NET 2.0 verziótól. A.NET 2.0 verziótól. Típusparaméter Típusparaméter Más nyelvben ez a template (sablon). Más nyelvben.
A Visual Basic nyelvi elemei
Power Lutár Patrícia Pellek Krisztián.  -ltLess than  -leLess than or equal to  -gtGreater than  -geGreater than or equal to  -eqEqual to  -neNot.
Programozás III KIVÉTEL.
Haladó Programozás Reflexió OE-NIK HP.
DLL használata és készítése Feladat
Excel programozás (makró)
TÁMOP /1-2F JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam Osztályok, objektumok definiálása és alkalmazása. Saját.
Krizsán Zoltán, iit C# osztályok 2 Adattagok  Osztály hatáskörben definiált változó.  Formája: [attribútum] [módosító] típus azonosító [=kezdő érték][,
Maven és Ant Build eszközök bemutatása
Farkas Bálint | Technical Evangelist | Microsoft
Gépészeti informatika (BMEGEMIBXGI)
Excel programozás (makró)
Dependency Injection Moq Feladat
Java Code Coverage Library
A CLIPS keretrendszer
Hernyák Zoltán Magasszintű Programozási Nyelvek I.
Web programozás és haladó fejlesztési technikák
Web programozás és haladó fejlesztési technikák – C#
Dependency Injection Tesztduplikátumok, Mock-ok, Fake-ek Feladat
B M Java Programozás 1. Gy: Java alapok IT A N Ismétlés ++
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Dependency Injection Tesztduplikátumok, Mock-ok, Fake-ek Feladat
Informatikai gyakorlatok 11. évfolyam
Függvénysablonok használata
Unit tesztelés Swift-ben
Előadás másolata:

Web programozás és haladó fejlesztési technikák Tesztelés a fejlesztői munkában NUnit Unit teszt Dependency Injection Tesztduplikátumok, Mock-ok, Fake-ek 1

„Tesztelés = kipróbálom kézzel”

Tesztelés szükségessége Tesztesetek száma? > 2^n if (condition1) { // something happens if (condition2) if (condition3) } …? Random exception befolyásolja condition3-at fájlhoz nyúl user inputot használ adatbáziselérés Órai munka (150-300); féléves beadandó (CarShop 4841); 1 fős kisprojekt (n*10e); avg projekt (n*100e); nagy projekt Mekkora egy projekt?

Tesztelés szükségessége „B” Team „A” Team Forrás: https://www.ndepend.com/docs/visual-studio-dependency-graph

„Majd a tesztelő leteszteli”

Tesztelés a fejlesztői munkában A tesztelés közelebb került az implementációhoz, mert: Korai feedbacket ad Védi a lefedett kódot a későbbi véletlen hibák ellen Követelmények tisztázását segíti Tiszta, jól strukturált kód írását kényszeríti ki (Bizonyos módszertanokban a tesztelés az implementáció elé került) „Agilis csapat” A termék/funkció fejlesztésének összes aspektusáért – tervezésért, implementációjáért, minőségellenőrzéséért, teszteléséért felel Egyre inkább a fenntartásért / supportért is A régi szerepek elmosódnak vagy szándékosan hiányoznak – „crossfunctional team”

Tesztelés szükségessége static void Main(string[] args) { Logger l = new Logger(); l.AddLogMethod(Console.WriteLine); l.AddLogMethod( m => using (StreamWriter writer = new StreamWriter("log.txt", true)) writer.WriteLine(m); } }); // ... l.Log("Program elindult"); l.Log("Adatbáziskapcsolat felépült"); Console.ReadLine();

Tesztelés szintjei DoSomething() DoSomething() DoSomething() UI teszt Integrációs teszt Komponensteszt Unit teszt (Az elnevezések fejlesztői közösségenként változhatnak) DoSomething() DoSomething() DoSomething() Forrás: https://www.ndepend.com/docs/visual-studio-dependency-graph

NUnit Teszt keretrendszer .NET nyelvekhez (Java: jUnit) Nagyobb programcsalád része Unitteszt: NUnit (vs. Visual Studio Unit Testing Framework) Mocking: NSubstitute (vs. Moq, Rhino Mocks) IoC container: NInject (vs. Spring.Net, Castle Windsor, Unity) Tesztlefedettség: NCover (vs. dotCover) Unit teszttől integrációs tesztig minden tesztszinthez jó Saját GUI, command line, vagy Studióban Test Explorer (NUnit3TestAdapter kell hozzá) Félkövér, amit megnézünk. Moq a következő órán. Általában a fejlesztői közösség összeválogatja a toolkészletet, nem feltétlenül együtt használják az N... családot NUnit nemigen különbözik az összes hasonló célú keretrendszertől, igazából tökmindegy, melyiket választják.

Egyszerű tesztelt projekt Éles projekt(ek) + tesztprojekt(ek) (Class Library) Tesztprojekt referenciái: Tesztelt projekt Tesztkeretrendszer A tesztprojektben a tesztelt projekt publikus részei tesztelhetők Internal részek: [InternalsVisibleTo(„ConsoleApplication1Tests”)] Class Library

Egyszerű tesztelt projekt Test / Windows / Test Explorer NUnit3TestAdapter kell hozzá! (Nuget) Fejlesztői közösség szokásától és tesztektől függően folyamatosan, vagy lényeges kódváltoztatás után, merge előtt, merge után, push előtt mindenképpen futtatják. Piros teszttel nem pusholnak kódot „ConsoleApplication1Tests” projektben, „Class1Tests” osztályban van ez a teszt.

Egyszerű tesztelt projekt

Hogyan működik? Reflection Studio Test Explorer => NUnit NUnit reflexióval végigkeresi a solution(ból keletkező exék és dll-ek) összes elérhető osztályát [TestFixture] attribútum után [TestFixture] osztály [Test] attribútummal ellátott függvényei a tesztek, ezeket is megkeresi Értelmezi a tesztek működését/inputjait/stb. befolyásoló egyéb attribútumokat ([TestCaseSource], [Explicit], ... ... ... ) Reflexióval futtatja a teszteket

NUnit Gyakori felépítés („AAA”) Given…When…Then() Arrange: előkészítés, objektumok létrehozása, beállítása stb. Act: tesztelendő egyetlen lépés végrehajtása Assert: az eredmény, vagy ami a tesztelt tevékenység hatására történt, az az elvárásnak megfelelő-e? Given…When…Then()

NUnit Rengeteg lehetőség // Elvárások : Assert.That(result, Is.EqualTo("MyResult")); Assert.That(result, Is.Null); Assert.That(result, Is.LessThan(2)); Assert.That(result, Is.SameAs(otherReferenceToTheSameObject)); Assert.That(result, Is.Not.Null); // tagadás // Exception-ellenőrzések: Assert.That(() => t.MyTestedMethod(), Throws.TypeOf<NullReferenceException>()); Assert.That(() => t.MyTestedMethod(), Throws.Nothing); // régi szintaktika: (ugyanaz, mint az Is.EqualTo) Assert.AreEqual(result, 42); Assert.That után a második paraméterben mondatszerűen olvasható/írható („fluent”) szintaktika. Volt egy régi szintaktika is, régi NUnit még csak ezt tudta (utolsó sor). Assert.AreEqual, Assert.AreSame, Assert.IsNull, Assert.IsNotNull ... stb.

NUnit Akárhány input paraméter lehet a tesztmetódusban – ugyanennyit kell megadni a TestCase attribútumban Attribútum csak konstans értékeket kaphat -> TestCaseSource! Hasonló lehetőségek: [Sequential] – az input paraméterek megadott értékek közül sorra kapnak értékeket [Combinatorial] – az input paraméterek számára megadott értékek összes lehetséges kombinációjával meghívódik a teszt [Pairwise] – az előzőhöz képest optimalizált (kevesebb tesztesetet csinál)

NUnit TestCaseSource Dinamikusan készített v. nem konstans értékekkel dolgozó tesztesetekhez – akár saját osztályok átadása értékekként Sokféle formában használható: object[] helyett TestCaseData utód, property helyett metódus, osztály... public static IEnumerable<TestCaseData> MyTestCases { get List<TestCaseData> testCases = new List<TestCaseData>(); for (int i = 0; i < 10; i++) testCases.Add(new TestCaseData(new object[] { i, i * 2 })); } return testCases; [TestCaseSource("MyTestCases")] public void Class1_DoSomethingWithInput_ResultIsAsExpected(int input, int expected) // ... mint előbb

NUnit [Setup] [TearDown] [TestFixtureSetUp] / [OneTimeSetUp] Az így jelölt metódus minden egyes teszt vagy teszteset előtt le fog futni [TearDown] Az így jelölt metódus minden egyes teszt vagy teszteset futása után lefut [TestFixtureSetUp] / [OneTimeSetUp] Az így jelölt metódus az adott [TestFixture] tesztjeinek futtatása előtt fut, egyszer Pl. az összes teszt által használt objektumok hozhatók létre így – de vigyázzunk, a tesztek ideális esetben nem befolyásolhatják egymást! [TestFixtureTearDown] / [OneTimeTearDown] Az így jelölt metódus az adott [TestFixture] tesztjeinek futtatása után fut, egyszer [SetUpFixture] Osztályra rakható, namespace szintű setup/teardown OneTime... : NUnit 3.0-tól kezdve ez a neve

Jól tesztelni nehéz Legyenek a tesztek gyorsak Lassú tesztek folyamatos futtatása nem lehetséges => hibák késői kiderülését okozhatja Legyenek lehetőleg egymástól függetlenek Sorrend, időzítés stb. nem hathat ki az eredményre Ránézésre olvasható nevekkel A jól elkészített tesztlista dokumentálja a kód képességeit (requirement-listának fogható fel) Nem kell és nem is szabad minden inputlehetőséget lefedni Sokszor példákkal tesztelnek Corner case-ek megtalálása fontosabb Egyszerre egyetlen művelet, és egy osztály tesztelése Mindig függetlenül az éles adattól, ami változhat – tehát nem olvasunk éles adatbázist, éles settingsfájlt, stb. Osztályok függőségeit is helyettesítjük: Dependency Injection + tesztduplikátumok (test doubles) Ránézésre olvasható nevekkel: + ránézésre olvasható teszt is legyen Az egymástól való függetlenítés miatt akár kódduplikáció is simán megengedett

Tesztesetek – egyszerű kód if (max_x < 0 || max_y < 0) throw new ArgumentException("...");

Tesztesetek – egyszerű kód ??? if (max_x <= 0 || max_y <= 0) throw new ArgumentException("..."); if (max_x < 0 || max_y < 0) throw new ArgumentException("...");

Tesztesetek – komplex(ebb) kód …? // Warning - nem unittest! // Warning - nem unittest! // Warning - nem unittest! if (max_x <= 0 || max_y <= 0) throw new ArgumentException("...");

Warning – nem unittest!

Mit tehetünk?

Refaktorálás Tight coupling Refaktorálás = a kód struktúrájának módosítása a viselkedés módosítása nélkül Refactoring for testability

Refaktorált példa – NewsletterService

Refaktorált példa – NewsletterService

Refaktorált példa – NewsletterService

Refaktorált példa – NewsletterService Loose coupling

Dependency Injection Az osztályok függőségeit kívülről biztosítjuk – interfészek formájában A DI lehetővé teszi a fejlesztés előrehaladtával a függőség lecserélését – az interfész megtartása mellett Lehetővé teszi a „valódi” unit- („egység-”) tesztelést is Tesztelésnél szándékosan cseréljük a függőséget egy ismert, egyszerű, e célra létrehozott objektumra Osztály függetlenítése a függőségeitől („Mindig függetlenül az éles adattól” ... „Egyszerre egyetlen művelet, és egy osztály tesztelése”) Gyorsaság Komplex osztály helyett nagyon egyszerű csereobjektum, csak azokkal az aspektusokkal, amelyekről a teszt szól Függetlenség 1 teszt => 1 csereobjektum Ha a tesztet osztály esetleg írni akar az objektumba, az se gond Technikái: fake függőségek, mockolás, stb. A DI nem (elsősorban) teszt célú dolog, de a tesztelhetőség egy lényeges előny. A DI-t teljesen betartó kód írása bonyolult, a Main()-nek ismernie kéne minden függőséget? => IoC containerek

Constructor Injection interface IMyDependency { string DoSomething(); } class MyClass private IMyDependency dependency; public MyClass(IMyDependency dependency) this.dependency = dependency; // metódusaiban: dependency.DoSomething() // használata IMyDependency myDependency; // értékadás... MyClass myClass = new MyClass(myDependency);

Method Injection, Setter Injection class MyClass { public void DoSomethingUsingDependency(IMyDependency dependency) // ... dependency.DoSomething() ... } class MyClass { public IMyDependency Dependency { get; set; } // metódusaiban: dependency.DoSomething() } Constructor Injection – gyakori, ha sok helyen kell a függőség Method Injection – gyakori, ha egy helyen kell a függőség Setter Injection – ritka Mindenhol ellenőrizni kell, hogy be lett-e már állítva Többszálúság még több gondot okoz (nem lett-e újra null?) Most már használhatunk test double-öket!

Fake-ek Azonos interfészt implementál a helyettesítendő objektummal, de semmilyen, vagy csak szándékosan egyszerűsítő, tesztcélú logikát tartalmaz

Fake-ek

Mock-ok Azonos interfészt implementál a helyettesítendő objektummal – nincs logika, fix adat Általában lehetőséget ad a végrehajtódó logika megfigyelésére is Expectation-ök: „a DoSomething() függvény pontosan egyszer hívódott” Mocking framework segítségével szokás készíteni Mocking framework képességeitől függően a mock, fake, stub stb. különbség elmosódhat Nagyon gyakori, hogy egyszerűen fake-nek használják a mockokat (és nincs expectation-ellenőrzés) Az egyik legelterjedtebb .NET mocking framework: Moq Mock<IEmailSender> mockMailSender = new Mock<IEmailSender>(); // mock elvárt viselkedésének beállítása... NewsletterService service = new NewsletterService(mockMailSender.Object);

Mock elvárt viselkedésének beállítása Egy mock objektum bármely függvénye bármilyen hívást enged, nem dob exceptiont, és default értéket ad vissza Setup által módosítható ez a működés Onnantól csak az így meghatározott hívások megengedettek! Egy mock objektum propertyje nem jegyzi meg az értékét, és default értéket ad vissza Setup/SetupAllProperties által módosítható ez a működés Mock<ISubscriberRepository> repositoryMock = new Mock<ISubscriberRepository>(); Mock<IEmailSender> senderMock = new Mock<IEmailSender>(); // különféle elvárt viselkedések beállítása, paraméterektől függően repositoryMock.Setup(m => m.Subscribers).Returns(expectedSubscribers); repositoryMock.Setup(m => m.Subscribers).Returns(Enumerable.Empty<Subscriber>()); repositoryMock.Setup(m => m.Subscribers).Throws<NullReferenceException>(); senderMock.Setup( m => m.SendEmail("a@a.hu", "to", "subject", "body")).Returns(true); m => m.SendEmail(null, It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())) .Throws<NullReferenceException>(); ARRANGE fázisban csinálod ezt. A fenti Setup-ok egyszerre nyilván nem fognak működni, csak példák. Ha egyszer setupoltál, akkor csak a konkrétan megadott módokon tudod hívni a függvényt, különben exception!!!

Logika ellenőrzése mockkal (csak Setup után) // ARRANGE Mock<IEmployeeBusinessLogic> mbl = new Mock<IEmployeeBusinessLogic>(); // ... Setup a később ellenőrzendő függvényekre, propertykre... // ACT ... // ASSERT // 1x hívódott a@a.hu-ra senderMock.Verify( m => m.SendEmail("a@a.hu", It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Once); // sosem hívódott nullal m => m.SendEmail(null, It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()), Times.Never); // 0x volt 1-nél nagyobb log loggerMock.Verify( m => m.Log(It.Is<int>(i => i > 1), It.IsAny<string>()), Times.Never); ASSERT fázisban csinálod ezt

Példa

Test doubles http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html Forrás: http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html

Test doubles Astels = David Astels: Test-Driven Development - A practical guide Beck = Kent Beck: Test-Driven Development By Example Feathers = Michael Feathers: Working Effectively with Legacy Code Fowler = Martin Fowler: Mocks are Stubs jMock = Steve Freeman, Tim Mackinnon, Nat Pryce, Joe Walnes: Mock Roles, Not Objects UTWJ = Morgan Kaufmann: Unit Testing With Java OMG = Object Management Group's CORBA specs Pragmatic = Andy Hunt, Dave Thomas: Pragmatic Unit Testing with Nunit Recipes = J.B.Rainsberger: JUnit Recipes Forrás: http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html

Testability Code Smells Referenciák osztály és nem interfész típusú változókban Refaktorálás interfész típusú változókká new() Refaktorálás DI irányba (gyakran Factory pattern) DI: túl sok paraméter Túl sok dologért felelős az osztály, refaktorálás / bontás Esetleg összefoglalás közös objektumba Statikus osztályok és változók használata (pl. Singleton pattern) Refaktorálás példányok használatára Sok/hosszú statikus helper metódus Strukturált programozás OO helyett, kiszervezés nemstatikus osztályba Felhasználói interakciótól függő részek, ablakok Kiszervezés külön osztályba (Humble Object pattern) Adatbázis, fájlírás, egyéb külső erőforrás Kiszervezés külön osztályba (Repository, Humble Object pattern) Túl sokat kell mockolni “A code smell is a surface indication that usually corresponds to a deeper problem in the system.” ~ Martin Fowler

Módszertanok Először kód, utána tesztek Nehéz, nem hatékony! Test First: a fejlesztő a teszteket készíti el először, utána a kódot Előre leírja a kívánt követelményeket – eközben valószínűleg többet is tisztázni kell! Vagy biztosítja egy létező kód jelenlegi működésének megtartását átírás előtt TDD (Test-Driven Development): Sokszor pair programming-ben csinálják A kód ~100%-ban tesztelhetőre „íródik” meg Fejlesztési idő kb. duplázódik Nem mindent érdemes így tesztelni (elsősorban „algoritmikusabb” feladatokhoz ideális) BDD, ATDD...

Lefedettség dotCover NCover OpenCover Code coverage is collected by using a specialized tool to instrument the binaries to add tracing calls and run a full set of automated tests against the instrumented product. A good tool will give you not only the percentage of the code that is executed, but also will allow you to drill into the data and see exactly which lines of code were executed during a particular test. dotCover NCover OpenCover

Lefedettség Gyakran van alsó határ, de nem érdemes 100%-ra hajtani Nagyon sokféleképp lehet mérni – vs Use Case Coverage… Statement Coverage: minden utasítás lefutott (if, ciklus nincs benne) Branch Coverage: minden döntési ág lefutott (if, else) Condition Coverage: minden boolean kifejezés igaz és hamis értéket is kapott Loop Coverage: minden ciklus futott 0x, 1x és >1x, illetve ha lehetséges, a maximum limittel és annál eggyel nagyobbal. Parameter Value Coverage: paraméterek összes jellegzetes értéke tesztelendő (pl. string null, üres, whitespace…) Inheritance Coverage: visszaadott objektumtípus tesztelése … ust remember, having "100% code-coverage" doesn't mean everything is tested completely - while it means every line of code is tested, it doesn't mean they are tested under every (common) situation.. I would use code-coverage to highlight bits of code that I should probably write tests for. For example, if whatever code-coverage tool shows myImportantFunction() isn't executed while running my current unit-tests, they should probably be improved. Basically, 100% code-coverage doesn't mean your code is perfect. Use it as a guide to write more comprehensive (unit-)tests. Condition coverage: All boolean expressions to be evaluated for true and false. Decision coverage: Not just boolean expressions to be evaluated for true and false once, but to cover all subsequent if-elseif-else body. Loop Coverage: means, has every possible loop been executed one time, more than once and zero time. Also, if we have assumption on max limit, then, if feasible, test maximum limit times and, one more than maximum limit times. Entry and Exit Coverage: Test for all possible call and its return value. Parameter Value Coverage (PVC). To check if all possible values for a parameter are tested. For example, a string could be any of these commonly: a) null, b) empty, c) whitespace (space, tabs, new line), d) valid string, e) invalid string, f) single-byte string, g) double-byte string. Failure to test each possible parameter value may leave a bug. Testing only one of these could result in 100% code coverage as each line is covered, but as only one of seven options are tested, means, only 14.2% coverage of parameter value. Inheritance Coverage: In case of object oriented source, when returning a derived object referred by base class, coverage to evaluate, if sibling object is returned, should be tested.