Come scrivere un test unitario?


135

Ho una classe Java. Come posso testarlo ?


Nel mio caso, ho classe fa una somma binaria. Prende due byte[]array, li somma e restituisce un nuovo array binario.


7
È possibile utilizzare uno strumento come jUnit e scrivere casi di test (metodi di test) per la propria classe java. Quindi invoca i test jUnit come parte del processo di generazione (ant / maven). L'uso di jUnit non è affatto difficile, la parte difficile è trovare quanti più scenari di test puoi pensare in modo da poter catturare i bug presto e spesso.
CoolBeans,

Risposte:


133
  1. Definire l'output previsto e desiderato per un caso normale, con input corretto.

  2. A questo punto, implementa il test dichiarando una classe, assegnagli un nome (di solito qualcosa come TestAddingModule) e aggiungi il metodo testAdd (cioè come quello sotto):

    • Scrivi un metodo e sopra aggiungi l'annotazione @Test.
    • Nel metodo, esegui la somma binaria e assertEquals(expectedVal,calculatedVal).
    • Prova il tuo metodo eseguendolo (in Eclipse, fai clic con il pulsante destro del mouse, seleziona Esegui come → Test JUnit).

      //for normal addition 
      @Test
      public void testAdd1Plus1() 
      {
          int x  = 1 ; int y = 1;
          assertEquals(2, myClass.add(x,y));
      }
  3. Aggiungi altri casi come desiderato.

    • Verifica che la somma binaria non generi un'eccezione imprevista in caso di overflow di numeri interi.
    • Verifica che il tuo metodo gestisca correttamente gli input Null (esempio sotto).

      //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. è richiesta la notazione @Test? 2. perché non testare l'input null con with assertNotNull? 3. dove vengono catturati i risultati dei test unitari? come vengono indicati i risultati per l'utente?
user137717,

10
Sì, @Testè richiesta la notazione. Questo viene fatto per segnalare al corridore di unit test che questo metodo rappresenta un unit test e deve essere eseguito. I metodi non annotati non @Testvengono eseguiti dal test runner.
Ali Shah Ahmed,

per la seconda prova - non si dovrebbe aggiungere un nulla ysolo darvi y?
Aggiunta il

Grazie! Voglio sapere perché non è necessario aggiungere statical modificatore del metodo di prova.
Liang Zhang,

104

Fornisco questo post sia per IntelliJ che per Eclipse .

Eclisse:

Per effettuare unit test per il tuo progetto, segui questi passaggi (sto usando Eclipse per scrivere questo test):

1- Fare clic su Nuovo -> Progetto Java.

Crea progetto

2- Scrivi il nome del tuo progetto e fai clic su Fine.

Crea progetto

3- Fare clic con il tasto destro sul progetto. Quindi, fai clic su Nuovo -> Classe.

Crea classe

4- Scrivi il nome della tua classe e fai clic su Fine.

Crea classe

Quindi, completa la classe in questo modo:

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

5- Fare clic su File -> Nuovo -> JUnit Test Case.

Crea JUnite Test

6- Controllare setUp () e fare clic su Fine. SetUp () sarà il luogo in cui si inizializza il test.

Controlla SetUp ()

7- Fare clic su OK.

Aggiungi JUnit

8- Qui, aggiungo semplicemente 7 e 10. Quindi, mi aspetto che la risposta sia 17. Completa la tua classe di test in questo modo:

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- Scrivi fare clic sulla classe di test in Esplora pacchetti e fare clic su Esegui come -> Test JUnit.

Esegui JUnit Test

10- Questo è il risultato del test.

Risultato del test

IntelliJ: Nota che ho usato IntelliJ IDEA community 2020.1 per gli screenshot. Inoltre, devi configurare il tuo jre prima di questi passaggi. Sto usando JDK 11.0.4.

1- Fare clic con il tasto destro del mouse sulla cartella principale del progetto-> nuova -> directory. Dovresti chiamare questo "test". inserisci qui la descrizione dell'immagine 2- Fare clic con il tasto destro sulla cartella test e creare il pacchetto corretto. Suggerisco di creare gli stessi nomi di packaging della classe originale. Quindi, fai clic con il pulsante destro del mouse sulla directory di test -> contrassegna directory come -> radice delle origini di test. inserisci qui la descrizione dell'immagine 3- Nel pacchetto giusto nella directory di test, è necessario creare una classe Java (suggerisco di usare Test.java). inserisci qui la descrizione dell'immagine 4- Nella classe creata, digitare "@Test". Quindi, tra le opzioni che ti offre IntelliJ, seleziona Aggiungi 'JUnitx' al percorso di classe. inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine 5- Scrivi il tuo metodo di prova nella tua classe di prova. La firma del metodo è simile a:

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

Puoi fare le tue affermazioni come di seguito:

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

Queste sono le importazioni che ho aggiunto:

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

inserisci qui la descrizione dell'immagine

Questo è il test che ho scritto: inserisci qui la descrizione dell'immagine

Puoi controllare i tuoi metodi come di seguito:

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

Per eseguire i test unitari, fare clic con il tasto destro del mouse sul test e fare clic su Esegui. inserisci qui la descrizione dell'immagine

Se il test ha esito positivo, il risultato sarà simile al seguente: inserisci qui la descrizione dell'immagine

Spero possa essere d'aiuto. Puoi vedere la struttura del progetto in GitHub https://github.com/m-vahidalizadeh/problem_solving_project .


12
Adoro la tua risposta, è il miglior "how-to"!
Alisa,

4
Sono contento che la mia risposta sia stata utile. Grazie per il tuo commento.
Mohammad,

1
Ecco come dovrebbero apparire i tutorial; esempio pulito, conciso, completo. Molto bene.
Jack Of Blades

