Jak napisać test jednostkowy?


135

Mam klasę Java. Jak mogę to przetestować jednostkowo ?


W moim przypadku mam klasę robi sumę binarną. Pobiera dwie byte[]tablice, sumuje je i zwraca nową tablicę binarną.


7
Możesz skorzystać z narzędzia takiego jak jUnit i napisać przypadki testowe (metody testowe) dla swojej klasy java. Następnie wywołaj testy jUnit jako część procesu budowania (ant / maven). Korzystanie z jUnit nie jest wcale trudne, najtrudniejszą częścią jest wymyślenie tylu scenariuszy testowych, które możesz wymyślić, aby wcześnie i często łapać błędy.
CoolBeans,

Odpowiedzi:


133
  1. Zdefiniuj oczekiwane i pożądane dane wyjściowe dla normalnego przypadku, z poprawnymi danymi wejściowymi.

  2. Teraz zaimplementuj test, deklarując klasę, nazwij ją dowolnie (zwykle coś w rodzaju TestAddingModule) i dodaj do niego metodę testAdd (tj. Taką jak ta poniżej):

    • Napisz metodę, a nad nią dodaj adnotację @Test.
    • W metodzie uruchom sumę binarną i assertEquals(expectedVal,calculatedVal).
    • Przetestuj swoją metodę, uruchamiając ją (w Eclipse kliknij prawym przyciskiem myszy, wybierz Uruchom jako → Test JUnit).

      //for normal addition 
      @Test
      public void testAdd1Plus1() 
      {
          int x  = 1 ; int y = 1;
          assertEquals(2, myClass.add(x,y));
      }
  3. Dodaj inne przypadki według potrzeb.

    • Sprawdź, czy suma binarna nie zgłasza nieoczekiwanego wyjątku w przypadku przepełnienia liczby całkowitej.
    • Sprawdź, czy Twoja metoda z wdziękiem obsługuje dane wejściowe o wartości Null (przykład poniżej).

      //if you are using 0 as default for null, make sure your class works in that case.
      @Test
      public void testAdd1Plus1() 
      {
          int y = 1;
          assertEquals(0, myClass.add(null,y));
      }

1. czy wymagana jest notacja @Test? 2. dlaczego nie sprawdzić, czy dane wejściowe są zerowe za pomocą assertNotNull? 3. gdzie są przechwytywane wyniki testów jednostkowych? w jaki sposób wyniki są wskazywane użytkownikowi?
user137717

10
Tak, @Testnotacja jest wymagana. Ma to na celu zasygnalizowanie biegaczowi testów jednostkowych, że ta metoda reprezentuje test jednostkowy i powinna zostać wykonana. Metody bez adnotacji nie @Testsą wykonywane przez moduł uruchamiający testy.
Ali Shah Ahmed

do drugiego testu - czy dodanie a nie powinno nullpo yprostu dać y?
Adjit

Dzięki! Chcę wiedzieć, dlaczego nie ma potrzeby dodawania staticdo modyfikatora metody testowej.
Liang Zhang

103

Udostępniam ten post zarówno dla IntelliJ, jak i Eclipse .

Zaćmienie:

Aby wykonać test jednostkowy dla swojego projektu, wykonaj następujące kroki (używam Eclipse do napisania tego testu):

1- Kliknij Nowy -> Projekt Java.

Utwórz projekt

2- Zapisz nazwę swojego projektu i kliknij Zakończ.

Utwórz projekt

3- Kliknij prawym przyciskiem myszy swój projekt. Następnie kliknij Nowy -> Klasa.

Utwórz klasę

4- Zapisz nazwę swojej klasy i kliknij Zakończ.

Utwórz klasę

Następnie wypełnij zajęcia w ten sposób:

public class Math {
    int a, b;
    Math(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public int add() {
        return a + b;
    }
}

5- Kliknij Plik -> Nowy -> Przypadek testowy JUnit.

Utwórz test JUnite

6- Sprawdź setUp () i kliknij Zakończ. SetUp () będzie miejscem, w którym zainicjujesz swój test.

Sprawdź SetUp ()

7- Kliknij OK.

Dodaj JUnit

8- Tutaj po prostu dodaję 7 i 10. Tak więc oczekuję, że odpowiedź będzie wynosić 17. Wypełnij klasę testową w ten sposób:

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class MathTest {
    Math math;
    @Before
    public void setUp() throws Exception {
        math = new Math(7, 10);
    }
    @Test
    public void testAdd() {
        Assert.assertEquals(17, math.add());
    }
}

9- Napisz, kliknij swoją klasę testową w eksploratorze pakietów i kliknij Uruchom jako -> Test JUnit.

Uruchom test JUnit

10- To jest wynik testu.

Wynik testu

IntelliJ: Zwróć uwagę, że do zrzutów ekranu użyłem społeczności IntelliJ IDEA 2020.1. Przed wykonaniem tych czynności musisz również skonfigurować środowisko JRE. Używam JDK 11.0.4.

1- Kliknij prawym przyciskiem myszy główny folder projektu -> nowy -> katalog. Powinieneś nazwać to „testem”. wprowadź opis obrazu tutaj 2- Kliknij prawym przyciskiem myszy folder testowy i utwórz odpowiedni pakiet. Proponuję stworzyć takie same nazwy opakowań, jak oryginalna klasa. Następnie kliknij prawym przyciskiem myszy katalog testowy -> zaznacz katalog jako -> źródło testowe root. wprowadź opis obrazu tutaj 3- W odpowiednim pakiecie w katalogu testowym musisz utworzyć klasę Java (proponuję użyć Test.java). wprowadź opis obrazu tutaj 4- W utworzonej klasie wpisz „@Test”. Następnie spośród opcji, które daje IntelliJ, wybierz Dodaj „JUnitx” do ścieżki klas. 5- Napisz swoją metodę testową w klasie testowej. Podpis metody wygląda następująco:wprowadź opis obrazu tutaj wprowadź opis obrazu tutaj

@Test
public void test<name of original method>(){
...
}

Możesz zrobić swoje asercje jak poniżej:

Assertions.assertTrue(f.flipEquiv(node1_1, node2_1));

Oto import, który dodałem:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

wprowadź opis obrazu tutaj

Oto test, który napisałem: wprowadź opis obrazu tutaj

Możesz sprawdzić swoje metody, jak poniżej:

Assertions.assertEquals(<Expected>,<actual>);
Assertions.assertTrue(<actual>);
...

Aby uruchomić testy jednostkowe, kliknij prawym przyciskiem myszy test i kliknij Uruchom. wprowadź opis obrazu tutaj

Jeśli twój test przejdzie pomyślnie, wynik będzie taki jak poniżej: wprowadź opis obrazu tutaj

Mam nadzieję, że to pomoże. Możesz zobaczyć strukturę projektu w GitHub https://github.com/m-vahidalizadeh/problem_solving_project .


12
Uwielbiam twoją odpowiedź, to najlepsze „jak to zrobić”!
alisa

4
Cieszę się, że moja odpowiedź była pomocna. Dziękuję za Twój komentarz.
Mohammad

1
Tak powinny wyglądać samouczki; czysty, zwięzły, pełny przykład. Bardzo dobrze.
Jack Of Blades

1
Bardzo dziękuję Jack. Cieszę się, że okazało się to pomocne.
Mohammad,

18

Jest to bardzo ogólne pytanie, na które można odpowiedzieć na wiele sposobów.

Jeśli chcesz używać JUnit do tworzenia testów, musisz utworzyć swoją klasę testcase, a następnie utworzyć indywidualne metody testowe, które testują określoną funkcjonalność Twojej klasy / modułu w ramach testów (pojedyncze klasy przypadków testowych są zwykle powiązane z jedną klasą „produkcyjną”, która jest testowany) i wewnątrz tych metod wykonuj różne operacje i porównuj wyniki z tym, co byłoby poprawne. Szczególnie ważne jest, aby spróbować objąć jak najwięcej przypadków narożnych.

W swoim konkretnym przykładzie możesz na przykład przetestować następujące elementy:

  1. Prosty dodatek między dwiema liczbami dodatnimi. Dodaj je, a następnie sprawdź, czy wynik jest taki, jakiego oczekujesz.
  2. Dodanie między liczbą dodatnią a ujemną (która zwraca wynik ze znakiem pierwszego argumentu).
  3. Dodatek między liczbą dodatnią a ujemną (która zwraca wynik ze znakiem drugiego argumentu).
  4. Dodatek między dwiema liczbami ujemnymi.
  5. Dodatek powodujący przepełnienie.

Aby zweryfikować wyniki, możesz użyć różnych metod assertXXX z klasy org.junit.Assert (dla wygody możesz wykonać „import static org.junit.Assert. *”). Te metody sprawdzają określony warunek i kończą się niepowodzeniem, jeśli nie sprawdzają poprawności (opcjonalnie z określonym komunikatem).

Przykładowa klasa testcase w Twoim przypadku (bez zdefiniowanej zawartości metod):

import static org.junit.Assert.*;

public class AdditionTests {
    @Test
    public void testSimpleAddition() { ... }


    @Test
    public void testPositiveNegativeAddition() { ... }


    @Test
    public void testNegativePositiveAddition() { ... }


    @Test
    public void testNegativeAddition() { ... }


    @Test
    public void testOverflow() { ... }
}

Jeśli nie jesteś przyzwyczajony do pisania testów jednostkowych, ale zamiast tego testujesz swój kod pisząc testy ad-hoc, które następnie sprawdzasz "wizualnie" (na przykład piszesz prostą główną metodę, która akceptuje argumenty wprowadzone przy użyciu klawiatury i następnie wypisuje wyniki - a następnie kontynuujesz wprowadzanie wartości i sprawdzanie siebie, czy wyniki są poprawne), możesz zacząć od napisania takich testów w powyższym formacie i walidacji wyników za pomocą poprawnej metody assertXXX zamiast robić to ręcznie. W ten sposób możesz ponownie uruchomić test znacznie łatwiej niż gdybyś musiał wykonać testy ręczne.


8

Jak wspomniano @CoolBeans, spójrz na jUnit . Oto krótki samouczek, który pomoże Ci rozpocząć pracę z jUnit 4.x

Na koniec, jeśli naprawdę chcesz dowiedzieć się więcej o testowaniu i programowaniu opartym na testach (TDD), polecam zajrzeć do następującej książki autorstwa Kenta Becka: Test-Driven Development By Example .


6

Inne odpowiedzi pokazały, jak używać JUnit do konfigurowania klas testowych. JUnit to nie jedyna platforma testowa Java. Koncentrując się na technicznych szczegółach korzystania z frameworka, jednak odwraca uwagę od najważniejszych koncepcji, które powinny kierować Twoimi działaniami, więc o nich opowiem.

  • Testowanie (wszelkiego rodzaju rzeczy) porównuje rzeczywiste zachowanie czegoś (testowany system, SUT) z jego oczekiwanym zachowaniem.

  • Testowanie automatyczne można przeprowadzić za pomocą programu komputerowego. Ponieważ porównania dokonuje nieelastyczny i nieinteligentny program komputerowy, oczekiwane zachowanie musi być dokładnie i jednoznacznie znane.

  • To, czego oczekuje się od programu lub części programu (klasy lub metody), to jego specyfikacja . Dlatego testowanie oprogramowania wymaga posiadania specyfikacji dla SUT. Może to być wyraźny opis lub niejawna specyfikacja w Twojej głowie tego, czego się spodziewasz.

  • Dlatego zautomatyzowane testowanie jednostkowe wymaga precyzyjnej i jednoznacznej specyfikacji testowanej klasy lub metody.

  • Ale potrzebowałeś tej specyfikacji, kiedy zaczynałeś pisać ten kod. Tak więc część tego, o co chodzi w testowaniu, zaczyna się tak naprawdę, zanim napiszesz choćby jedną linijkę testu SUT. Technika testowania Test Driven Development (TDD) doprowadza ten pomysł do skrajności i polega na utworzeniu kodu testów jednostkowych przed napisaniem kodu, który ma być testowany.

  • Struktury testów jednostkowych testują SUT przy użyciu asercji . Asercja to wyrażenie logiczne (wyrażenie z booleantypem wyniku; predykat ), które musi być, truejeśli SUT zachowuje się poprawnie. Specyfikacja musi zatem zostać wyrażona (lub ponownie wyrażona) jako stwierdzenia.

  • Użyteczną techniką wyrażania specyfikacji jako asercji jest programowanie na podstawie kontraktu . Te specyfikacje dotyczą warunków końcowych . Warunek końcowy to stwierdzenie o publicznie widocznym stanie SUT po powrocie z metody lub konstruktora. Niektóre metody mają warunki końcowe, które są niezmiennymi , czyli predykatami, które są prawdziwe przed i po wykonaniu metody. Klasa może być również powiedział, że niezmienniki, które są postconditions każdego konstruktora i metody klasy, a więc powinny zawsze być prawdziwe. Warunki końcowe (i niezmienniki) są wyrażone tylko w postaci widocznego stanu reklamy: publici protectedpól, wartości zwróconych przezpublici protectedmetody (takie jak pobierające) oraz publicznie widoczny stan obiektów przekazanych (przez odwołanie) do metod.


Wielu początkujących zadaje tutaj pytania z pytaniem, w jaki sposób mogą przetestować jakiś kod, prezentując kod, ale bez podawania specyfikacji tego kodu. Jak pokazuje ta dyskusja, nikt nie jest w stanie udzielić dobrej odpowiedzi na takie pytanie, ponieważ w najlepszym przypadku potencjalni respondenci muszą odgadnąć specyfikację i mogą to zrobić niepoprawnie. Pytający w rachubę widocznie nie rozumie znaczenie specyfikacji, a zatem jest nowicjuszem, który musi zrozumieć podstawy Opisałem tutaj przed próbuje napisać kod testowy.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.