SlideShare a Scribd company logo
1 of 55
Legéndi Richárd Olivér
             AITIA Szeminárium
                 rlegendi@aitia.ai
http://people.inf.elte.hu/legendi/
                    2012. május 25.
Áttekintkés
 Miért?
 Honnan jön?
 Kik?
 Hogyan?
 Hol használják aktívan?
 Mit követel meg?
 Toolok
    Ami belefér 
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.
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
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).
Hogyan?




Forrás: http://www.javacodegeeks.com/2012/05/test-driven-development-win-win.html
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
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.
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)
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)
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”
Toolok
 Özönvíz (pun intended )
   http://www.opensourcetesting.org/unit_java.php
   70 külön lib/framework/tool...
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
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.
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;
    }
}
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);
    }
}
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() {         // ...
  // ...                                        }
}
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
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)
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.
Egyéb Toolok
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...
Mocking frameworkök – ízelítő




http://code.google.com/p/jmockit/wiki/MockingToolkitComparisonMatrix
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);
}
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
 ...
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
    ...
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
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
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();
}
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
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
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/
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/
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...
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
Példa: Specs2 Forms
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 
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/
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")
}
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]
}
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%")
}
UI Testing
 Számtalan változat:
    WindowsTester
    Jubula (Eclipse-ben alapból van már)
    FEST
    Jemmy
    Maveryx
    ...
Selenium (Play!)
#{selenium 'Test security'}

   clearSession()
   open('/admin')
   assertTextPresent('Login')

   type('login', 'admin')
   type('password', '12345')
   clickAndWait('signin')

   assertText('success', 'Welcom admin!')

#{/selenium}
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();
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
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, ...
Ö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...
Ö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
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
Kérdések
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.
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

More Related Content

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

Szerver oldali fejlesztés korszerű módszerekkel C# nyelven
Szerver oldali fejlesztés korszerű módszerekkel C# nyelvenSzerver oldali fejlesztés korszerű módszerekkel C# nyelven
Szerver oldali fejlesztés korszerű módszerekkel C# nyelvenKrisztián Gyula Tóth
 
PHP alkalmazások minőségbiztosítása
PHP alkalmazások minőségbiztosításaPHP alkalmazások minőségbiztosítása
PHP alkalmazások minőségbiztosításaFerenc Kovács
 
A PHP 5.4 újdonságai
A PHP 5.4 újdonságaiA PHP 5.4 újdonságai
A PHP 5.4 újdonságaiFerenc Kovács
 
Mi a baj a Drupaloddal
Mi a baj a DrupaloddalMi a baj a Drupaloddal
Mi a baj a Drupaloddalthesnufkin
 
Objektum-orientált fejlesztés PHP nyelven (2. rész)
Objektum-orientált fejlesztés PHP nyelven (2. rész)Objektum-orientált fejlesztés PHP nyelven (2. rész)
Objektum-orientált fejlesztés PHP nyelven (2. rész)vvinston
 
Interface Design
Interface DesignInterface Design
Interface Designpzsigi
 
Objektum-orinetált mérések a gyakorlatban
Objektum-orinetált mérések a gyakorlatbanObjektum-orinetált mérések a gyakorlatban
Objektum-orinetált mérések a gyakorlatbanAntal Orcsik
 
Egységtesztek automatikus generálása forráskódból
Egységtesztek automatikus generálása forráskódbólEgységtesztek automatikus generálása forráskódból
Egységtesztek automatikus generálása forráskódbólZoltan Micskei
 
A PHP 5.5 újdonságai.
A PHP 5.5 újdonságai.A PHP 5.5 újdonságai.
A PHP 5.5 újdonságai.Ferenc Kovács
 
Mágikus Magento - Bevezetés a Magento világába
Mágikus Magento - Bevezetés a Magento világábaMágikus Magento - Bevezetés a Magento világába
Mágikus Magento - Bevezetés a Magento világábaJános Ács
 
Két Java fejlesztő első Scala projektje
Két Java fejlesztő első Scala projektjeKét Java fejlesztő első Scala projektje
Két Java fejlesztő első Scala projektjeDPC Consulting Ltd
 
Testing the system: ethical hacking and penetration testing (in Hungarian)
Testing the system: ethical hacking and penetration testing (in Hungarian)Testing the system: ethical hacking and penetration testing (in Hungarian)
Testing the system: ethical hacking and penetration testing (in Hungarian)Csaba Krasznay
 

Similar to Szoftver tesztelés - Gyakorlati jó-ha-tudod (16)

Ci
CiCi
Ci
 
Szerver oldali fejlesztés korszerű módszerekkel C# nyelven
Szerver oldali fejlesztés korszerű módszerekkel C# nyelvenSzerver oldali fejlesztés korszerű módszerekkel C# nyelven
Szerver oldali fejlesztés korszerű módszerekkel C# nyelven
 
Szoftver tesztelés
Szoftver tesztelésSzoftver tesztelés
Szoftver tesztelés
 
