Поиск…


замечания

параметр контекст подробности
@BeforeClass статический Выполняется, когда класс сначала создается
@До Пример Выполнено перед каждым тестом в классе
@Тестовое задание Пример Должен быть объявлен каждый метод тестирования
@После Пример Выполняется после каждого теста в классе
@После школы статический Выполнено до уничтожения класса

Пример Формат тестового класса

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

Единичное тестирование с использованием JUnit

Здесь у нас есть класс Counter с методами countNumbers() и 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.*");
    }
}

Для тестирования этого класса мы можем использовать структуру Junit. Добавьте junit.jar в свой путь к проекту. Затем создайте класс Test case, как показано ниже:

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);
    }
}

В вашей среде IDE вы можете запустить этот класс как «тестовый тест Junit» и посмотреть результат в графическом интерфейсе. В командной строке вы можете скомпилировать и запустить тестовый пример, как показано ниже:

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

Результат успешного тестового прогона должен выглядеть так:

JUnit version 4.9b2
..
Time: 0.019

OK (2 tests)

В случае отказа теста он будет больше похож:

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

арматура

Из Википедии :

Прибор для тестирования - это то, что используется для постоянного тестирования какого-либо элемента, устройства или части программного обеспечения.

Он также может повысить читаемость тестов путем извлечения общего кода инициализации / окончательной обработки из самих методов тестирования.

Если обычная инициализация может выполняться один раз вместо каждого теста, это также может сократить время, затрачиваемое на запуск тестов.

Пример, приведенный ниже, изобретен, чтобы показать основные параметры, предоставленные JUnit. Предположим, что класс Foo который дорого инициализируется:

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

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

В еще одном классе Bar есть ссылка на Foo :

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

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

В приведенных ниже тестах ожидаются исходный контекст списка, содержащего один 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();
    }
}

В примере @BeforeClass аннотированный метод setupOnce() используется для создания Foo объекта, который является дорогим инициализацию. Важно, чтобы он не изменялся ни одним из тестов, иначе результат тестового прогона мог зависеть от порядка выполнения отдельных тестов. Идея состоит в том, что каждый тест независим и проверяет одну небольшую функцию.

Функция @Before setup() аннотированного метода setup() устанавливает тестовый контекст. Контекст может быть изменен во время выполнения теста, поэтому он должен быть инициализирован перед каждым тестом. Эквивалентный эффект может быть достигнут путем включения кода, содержащегося в этом методе, в начале каждого тестового метода.

@After аннотированный метод tearDown() очищает ресурсы в контексте теста. Он вызывается после каждого вызова вызова и как таковой часто используется для освобождения ресурсов, выделенных в @Before annotated.

@AfterClass аннотированный метод tearDownOnce() очищает ресурсы , как только все тесты выполняются. Такие методы обычно используются для освобождения ресурсов, выделенных во время инициализации или в аннотированном методе @BeforeClass . Тем не менее, вероятно, лучше избегать внешних ресурсов в модульных тестах, чтобы тесты не зависели ни от чего за пределами тестового класса.

Единичное тестирование с использованием теорий

Из JavaDoc

Бегун Theories позволяет протестировать определенную функциональность против подмножества бесконечного набора точек данных.

Запуск теории

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
    }
}

Методы, аннотированные с помощью @Theory будут читаться как теории на языке Theories.

Аннотация @DataPoint

@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
    }
}

Каждое поле, аннотированное с помощью @DataPoint будет использоваться в качестве параметра метода данного типа в теориях. В примере выше theoryMethod будет работать два раза со следующими параметрами: ["str1", 2] , ["str2", 2]

@DataPoints аннотация @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
    }
}

Каждый элемент массива, аннотированный аннотацией @DataPoints будет использоваться в качестве параметра метода данного типа в теориях. В примере выше theoryMethod будет работать четыре раза со следующими параметрами: ["str1", 1], ["str2", 1], ["str1", 2], ["str2", 2]

Измерение производительности

Если вам нужно проверить, требуется ли слишком много времени для выполнения метода тестирования, вы можете сделать это, указав ожидаемое время выполнения, используя свойство timeout аннотации @Test. Если выполнение теста занимает больше времени, чем миллисекунды, это приводит к сбою тестового метода.

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());
    }

}

В большинстве случаев без testString JVM testString не удастся. Но testStringBuffer и testStringBuilder должны успешно пройти этот тест.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow