Як написати одиничний тест?


135

У мене клас Java. Як я можу перевірити його?


У моєму випадку у мене клас робить двійкову суму. Він займає два byte[]масиви, підсумовує їх і повертає новий двійковий масив.


7
Ви можете використовувати такий інструмент, як jUnit, і писати тестові приклади (методи тестування) для свого класу java. Потім запускайте тести jUnit як частину процесу збирання (ant / maven). Використовувати jUnit зовсім не складно, складна частина придумує стільки тестових сценаріїв, які ви можете придумати, щоб ви могли ловити помилки рано та часто.
CoolBeans

Відповіді:


133
  1. Визначте очікуваний та бажаний вихід для нормального випадку, з правильним введенням.

  2. Тепер реалізуйте тест, оголосивши клас, назвіть йому що-небудь (як правило, щось на зразок TestAddingModule), і додайте до нього метод testAdd (тобто, як описаний нижче):

    • Напишіть метод, а над ним додайте анотацію @Test.
    • У методі запустіть свою двійкову суму і assertEquals(expectedVal,calculatedVal).
    • Перевірте свій метод, запустивши його (у програмі Eclipse клацніть правою кнопкою миші та виберіть Запустити як → JUnit test).

      //for normal addition 
      @Test
      public void testAdd1Plus1() 
      {
          int x  = 1 ; int y = 1;
          assertEquals(2, myClass.add(x,y));
      }
  3. Додайте інші випадки за бажанням.

    • Перевірте, що ваша двійкова сума не є несподіваним винятком, якщо є ціле переповнення.
    • Перевірте, чи ваш метод витончено обробляє Null input (приклад нижче).

      //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. чи потрібна нотація @Test? 2. чому б не перевірити нульовий ввід за допомогою assertNotNull? 3. куди фіксуються результати одиничних тестів? як результати показуються користувачеві?
користувач137717

10
Так, @Testнотація не потрібна. Це робиться для того, щоб повідомити пробігу тестового пристрою, що цей метод являє собою тест на одиницю і його слід виконати. Методи, які не зазначаються @Test, не виконуються тестовим бігуном.
Алі Шах Ахмед

для другого тесту - чи не слід додавати, nullщоб yпросто дати вам y?
Аджит

Дякую! Я хочу знати, чому не потрібно додавати staticдо модифікатора методу тестування.
Лян Чжан

104

Я надаю цю посаду як для IntelliJ, так і для Eclipse .

Затемнення:

Щоб зробити тестовий блок для вашого проекту, будь ласка, виконайте наступні кроки (я використовую Eclipse для того, щоб написати цей тест):

1- Клацніть на Створити -> Java Project.

Створити проект

2- Запишіть назву вашого проекту та натисніть кнопку «Завершити».

Створити проект

3- Клацніть правою кнопкою миші на вашому проекті. Потім натисніть кнопку Створити -> Клас.

Створити клас

4- Запишіть назву свого класу та натисніть на закінчити.

Створити клас

Потім закінчіть клас так:

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

5- Клацніть на Файл -> Створити -> Тест JUnit.

Створіть тест JUnite

6- Перевірте setUp () і натисніть кнопку "Завершити". SetUp () буде місцем ініціалізації вашого тесту.

Перевірте SetUp ()

7- Натисніть кнопку ОК.

Додати JUnit

8- Тут я просто додаю 7 і 10. Тож я очікую, що відповідь буде 17. Доповніть свій тестовий клас так:

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- Напишіть клацніть на своєму тестовому класі в Explorer Explorer і натисніть Виконати як -> JUnit Test.

Запустіть тест JUnit

10- Це результат тесту.

Результат тесту

IntelliJ: Зауважте, що для скріншотів я використав спільноту IntelliJ IDEA 2020.1. Також перед цим кроком потрібно налаштувати jre. Я використовую JDK 11.0.4.

1- Клацніть правою кнопкою миші головну папку вашого проекту-> new -> каталогу. Вам слід назвати це "тестом". введіть тут опис зображення 2- Клацніть правою кнопкою миші на тестовій папці та створіть належний пакет. Я пропоную створити ті ж назви упаковки, що і оригінальний клас. Потім клацніть правою кнопкою миші тестовий каталог -> позначити каталог як -> корінь тестових джерел. введіть тут опис зображення 3- У правому пакеті в тестовому каталозі вам потрібно створити клас Java (пропоную використовувати Test.java). введіть тут опис зображення 4- У створеному класі наберіть '@Test'. Потім серед опцій, які надає IntelliJ, виберіть Додати клас "JUnitx" на classpath. 5- Напишіть свій тестовий метод у свій тестовий клас. Підпис методу виглядає так:введіть тут опис зображення введіть тут опис зображення

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

Ви можете робити свої твердження, як показано нижче:

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

Це імпорт, який я додав:

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

введіть тут опис зображення

Це тест, який я написав: введіть тут опис зображення

Ви можете перевірити свої методи, як показано нижче:

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

Для запуску тестування пристрою клацніть правою кнопкою миші на тесті та натисніть кнопку Виконати. введіть тут опис зображення

Якщо ваш тест пройде, результат буде таким: введіть тут опис зображення

Я сподіваюся, що це допомагає. Ви можете побачити структуру проекту в GitHub https://github.com/m-vahidalizadeh/problem_solving_project .


12
Любіть свою відповідь, це найкраще "як"!
alisa

4
Я радий, що моя відповідь була корисною. Дякую за Ваш коментар
Мохаммед