PHP alkalmazások minőségbiztosítása
PHP alkalmazások minőségbiztosításaPHP alkalmazások minőségbiztosítása
PHP alkalmazások minőségbiztosítása
 
A PHP 5.4 újdonságai
A PHP 5.4 újdonságaiA PHP 5.4 újdonságai
A PHP 5.4 újdonságai
 
Mi a baj a Drupaloddal
Mi a baj a DrupaloddalMi a baj a Drupaloddal
Mi a baj a Drupaloddal
 
Objektum-orientált fejlesztés PHP nyelven (2. rész)
Objektum-orientált fejlesztés PHP nyelven (2. rész)Objektum-orientált fejlesztés PHP nyelven (2. rész)
Objektum-orientált fejlesztés PHP nyelven (2. rész)
 
Laravel for Dummies
Laravel for DummiesLaravel for Dummies
Laravel for Dummies
 
Interface Design
Interface DesignInterface Design
Interface Design
 
Objektum-orinetált mérések a gyakorlatban
Objektum-orinetált mérések a gyakorlatbanObjektum-orinetált mérések a gyakorlatban
Objektum-orinetált mérések a gyakorlatban
 
Egységtesztek automatikus generálása forráskódból
Egységtesztek automatikus generálása forráskódbólEgységtesztek automatikus generálása forráskódból
Egységtesztek automatikus generálása forráskódból
 
Jee kurzus 8. het
Jee kurzus 8. hetJee kurzus 8. het
Jee kurzus 8. het
 
A PHP 5.5 újdonságai.
A PHP 5.5 újdonságai.A PHP 5.5 újdonságai.
A PHP 5.5 újdonságai.
 
Mágikus Magento - Bevezetés a Magento világába
Mágikus Magento - Bevezetés a Magento világábaMágikus Magento - Bevezetés a Magento világába
Mágikus Magento - Bevezetés a Magento világába
 
Két Java fejlesztő első Scala projektje
Két Java fejlesztő első Scala projektjeKét Java fejlesztő első Scala projektje
Két Java fejlesztő első Scala projektje
 
Testing the system: ethical hacking and penetration testing (in Hungarian)
Testing the system: ethical hacking and penetration testing (in Hungarian)Testing the system: ethical hacking and penetration testing (in Hungarian)
Testing the system: ethical hacking and penetration testing (in Hungarian)
 

More from Richard Oliver Legendi

Tools For Statistical And Behavioral Analysis Of Mason Models
Tools For Statistical And Behavioral Analysis Of Mason ModelsTools For Statistical And Behavioral Analysis Of Mason Models
Tools For Statistical And Behavioral Analysis Of Mason ModelsRichard Oliver Legendi
 
When Experimental and Computational Research Meet: The Participatory Extensio...
When Experimental and Computational Research Meet: The Participatory Extensio...When Experimental and Computational Research Meet: The Participatory Extensio...
When Experimental and Computational Research Meet: The Participatory Extensio...Richard Oliver Legendi
 
Comparison of Elementary Dynamic Network Models Using Empirical Data
Comparison of Elementary Dynamic Network Models Using Empirical DataComparison of Elementary Dynamic Network Models Using Empirical Data
Comparison of Elementary Dynamic Network Models Using Empirical DataRichard Oliver Legendi
 
Model Replication in the Context of Agent-based Simulation
Model Replication in the Context of Agent-based SimulationModel Replication in the Context of Agent-based Simulation
Model Replication in the Context of Agent-based SimulationRichard Oliver Legendi
 
Replication of Macroeconomics from the Bottom-up
Replication of Macroeconomics from the Bottom-upReplication of Macroeconomics from the Bottom-up
Replication of Macroeconomics from the Bottom-upRichard Oliver Legendi
 
ELTE VI. féléves doktori beszámoló
ELTE VI. féléves doktori beszámolóELTE VI. féléves doktori beszámoló
ELTE VI. féléves doktori beszámolóRichard Oliver Legendi
 
Fables - Funkcionális programozási nyelv ágens-alapú szimulációkhoz
Fables - Funkcionális programozási nyelv ágens-alapú szimulációkhozFables - Funkcionális programozási nyelv ágens-alapú szimulációkhoz
Fables - Funkcionális programozási nyelv ágens-alapú szimulációkhozRichard Oliver Legendi
 
FABLES IME - Agent-Based Modeling environment
FABLES IME - Agent-Based Modeling environmentFABLES IME - Agent-Based Modeling environment
FABLES IME - Agent-Based Modeling environmentRichard Oliver Legendi
 
2011 Eclipse DemoCamp Budapest, Indigo Release
2011 Eclipse DemoCamp Budapest, Indigo Release2011 Eclipse DemoCamp Budapest, Indigo Release
2011 Eclipse DemoCamp Budapest, Indigo ReleaseRichard Oliver Legendi
 
2010/04/28 IK Szakest, Ágens-alapú szimulációk
2010/04/28 IK Szakest, Ágens-alapú szimulációk2010/04/28 IK Szakest, Ágens-alapú szimulációk
2010/04/28 IK Szakest, Ágens-alapú szimulációkRichard Oliver Legendi
 

More from Richard Oliver Legendi (10)

Tools For Statistical And Behavioral Analysis Of Mason Models
Tools For Statistical And Behavioral Analysis Of Mason ModelsTools For Statistical And Behavioral Analysis Of Mason Models
Tools For Statistical And Behavioral Analysis Of Mason Models
 
When Experimental and Computational Research Meet: The Participatory Extensio...
When Experimental and Computational Research Meet: The Participatory Extensio...When Experimental and Computational Research Meet: The Participatory Extensio...
When Experimental and Computational Research Meet: The Participatory Extensio...
 
Comparison of Elementary Dynamic Network Models Using Empirical Data
Comparison of Elementary Dynamic Network Models Using Empirical DataComparison of Elementary Dynamic Network Models Using Empirical Data
Comparison of Elementary Dynamic Network Models Using Empirical Data
 
Model Replication in the Context of Agent-based Simulation
Model Replication in the Context of Agent-based SimulationModel Replication in the Context of Agent-based Simulation
Model Replication in the Context of Agent-based Simulation
 
Replication of Macroeconomics from the Bottom-up
Replication of Macroeconomics from the Bottom-upReplication of Macroeconomics from the Bottom-up
Replication of Macroeconomics from the Bottom-up
 
ELTE VI. féléves doktori beszámoló
ELTE VI. féléves doktori beszámolóELTE VI. féléves doktori beszámoló
ELTE VI. féléves doktori beszámoló
 
Fables - Funkcionális programozási nyelv ágens-alapú szimulációkhoz
Fables - Funkcionális programozási nyelv ágens-alapú szimulációkhozFables - Funkcionális programozási nyelv ágens-alapú szimulációkhoz
Fables - Funkcionális programozási nyelv ágens-alapú szimulációkhoz
 
FABLES IME - Agent-Based Modeling environment
FABLES IME - Agent-Based Modeling environmentFABLES IME - Agent-Based Modeling environment
FABLES IME - Agent-Based Modeling environment
 
2011 Eclipse DemoCamp Budapest, Indigo Release
2011 Eclipse DemoCamp Budapest, Indigo Release2011 Eclipse DemoCamp Budapest, Indigo Release
2011 Eclipse DemoCamp Budapest, Indigo Release
 
2010/04/28 IK Szakest, Ágens-alapú szimulációk
2010/04/28 IK Szakest, Ágens-alapú szimulációk2010/04/28 IK Szakest, Ágens-alapú szimulációk
2010/04/28 IK Szakest, Ágens-alapú szimulációk
 

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

  • 1. Legéndi Richárd Olivér AITIA Szeminárium rlegendi@aitia.ai http://people.inf.elte.hu/legendi/ 2012. május 25.
  • 2.
  • 3. Áttekintkés  Miért?  Honnan jön?  Kik?  Hogyan?  Hol használják aktívan?  Mit követel meg?  Toolok  Ami belefér 
  • 4. 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.
  • 5. 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
  • 6. 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).
  • 8. 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
  • 9. 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.
  • 10. 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)
  • 11. 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)
  • 12. 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”
  • 13.
  • 14. Toolok  Özönvíz (pun intended )  http://www.opensourcetesting.org/unit_java.php  70 külön lib/framework/tool...
  • 15. 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
  • 16. 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.
  • 17. 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; } }
  • 18. 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); } }
  • 19. 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() { // ... // ... } }
  • 20. 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
  • 21. 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)
  • 22. 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.
  • 24. 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...
  • 25. Mocking frameworkök – ízelítő http://code.google.com/p/jmockit/wiki/MockingToolkitComparisonMatrix
  • 26. 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); }
  • 27. 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  ...
  • 28. 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  ...
  • 29. 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
  • 30. 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
  • 31. 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(); }
  • 32. 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
  • 33. 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
  • 34. 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/
  • 35. 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/
  • 36. 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...
  • 37. 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
  • 39. 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 
  • 40. 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/
  • 41. 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") }
  • 42. 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] }
  • 43. 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%") }
  • 44. UI Testing  Számtalan változat:  WindowsTester  Jubula (Eclipse-ben alapból van már)  FEST  Jemmy  Maveryx  ...
  • 45. Selenium (Play!) #{selenium 'Test security'} clearSession() open('/admin') assertTextPresent('Login') type('login', 'admin') type('password', '12345') clickAndWait('signin') assertText('success', 'Welcom admin!') #{/selenium}
  • 46. 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();
  • 47. 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
  • 48. 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, ...
  • 49. Ö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...
  • 50. Ö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
  • 51. 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
  • 53.
  • 54. 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.
  • 55. 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