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.