Testowanie w Extreme Programming

Jednym z podstawowych postulatów XP jest automatyczne testowanie zarówno jednostkowe jak i integracyjne. Testy zapewniają nam sprzężenie zwrotne, które dostarcza informacji o jakości utworzonego kodu. XP posuwa się jeszcze o krok dalej -- stawia testy jako narzędzie wspomagające proces implementacji. Wyniki testów mówią nam o stanie zaawansowania projektu.

Testy jednostkowe - są testami najniższego poziomu, wykonywane są dla pojedynczych funkcji.
Testy integracyjne - są to testy powiązań między modułami.

Typowy cykl pracy podczas dodawania nowej funkcjonalności to:

Inną, typową sytuacją spotykaną podczas programowania jest zmiana funkcjonalności. Szczególnie często ona występuje przy przyrostowym tworzeniu systemu. Zmieniając istniejącą funkcjonalność można jednak spowodować błędy w kodzie, który zależy od właśnie zmodyfikowanego kodu. Oczywiście znowu zaczniemy od testów:

Podobnie postępujemy w momencie znalezienia błędu -- najpierw dodajemy test ujawniający znaleziony błąd. Następnie uruchamiamy testy, by upewnić się, że błąd rzeczywiście jest wykrywany. Dopiero wtedy, posiadając testy "wyczulone" na zlokalizowany błąd, aktualizujemy implementację. Poprawka jest zakończona wtedy, gdy testy kończą się sukcesem.


Prosty projekt z wykorzystaniem JUnit w Eclipsie

  1. Pobrac JUnit. Aktualna wersja 3.8.1 (ok 500kB), ze strony projektu JUnit www.junit.org
  2. Stworzyć Java project o nazwie JUnit.
  3. Zaimportować do katalogu src niektóre źródła z pliku src.jar, który był w pliku junit3.8.1.zip.
  4. Stworzyć nowy projekt TrafficLights i dodać do jego Java Build Path projekt JUnit.
  5. Stworzyć nową klasę TrafficLightsTest w pakiecie trafficlightsmodel dziedziczącą po klasie junit.framework.TestCase
  6. Można teraz napisać metodę testującą jeszcze nie stworzoną klasę TrafficLights. Aby metoda była wywoływana jako test, należy jej nazwę zacząć od "test":
    public class TrafficLightsTest extends TestCase {
     public void testNewTrafficLights() {
      TrafficLights a = new TrafficLights();
      assertEquals(true, a.getRed());
      assertEquals(false, a.getYellow());
      assertEquals(false, a.getGreen());
     }
    }
    
  7. Przy pomocy QuickFix można wygenerować klasę TrafficLights i jej metody:
    public class TrafficLights {
     public boolean getRed() {
      return false;
     }
     public boolean getYellow() {
      return false;
     }
     public boolean getGreen() {
      return false;
     }
    }
    
    
  8. Można już przeprowadzić pierwszy test - Run -> JUnit Test

    Oczywiście nie będzie pomyślny, dopóki nie zmienimy metody getRed() na:
     public boolean getRed() {
      return true;
     }
    


  9. Do klasy TrafficLights przyda się metoda step(), która będzie zmieniała kolor świateł.
  10. Najpierw wedle metodologii XP, powinno się stworzyć testy metody step(). Zmiana klasy TrafficLightsTest:
    public class TrafficLightsTest extends TestCase {
     private void assertLights(String expected, TrafficLights a) {
      String actual = "";
      if (a.getRed()) actual += "R";
      if (a.getYellow()) actual +="Y";
      if (a.getGreen()) actual += "G";
      assertEquals("Lights", expected, actual);
     }
    
     public void testNewTrafficLights() {
      TrafficLights a = new TrafficLights();
      assertLights("R", a);
     }
    
     public void testStepping() {
      TrafficLights a = new TrafficLights();
      a.step();
      assertLights("RY", a);
      a.step();
      assertLights("G", a);
      a.step();
      assertLights("Y", a);
      a.step();
      assertLights("R", a);
     }
    }
    
  11. Skoro są testy, to należy dokończyć implementację klasy TrafficLights
    public class TrafficLights {
     private static final int RED = 1, YELLOW = 2, GREEN = 4;
     private int lights = RED;
     private boolean isLit(int color) {
      return (lights & color) == color;
     }
     public boolean getRed() {
      return isLit(RED);
     }
     public boolean getYellow() {
      return isLit(YELLOW);
     }
     public boolean getGreen() {
      return isLit(GREEN);
     }
     public void step() {
      switch (lights) {
       case RED: lights = RED+YELLOW; break;
       case RED+YELLOW: lights = GREEN; break;
       case GREEN: lights = YELLOW; break;
       case YELLOW: lights = RED; break;
       default: throw new RuntimeException("Illegal TrafficLights State: " + lights);
      }  
     }
    }
    
    Uruchamiamy ponownie test klikając ikonkę w widoku JUnit.

    Wszystko teraz powinno pójść ok.

Bibliografia



Strona główna