1
Ось як мають виглядати підручники; чистий, лаконічний, повний приклад. Дуже добре.
Jack Of Blades

1
Дуже дякую Джеку. Я радий, що ти знайшов це корисним.
Мохаммед

18

Це дуже загальне питання, і є багато способів відповіді на нього.

Якщо ви хочете використовувати JUnit для створення тестів, вам потрібно створити свій клас тестових зразків, а потім створити індивідуальні методи тестування, які перевіряють конкретну функціональність вашого класу / модуля під час тестів (окремі класи тестових шаблонів зазвичай асоціюються з одним класом "виробництва", який тестується) і всередині цих методів виконують різні операції та порівнюють результати з тим, що було б правильним. Особливо важливо спробувати охопити якомога більше кутових справ.

У конкретному прикладі ви можете, наприклад, перевірити наступне:

  1. Просте додавання між двома додатними числами. Додайте їх, а потім перевірте, що результат - це те, що ви очікували.
  2. Доповнення між додатним і від’ємним числом (яке повертає результат зі знаком першого аргументу).
  3. Доповнення між додатним і від’ємним числом (яке повертає результат зі знаком другого аргументу).
  4. Додавання між двома від’ємними числами.
  5. Доповнення, що призводить до переповнення.

Для перевірки результатів можна скористатися різними методами assertXXX з класу org.junit.Assert (для зручності можна зробити "імпорт статичного org.junit.Assert. * '). Ці методи перевіряють певну умову і проходять тест, якщо він не підтверджується (з конкретним повідомленням, необов'язково).

Приклад класу тестів у вашому випадку (без визначеного вмісту методів):

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

Якщо ви не звикли писати одиничні тести, але замість цього випробуєте свій код, написавши спеціальні тести, які потім перевіряєте "візуально" (наприклад, ви пишете простий основний метод, який приймає аргументи, введені за допомогою клавіатури, а потім друкує результати - і тоді ви продовжуєте вводити значення та перевіряти себе, якщо результати правильні), тоді ви можете почати, написавши такі тести у форматі вище та перевірити результати правильним методом assrtXXX, а не робити це вручну. Таким чином, ви можете повторно запустити тест набагато простіше, ніж якщо вам доведеться робити ручні тести.


8

Як і @CoolBeans, згаданий, погляньте на jUnit . Ось короткий підручник для початку роботи з jUnit 4.x

Нарешті, якщо ви дійсно хочете дізнатися більше про тестування та тестово-орієнтовану розробку (TDD), рекомендую поглянути на наступну книгу Кента Бека: Тестова розробка за прикладом .


6

Інші відповіді показали, як використовувати JUnit для налаштування тестових класів. JUnit - не єдина тестова основа Java. Концентруючись на технічних деталях використання рамки, однак, це заважає найважливішим концепціям, які повинні керувати вашими діями, тому я поговорю про них.

  • Тестування (всілякі всілякі речі) порівнює фактичну поведінку чогось (Система під тестом, SUT) з її очікуваною поведінкою.

  • Автоматизоване тестування можна зробити за допомогою комп’ютерної програми. Оскільки це порівняння проводиться за допомогою негнучкої та непродуманої комп’ютерної програми, очікувана поведінка повинна бути точно та однозначно відома.

  • Очікується, яку програму або частину програми (клас чи метод) робити - це її специфікація . Тому для тестування програмного забезпечення потрібно мати специфікацію для SUT. Це може бути явний опис або неявна конкретизація в голові того, що очікується.

  • Тому автоматичне тестування блоку вимагає точної та однозначної специфікації класу чи методу, який ви випробовуєте.

  • Але вам потрібна була ця специфікація, коли ви вирішили написати цей код. Тому частина тестування насправді починається ще до того, як ви напишете навіть один рядок SUT. Техніка тестування Driven Driven Development (TDD) до кінця сприймає цю ідею, і чи ви створили код тестування одиниць перед тим, як написати код для тестування.

  • Рамки для тестування блоку перевіряють ваш SUT за допомогою тверджень . Твердження - це логічний вираз (вираз з booleanтипом результату; присудок ), який повинен бути, trueякщо SUT веде себе правильно. Отже, специфікація повинна бути виражена (або повторно виражена) як твердження.

  • Корисна методика висловлення специфікації як тверджень - це програмування за контрактом . Ці технічні характеристики відносяться до постумов . Пост-умова - це твердження про загальнодоступний стан SUT після повернення з методу чи конструктора. Деякі методи мають пост-умови, які є інваріантами , це предикати, які відповідають дійсності до та після виконання методу. Клас також можна сказати , що є інваріанти, які постумови кожного конструктора і методи класу, і , отже , повинна завжди бути правдою. Пост-умови (та інваріанти) виражаються лише в умовах видимості публічності: publicі protectedполя, значення, поверненіpublicі protectedметоди (наприклад, геттери), і загальнодоступний стан об'єктів, переданих (за посиланням) на методи.


Багато початківців тут задають питання, запитуючи, як вони можуть протестувати якийсь код, представляючи код, але не вказуючи специфікацію цього коду. Як це обговорення показує, що неможливо нікому , щоб дати хороший відповідь на таке питання, тому що в кращому випадку потенційних answereres повинні вгадати специфікації, і може зробити це неправильно. Аскер питання , очевидно , не розуміє важливості специфікації, і, таким чином , новачок , який повинен зрозуміти основи я описав тут , перш ніж намагатися писати який - то тестовий код.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.