1
Grazie mille Jack. Sono contento che tu l'abbia trovato utile.
Mohammad,

18

Questa è una domanda molto generica e ci sono molti modi per rispondere.

Se si desidera utilizzare JUnit per creare i test, è necessario creare la classe di testcase, quindi creare singoli metodi di test che testano funzionalità specifiche della propria classe / modulo durante i test (le singole classi di testcase sono generalmente associate a una singola classe di "produzione" che è in fase di test) e all'interno di questi metodi eseguire varie operazioni e confrontare i risultati con ciò che sarebbe corretto. È particolarmente importante provare a coprire il maggior numero possibile di custodie angolari.

Nel tuo esempio specifico, potresti ad esempio provare quanto segue:

  1. Una semplice aggiunta tra due numeri positivi. Aggiungili, quindi verifica che il risultato sia quello che ti aspetteresti.
  2. Un'aggiunta tra un numero positivo e uno negativo (che restituisce un risultato con il segno del primo argomento).
  3. Un'aggiunta tra un numero positivo e uno negativo (che restituisce un risultato con il segno del secondo argomento).
  4. Un'aggiunta tra due numeri negativi.
  5. Un'aggiunta che provoca un overflow.

Per verificare i risultati, è possibile utilizzare vari metodi assertXXX dalla classe org.junit.Assert (per comodità, è possibile eseguire 'import static org.junit.Assert. *'). Questi metodi verificano una condizione particolare e falliscono il test se non viene convalidato (con un messaggio specifico, facoltativamente).

Esempio di classe testcase nel tuo caso (senza i contenuti dei metodi definiti):

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() { ... }
}

Se non si è abituati a scrivere unit test ma si verifica invece il proprio codice scrivendo test ad hoc che si convalidano "visivamente" (ad esempio, si scrive un metodo principale semplice che accetta argomenti immessi utilizzando la tastiera e quindi stampa i risultati - e quindi continui a inserire valori e a convalidare te stesso se i risultati sono corretti), quindi puoi iniziare scrivendo tali test nel formato sopra e convalidando i risultati con il metodo assertXXX corretto invece di farlo manualmente. In questo modo, è possibile rieseguire il test molto più facilmente se fosse necessario eseguire test manuali.


8

Come menzionato @CoolBeans, dai un'occhiata a jUnit . Ecco un breve tutorial per iniziare anche con jUnit 4.x

Infine, se vuoi davvero saperne di più sui test e sullo sviluppo guidato dai test (TDD), ti consiglio di dare un'occhiata al seguente libro di Kent Beck: Test-Driven Development By Example .


6

Altre risposte ti hanno mostrato come utilizzare JUnit per impostare le classi di test. JUnit non è l'unico framework di test Java. Concentrarsi sui dettagli tecnici dell'uso di un framework toglie comunque i concetti più importanti che dovrebbero guidare le tue azioni, quindi ne parlerò.

  • Il testing (di ogni genere di cose) confronta il comportamento reale di qualcosa (The System Under Test, SUT) con il comportamento atteso .

  • I test automatizzati possono essere eseguiti utilizzando un programma per computer. Poiché tale confronto viene eseguito da un programma informatico poco flessibile e non intelligente, il comportamento previsto deve essere noto in modo preciso e inequivocabile.

  • Ciò che un programma o parte di un programma (una classe o un metodo) dovrebbe fare è la sua specifica . Per testare il software è quindi necessario disporre di una specifica per SUT. Questa potrebbe essere una descrizione esplicita o una specifica implicita nella testa di ciò che è previsto.

  • Il test di unità automatizzato richiede quindi una specifica precisa e inequivocabile della classe o del metodo che si sta testando.

  • Ma avevi bisogno di quella specifica quando hai deciso di scrivere quel codice. Quindi parte di ciò che riguarda i test inizia effettivamente prima di scrivere anche una sola riga del SUT. La tecnica di test di Test Driven Development (TDD) porta questa idea all'estremo e ti consente di creare il codice di test dell'unità prima di scrivere il codice da testare.

  • I framework di unit test testano il tuo SUT usando asserzioni . Un'asserzione è un'espressione logica (un'espressione con un booleantipo di risultato; un predicato ) che deve essere truese il SUT si sta comportando correttamente. Le specifiche devono pertanto essere espresse (o ri-espresse) come asserzioni.

  • Una tecnica utile per esprimere una specifica come asserzioni è la programmazione per contratto . Queste specifiche sono in termini di postcondizioni . Una postcondizione è un'affermazione sullo stato pubblicamente visibile del SUT dopo il ritorno da un metodo o un costruttore. Alcuni metodi hanno postcondizioni che sono invarianti , che sono predicati che sono veri prima e dopo l'esecuzione del metodo. Si può anche dire che una classe ha degli invarianti, che sono postcondizioni di ogni costruttore e metodo della classe, e quindi dovrebbero essere sempre veri. Le postcondizioni (e gli invarianti) sono espresse solo in termini di stato visibile della pubblicità: publice eprotected campi, i valori restituiti da restituiti dapublicprotected metodi (come getter) e lo stato visibile pubblicamente degli oggetti passati (per riferimento) ai metodi.


Molti principianti pubblicano qui delle domande che chiedono come possono testare un po 'di codice, presentando il codice ma senza indicare le specifiche per quel codice. Come dimostra questa discussione, è impossibile per chiunque dare una buona risposta a tale domanda, perché nella migliore delle ipotesi i potenziali rispondenti devono indovinare le specifiche e potrebbero farlo in modo errato. Il richiedente della domanda evidentemente non capisce l'importanza di una specifica, ed è quindi un principiante che deve comprendere i fondamenti che ho descritto qui prima di provare a scrivere un codice di prova.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.