Zoeken…


Opmerkingen

Parameter Context Details
@Voor klas Statisch Wordt uitgevoerd wanneer de klasse voor het eerst wordt gemaakt
@Voordat Voorbeeld Uitgevoerd vóór elke test in de klas
@Test Voorbeeld Moet worden verklaard elke te testen methode
@Na Voorbeeld Uitgevoerd na elke test in de klas
@Na de les Statisch Uitgevoerd vóór vernietiging van de klas

Voorbeeld van testklasse-indeling

public class TestFeatureA {

    @BeforeClass
    public static void setupClass() {}
    
    @Before
    public void setupTest() {}
    
    @Test
    public void testA() {}
    
    @Test
    public void testB() {}
    
    @After
    public void tearDownTest() {}
    
    @AfterClass
    public static void tearDownClass() {}
    
    }
}

Unit testen met JUnit

Hier hebben we een klasse Counter met methoden countNumbers() en hasNumbers() .

public class Counter {

    /* To count the numbers in the input */
    public static int countNumbers(String input) {
        int count = 0;
        for (char letter : input.toCharArray()) {
            if (Character.isDigit(letter))
                count++;
        }
        return count;
    }

    /* To check whether the input has number*/
    public static boolean hasNumber(String input) {
        return input.matches(".*\\d.*");
    }
}

Om deze klasse te testen, kunnen we Junit-framework gebruiken. Voeg junit.jar aan uw projectklassepad. Maak vervolgens de klasse Testcase zoals hieronder:

import org.junit.Assert; // imports from the junit.jar
import org.junit.Test;

public class CounterTest {

    @Test // Test annotation makes this method as a test case
    public void countNumbersTest() {
        int expectedCount = 3;
        int actualCount = Counter.countNumbers("Hi 123");
        Assert.assertEquals(expectedCount, actualCount); //compares expected and actual value
    }

    @Test
    public void hasNumberTest() {
        boolean expectedValue = false;
        boolean actualValue = Counter.hasNumber("Hi there!");
        Assert.assertEquals(expectedValue, actualValue);
    }
}

In uw IDE kunt u deze klasse uitvoeren als "Junit-testcase" en de uitvoer in de GUI bekijken. In de opdrachtprompt kunt u de testcase compileren en uitvoeren zoals hieronder:

\> javac -cp ,;junit.jar CounterTest.java
\> java  -cp .;junit.jar org.junit.runner.JUnitCore CounterTest

De output van een succesvolle testrun moet er ongeveer hetzelfde uitzien als:

JUnit version 4.9b2
..
Time: 0.019

OK (2 tests)

In het geval van een testfout zou het er meer uitzien als:

Time: 0.024
There was 1 failure:
1) CountNumbersTest(CounterTest)
java.lang.AssertionError: expected:<30> but was:<3>
... // truncated output
FAILURES!!!
Tests run: 2,  Failures: 1

Wedstrijden

Van Wikipedia :

Een testopstelling is iets dat wordt gebruikt om een bepaald item, apparaat of software consequent te testen.

Het kan ook de leesbaarheid van tests verbeteren door de algemene initialisatie- / finalisatiecode uit de testmethoden zelf te extraheren.

Waar gemeenschappelijke initialisatie eenmaal kan worden uitgevoerd in plaats van vóór elke test, kan dit ook de hoeveelheid tijd verminderen die nodig is om tests uit te voeren.

In het onderstaande voorbeeld worden de belangrijkste opties van JUnit weergegeven. Ga uit van een klasse Foo die duur is om te initialiseren:

public class Foo {
    public Foo() {
        // expensive initialization
    }

    public void cleanUp() {
        // cleans up resources
    }
}

Een andere klasse Bar heeft een verwijzing naar Foo :

public class Bar {
    private Foo foo;
    
    public Bar(Foo foo) {
        this.foo = foo;
    }

    public void cleanUp() {
        // cleans up resources
    }
}

De onderstaande tests verwachten een eerste context van een lijst met één Bar .

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class FixturesTest {
    
    private static Foo referenceFoo;
    
    private List<Bar> testContext;
    
    @BeforeClass
    public static void setupOnce() {
        // Called once before any tests have run
        referenceFoo = new Foo();
    }

    @Before
    public void setup() {
        // Called before each test is run
        testContext = Arrays.asList(new Bar(referenceFoo));
    }
    
    @Test
    public void testSingle() {
        assertEquals("Wrong test context size", 1, testContext.size());
        Bar baz = testContext.get(0);
        assertEquals(referenceFoo, baz.getFoo());
    }
    
    @Test
    public void testMultiple() {
        testContext.add(new Bar(referenceFoo));
        assertEquals("Wrong test context size", 2, testContext.size());
        for (Bar baz : testContext) {
            assertEquals(referenceFoo, baz.getFoo());
        }
    }
    
    @After
    public void tearDown() {
        // Called after each test is run
        for (Bar baz : testContext) {
            baz.cleanUp();
        }
    }
    
    @AfterClass
    public void tearDownOnce() {
        // Called once after all tests have run
        referenceFoo.cleanUp();
    }
}

