O slideshow foi denunciado.
Seu SlideShare está sendo baixado. ×

Szoftver tesztelés - Gyakorlati jó-ha-tudod

Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Anúncio
Próximos SlideShares
20111130 oa gtest
20111130 oa gtest
Carregando em…3
×

Confira estes a seguir

1 de 55 Anúncio
Anúncio

Mais Conteúdo rRelacionado

Semelhante a Szoftver tesztelés - Gyakorlati jó-ha-tudod (16)

Mais de Richard Oliver Legendi (10)

Anúncio

Szoftver tesztelés - Gyakorlati jó-ha-tudod

  1. 1. Legéndi Richárd Olivér AITIA Szeminárium rlegendi@aitia.ai http://people.inf.elte.hu/legendi/ 2012. május 25.
  2. 2. Áttekintkés  Miért?  Honnan jön?  Kik?  Hogyan?  Hol használják aktívan?  Mit követel meg?  Toolok  Ami belefér 
  3. 3. Miért?  Quality  Ami nektek, a fejlesztőknek fontos:  Bizalom a saját kódodban  Refactor: Nem félsz változtatni  Nem fogod elbaszni, a teszted megfogja, ha valamit eltörtél!  Hype téma, csapból is ez folyi  Boldog-boldogtalan tesztkörnyezeteket ír  Tanuló tesztek, határvonalak tisztán tartása, regression tesztek (megoldott issue ne jöhessen vissza), etc.
  4. 4. Honnan jön: RoR  Agilis srácok  Irgalmatlan egyszerű használni: test "login with invalid credentials" do post :login => { :user_name => 'foo', :password =>'bar‚ } assert_equals flash[:error] , "Authentication failed" end
  5. 5. Kik?  Tesztvezérelt-fejlesztés (TDD) és a Behaviour Driven Development (BDD, végrehajtható specifikáció) elkötelezett hívei (v.ö. eXtreme Programming: nincs terv, kódolnak egyből).
  6. 6. Hogyan? Forrás: http://www.javacodegeeks.com/2012/05/test-driven-development-win-win.html
  7. 7. Hogyan?  A TDD három alapelve: 1. Nem írsz tényleges kódot, amíg nem írtál hozzá tesztet. 2. A tesztből annyit írsz meg, amennyi a kudarchoz elég (ha nem fordul pl., az már kudarc). 3. A tényleges kódból csak annyit írsz meg, ami elég a teszt sikeres teljesítéséhez.  „TDD-ciklus”: Test  Code  Refactor  A teszt és production kód szimbiózisban születik
  8. 8. Milyen?  F.I.R.S.T. alapelvek:  Fast - Ha lassú, nem futtatod.  Independent - Ha függőség van, hibát rejthet el.  Repeatable - Bárhol megismételhető (minden fejlesztőnél reprodukálható legyen a hiba).  Self-validating - Ha kézzel kell hasonlítgatnod a teszt eredményét, úgysem fogsz vele foglalkozni.  Timely - Rég nem támogatott API funkciók tesztje teljesen felesleges.
  9. 9. Mit követel meg?  A tervezést, kódstrukturát is átalakítja.  Kicsit más kódszervezés kell (mellékhatások elkerülése - azt nem tudod tesztelni)  Sok POJO, minimális funkcionalitással (azt könnyű tesztelni)
  10. 10. Mit követel meg?  Egyéb apróságok, pl. lazy instantiationt kidobni (premature optimalizáció)  Osztály nem vállalja fel a másodlagos feladatokat (Single Resp. Princ.)  Helyette inkább IoC/Dep. Inj. (AOP keretek, akkor hozza létre, amikor kell)
  11. 11. Tesztek fajtái  Mindre nézünk toolt:  Unit: ~POJO-k  Functional: ~project  Integration: ~full stack  Embedded DB + in-proc. web server + JWebUnit/Selenium  Acceptance: ~„user story”
  12. 12. Toolok  Özönvíz (pun intended )  http://www.opensourcetesting.org/unit_java.php  70 külön lib/framework/tool...
  13. 13. Assert  Lerágott csont, de szerintem hasznos   Control-flow invariant, etc.  Nem egy DbC facility, de hasznos:  Internal Invariants  Control-Flow Invariants  Preconditions, Postconditions, and Class Invariants http://docs.oracle.com/javase/1.4.2/docs/guide/lang/assert.html
  14. 14. Unit tesztek  Egységek (pl. modellek) tesztelésére  Tonnányi keretrendszer (JUnit/TestNG/...)  Kent Beck (XP megalkotója, Agile demigod), Erich Gamma (hasonló kaliberű úriember, pl. Eclipse JDT- ben volt benne a keze) haxolta össze egy repülőgépen a JUnit első verzióját.
  15. 15. Példa public class Utils { public static int sum(int[] arr) { if (null == arr) { throw new IllegalArgumentException("arr == null"); } int sum = 0; for (int i : arr) { sum += i; } return sum; } }
  16. 16. Tesztek (JUnit 4.x) import org.junit.* ; import static org.junit.Assert.* ; public class UtilsTest { @Test public void assertSumForZeroArray() { final int[] arr = new int[0]; // Given final int actual = Utils.sum(arr); // When final int expected = 0; // Then assertEquals("Sum of empty array must be zero.", expected, actual); } @Test(expected=IllegalArgumentException.class) public void assertForIllegalArgument() { Utils.sum(null); } }
  17. 17. Egyéb hasznos annotációk @Ignore("John broke this yesterday") @Test(timeout=1000) @Test public void public void someMethodThatShouldRunInAMinute() { someBuggyOrUnimplementedTest() { // ... // ... } } @Before @BeforeClass public void beforeEachTest() { public void initializeStuffBeforeAnyTests() { // ... // ... } } @After @AfterClass public void afterEachTest() { public void cleanupStuffAfterAllTests() { // ... // ... } }
  18. 18. Egyéb hasznos assert utasítások  assertTrue(...);  Tonnányi egyéb  assertFalse();  Ld. Assert javadoc  fail();  assertEquals(...);  assertArrayEquals(...);  assertEquals(...);  assertNotNull(...);  assertNull(...);  assertSame(...);  assertNotSame(...);  assertEquals(...);  assertThat(...); // Matcher
  19. 19. Common Pitfalls  Egy teszt-egy állítás (nem feltétlen egy assert utasítás)  Teszttel is játsz egy kicsit! Az is kód, abban is annyira bízz...  Triviális tesztek!   Triviális hibakeresés  Ajánlás: tényleges kód és a tesztek külön source mappában (production kódban semmi helye, tisztességes build tooloknál ez alap)  Láthatóság: a legritkább esetben oldjuk fel tesztek miatt. Legyen ez az utolsó, amivel próbálkozunk!  Vigyázat, 2 JUnit osztály van! A másik legacy...  Randomizálás? Inkább ne...  Mutation testing  assertTrue(actual == 0) != assertEquals(expected, actual)
  20. 20. IDE Integráció  Eclipse  Hozzáadás: Project jobklikk -> Properties -> Java Build Path -> Libraries -> Add Library -> JUnit -> JUnit 4 (alapból benne van)  Futtatás: Jobklikk -> Run As... -> JUnit  NetBeans  Alapból benne van egy egyszerű Java projectben.
  21. 21. Egyéb Toolok
  22. 22. Mocking  Motiváció: adatbázis nincs...  DAO-s példa: van interfész, van JdbcDao implementáció, aztán meg Test1Dao implementáció...  DE! Helyette: lehet mockolni, ügyes cuccok (Néha már-már internal DSL benyomását keltő toolok)  Ebből is van egy pár...
  23. 23. Mocking frameworkök – ízelítő http://code.google.com/p/jmockit/wiki/MockingToolkitComparisonMatrix
  24. 24. Mocking: Példa public void testBobsLogin() { User results = new User(); String userName = "bob"; String password = "bob1234"; String passwordHash = "0340e21833f1291f673fcaab8d13"; expect(mockDao.queryUserData(userName, passwordHash)) .andReturn(results); replay(mockDao); assertTrue(service.login(userName, password)); verify(mockDao); }
  25. 25. Tonnányi egyéb feature  Ellenőrzések  Hívások min/max/pontos száma  Sorrendiség  Részleges mockolás  Spy: adott függvények kiütésére  Viselkedés felvétele, visszajátszása, ellenőrzése  ...
  26. 26. PowerMock  Ha elértük a korlátokat, "jó lenne..." funkciók  Támogat több platformot  Mockito/EasyMock/...  Példák:  statikus függvények mockolása  final classok mockolása  ...
  27. 27. Hamcrest  Matcher library (innen a név)  "Literate programming" (Knuth, 1970)  Példával a legkönnyebb megérteni:  assertThat("Ray went to holiday", developers.getRay().countReadBooks(), equalTo(10));  assertThat(Math.sqrt(-1), is(notANumber()));  A BDD-s srácok nagyon szeretik  Kényelmi funkcionalitása van
  28. 28. Design by Contract  Eiffel – Bertrand Meyer  Minden komponensnek contractja van (Nem is áll olyan messze tőlünk, ld. equals(), hashCode() Javadocját!)  Ebből is van tonnányi, 3 példa:  comment, annotációs, konfigurációs osztályos  Invariáns, elő- és utófeltételek  Assertekkel kiváltható? Nem igazán...  AspectJ-vel lehet játszani egy szintig, de...  Hol hasznos? Pl. szervleteknél ott, ahol macera a tesztelés
  29. 29. Példa @Invariant("getCount() >= 0") public interface Stack<E> { int getCount(); ... @Ensure("{result}==(getCount()==0)") public boolean isEmpty(); @Require("getCount() > 0 ") @Ensure("getCount() == {old getCount()} - 1 ") void remove(); }
  30. 30. Code coverage  Nagyobb projectnél könnyű elveszteni, mit mennyire teszteltünk  Megoldás: Code coverage (számtalan definíció szerint)  Reneteg tool, pl. Clover, Cobertura (generált doksik királyak)  Vannak pluginok az IDE-kben, pl. EclEmma
  31. 31. Code coverage  Maximizálni érdemes, nem érdemes?  Nem biztos, hogy megéri a 100%-ra hajtani - bár láttam már ilyet (és nem is mindig megoldható, pl. BufferedReadert megfelelően használni lehetetlen)  Néha meg a 400% is kevés...  Koncentráljunk a lényeges komponensekre
  32. 32. Continuous Integration rendszerek  Rengeteg tool: Hudson, Jenkins, Bamboo, ...  Mikor?  Ha sok teszt van, és nem elég a GridGain farm pl. Unit tesztek gyorsan lefutnak, de lehetnek sokan.  Integráció! pl. cm/inch  Kapható/építhető build status jelző  http://hackaday.com/2011/04/12/led-build-monitor-helps-keep-an-eye-on-your-servers/
  33. 33. Sonar  Mindenféle statisztikák - a trend miatt fontos.  Összekötve a CI rendszerrel  Mutatja a tesztelésre szoruló részeket  Tonnányi projecthez példa:  http://nemo.sonarsource.org/
  34. 34. Acceptance tesztek  Rengeteg tool, framework, pl. FitNesse, Specs2  Decision table egy Wikibe  Teszt, minimális kóddal  Átruházható a tesztírás a kliensre  Haha...
  35. 35. Példa: FitNesse  Wiki: |eg.Division| |numerator|denominator|quotient?| |10 |2 |5 | |12.6 |3 |4.2 | |100 |4 |33 |  Kell hozzá egy minimális Java osztály, 3 adattaggal  Lesz egy nagy zöld „Teszt” gomb  Meg lehet nyomni  Példa: http://fitnesse.org/FitNesse.UserGuide.TwoMinuteExample
  36. 36. Példa: Specs2 Forms
  37. 37. BDD  Wiki:  BDD is a second-generation, outside–in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.  Magyarul: értse meg a nem kóder is a teszteket 
  38. 38. DSL – Scala, Specs1/2 class HelloWorldSpec extends Specification { "The 'Hello world' string" should { "contain 11 characters" in { "Hello world" must have size(11) } "start with 'Hello'" in { "Hello world" must startWith("Hello") } "end with 'world'" in { "Hello world" must endWith("world") } } } Forrás: http://etorreborre.github.com/specs2/
  39. 39. DSL – Scala, Specs2 import org.specs2._ class HelloWorldSpec extends Specification { def is = "This is a specification to check the 'Hello world' string" ^ p^ "The 'Hello world' string should" ^ "contain 11 characters" ! e1^ "start with 'Hello'" ! e2^ "end with 'world'" ! e3^ end def e1 = "Hello world" must have size(11) def e2 = "Hello world" must startWith("Hello") def e3 = "Hello world" must endWith("world") }
  40. 40. DSL – Groovy (Spock) @Unroll void "Ship goes to red alert only when enemy charges weapons"() { given: CommandComputer commandComputer = new CommandComputer() and: ~JUnit Theories, de egyszerűbb when: szintakszissal commandComputer.updateFromSensors(sensorReading) Forrás: http://sett.ociweb.com/sett/settFeb2012.html then: commandComputer.getAlertStatus() == expectedAlertStatus where: entityType << [EntityType.SHIP, EntityType.ANOMALY] powerReading << [PowerReading.HIGH, PowerReading.LOW] friendOrFoe << [FriendOrFoe.FOE, FriendOrFoe.UNKNOWN] powerType << [PowerType.WEAPONS, PowerType.RADIATION] direction << [Direction.TOWARD_SHIP, Direction.AWAY_FROM_SHIP] expectedAlertStatus << [AlertStatus.RED, AlertStatus.GREEN] }
  41. 41. DSL – Groovy (Spock) void "red alert causes shields be raised with the correct shield frequency"() { given: EnvironmentSystem environmentSystem = Mock(EnvironmentSystem) ShieldSystem shieldSystem = Mock(ShieldSystem) CommandComputer commandComputer = new CommandComputer() commandComputer.setEnvironmentSystem(environmentSystem) commandComputer.setShieldSystem(shieldSystem) when: String result = commandComputer.execute("Red Alert") then: 1 * shieldSystem.raiseShields({int shieldFrequency -> shieldFrequency == commandComputer.getShieldFrequency() }) >> 100 result.contains("Shield Strength 100%") }
  42. 42. UI Testing  Számtalan változat:  WindowsTester  Jubula (Eclipse-ben alapból van már)  FEST  Jemmy  Maveryx  ...
  43. 43. Selenium (Play!) #{selenium 'Test security'} clearSession() open('/admin') assertTextPresent('Login') type('login', 'admin') type('password', '12345') clickAndWait('signin') assertText('success', 'Welcom admin!') #{/selenium}
  44. 44. Selenium – Java API WebDriver driver = new FirefoxDriver(); driver.get("http://www.google.com"); WebElement element = driver.findElement(By.name("q")); element.sendKeys("Cheese!"); element.submit(); // Wait for the page to load, timeout after 10 seconds (new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver d) { return d.getTitle().toLowerCase().startsWith("cheese!"); } }); driver.quit();
  45. 45. Egyéb hasznos toolok  FindBugs – meglepődtök majd...  PMD/CMD  Patternek, ajánlások  Copy & paste kódok kiszűrése  Ant/Maven targetek, GUI-s alkalmazás, Eclipse plugin
  46. 46. Amiről nem esett szó, de jó lenne...  Stressz-teszt  JMeter http://netbeans.org/kb/docs/javaee/ecommerce/test-profile.html  Selenium IDE  Mutation testing: kipróbálod, szar, tényleg reccsen? (pl. PIT, a JUnitos srácok csinálják)  JUnit:  Theories, experimental feature-ök  Data tables  Arquillian (JBoss test framework)  Security testing:  Acuentix WebVulnerability Scanner, SQL Ninja, Tenable Nessus, ...
  47. 47. Összefoglalás  Megéri? Kódot megírni ~t idő, tesztelve megírni ~3t  DE! 2-3 manuális teszt után már egyértelműen megéri a befektetés (szerintem)  Tekintve, hogy p megírás, q fenntartás, és p <<< q...
  48. 48. Összefoglalás  Saját tapasztalat:  Kb. mindegy, melyik toolt használod, csak használd!  Megszünnek a napokig tartó debuggolások  Nem félsz hozzányúlni a kódhoz  Nem elfelejteni: a tesztkód írása ugyanolyan fegyelmet követel a fejlesztőtől, mint a tényleges kód írása...  Ha megszokod, nem kód többé, amihez nincs teszt (pl. R-ben is csak tesztekkel írok scriptet)  Tesztet írni fun – kielégíti az ember lelkének gonoszkodó kis részét   Jó, ha van 3 környezet: dev – test – prod
  49. 49. Megjegyzések  Metrikák: nem túl hasznosak, korrelálnak a LoC-dal  Sonar: „minőségi mutatók”  Könyvajánló: Robert C. Martin: Clean Code: A Handbook of Agile Software Craftsmanship Martin J. Fowler et al.: Refactoring Improving the Design of Existing Code
  50. 50. Kérdések
  51. 51. Köszönöm a figyelmet! Legéndi Richárd Olivér AITIA Szeminárium rlegendi@aitia.ai http://people.inf.elte.hu/legendi/ 2012. május 25.
  52. 52. Demo  Eclipse: JUnit hozzáadása, futtatása  Eclipse: Code coverage mutogatása  Sonar: EDN project  Crisis: Mark 1 Jenkins-project  Generált Maven doksi  Code coverage

×