In het voorbeeld wordt de @BeforeClass geannoteerde methode setupOnce() gebruikt om het Foo object te maken, wat duur is om te initialiseren. Het is belangrijk dat het door geen van de tests wordt gewijzigd, anders kan de uitkomst van de testrun afhankelijk zijn van de volgorde van uitvoering van de afzonderlijke tests. Het idee is dat elke test onafhankelijk is en één kleine functie test.

Met de methode @Before annotated setup() wordt de testcontext ingesteld. De context kan tijdens de uitvoering van de test worden gewijzigd en moet daarom vóór elke test worden geïnitialiseerd. Het equivalente effect kan worden bereikt door de code in deze methode op te nemen aan het begin van elke testmethode.

De @After geannoteerde methode tearDown() ruimt middelen binnen de test context. Het wordt genoemd na elke testoproep en wordt als zodanig vaak gebruikt om middelen vrij te maken die zijn toegewezen in een geannoteerde methode @Before .

De @AfterClass geannoteerde methode tearDownOnce() ruimt middelen, zodra alle tests zijn uitgevoerd. Dergelijke methoden worden meestal gebruikt om middelen vrij te maken die zijn toegewezen tijdens de initialisatie of in een geannoteerde @BeforeClass methode. Dat gezegd hebbende, is het waarschijnlijk het beste om externe bronnen in unit-tests te vermijden, zodat de tests niet afhankelijk zijn van iets buiten de testklasse.

Unit testen met behulp van theorieën

Van JavaDoc

De Theories runner maakt het mogelijk om een bepaalde functionaliteit te testen tegen een subset van een oneindige set datapunten.

Theorieën uitvoeren

import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

@RunWith(Theories.class)
public class FixturesTest {

    @Theory
    public void theory(){
        //...some asserts
    }
}

Methoden geannoteerd met @Theory worden gelezen als theorieën door Theories runner.

@DataPoint-annotatie

@RunWith(Theories.class)
public class FixturesTest {

    @DataPoint
    public static String dataPoint1 = "str1";
    @DataPoint
    public static String dataPoint2 = "str2";
    @DataPoint
    public static int intDataPoint = 2;

    @Theory
    public void theoryMethod(String dataPoint, int intData){
        //...some asserts
    }
}

Elk veld geannoteerd met @DataPoint zal worden gebruikt als een parameterparameter van een bepaald type in de theorieën. In het bovenstaande voorbeeld theoryMethod zal theoryMethod twee keer worden uitgevoerd met de volgende parameters: ["str1", 2] , ["str2", 2]

@DataPoints annotatie @RunWith (Theories.class) public class FixturesTest {

    @DataPoints
    public static String[] dataPoints = new String[]{"str1", "str2"};
    @DataPoints
    public static int[] dataPoints = new int[]{1, 2};

    @Theory
    public void theoryMethod(String dataPoint, ){
        //...some asserts
    }
}

Elk element van de array dat is geannoteerd met @DataPoints annotatie, wordt gebruikt als een parameterparameter van een bepaald type in de theorieën. In het bovenstaande voorbeeld theoryMethod zal theoryMethod vier keer worden uitgevoerd met de volgende parameters: ["str1", 1], ["str2", 1], ["str1", 2], ["str2", 2]

Prestatiemeting

Als u moet controleren of uw testmethode te lang duurt om uit te voeren, kunt u dat doen door uw verwachte uitvoeringstijd te vermelden met behulp van de timeout-eigenschap van @Test annotation. Als de testuitvoering langer duurt dan dat aantal milliseconden, zorgt dit ervoor dat een testmethode mislukt.

public class StringConcatenationTest {

    private static final int TIMES = 10_000;
    
    // timeout in milliseconds
    @Test(timeout = 20)
    public void testString(){

        String res = "";

        for (int i = 0; i < TIMES; i++) {
            res += i;
        }

        System.out.println(res.length());
    }

    @Test(timeout = 20)
    public void testStringBuilder(){

        StringBuilder res = new StringBuilder();

        for (int i = 0; i < TIMES; i++) {
            res.append(i);
        }

        System.out.println(res.length());
    }

    @Test(timeout = 20)
    public void testStringBuffer(){

        StringBuffer res = new StringBufferr();

        for (int i = 0; i < TIMES; i++) {
            res.append(i);
        }

        System.out.println(res.length());
    }

}

In de meeste gevallen zal de JVM- testString niet mislukken. Maar testStringBuffer en testStringBuilder moeten deze test met succes doorstaan.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow