Академический Документы
Профессиональный Документы
Культура Документы
оценка покрытия
Разрыв зависимостей
Изолированный тест не зависит от других тестов или окружения. Он работает сам по себе.
Пример. Есть два теста. Первый проверяет, что в базу данных добавилось значение. Второй —
что это значение выводится на экран.
Второй тест не изолирован, потому что зависит от первого. Если первый тест упадёт, значение
не появится в базе данных. Второй не сможет работать.
по одному;
в наборе тестов;
в случайном порядке.
Тест падает, если запустить только его, но вместе с другими тестами проходит. Как в
примере со строками.
Запускать тесты можно только в определённом порядке. Например, первый тест вводит
данные в поле ввода, а второй с ним работает. Если сначала запустить второй тест, он не
найдёт данные и упадёт.
Атомарность
Хороший тест нельзя декомпозировать на несколько маленьких тестов.
Нужно проверить, что товар добавляется в корзину. Для этого не стоит проходить весь путь от
стартовой страницы: можно сразу перейти к странице выбора товара. Тестировщик отсекает всё
ненужное и проверяет только конкретную функциональность.
Изоляция и атомарность
Нужно проверить, что будет, если внешний ресурс не сработает. Чаще всего не получится
вызвать настоящий сбой во вешней системе, но с помощью Mockito его можно сымитировать.
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import org.junit.Assert;
import org.junit.Test;
import java.io.IOException;
@Test
public void test() throws IOException {
ServiceClass serviceClass = new ServiceClass();
Server server = new Server();
int responseCode = serviceClass.sendGet("http://www.example.com/junk");
System.out.println("Код ответа от сервера: " + responseCode);
String status = server.checkServer(responseCode);
Assert.assertEquals("Сервер доступен", status);
}
Что-то пошло не так. Метод sendGet() вернул ошибку 404 — Not Found. Тест не прошёл.
Это означает, что программа не нашла сервер. Так может получиться, если его только
разрабатывают, а тестировать нужно уже сейчас. Или если проблемы с сетью.
Чтобы протестировать код, нужно разорвать зависимость с внешним ресурсом. Поможет
библиотека Mockito: она сымитирует работу сервера. Понадобится создать мок и вернуть ответ:
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.IOException;
@RunWith(MockitoJUnitRunner.class)
public class Praktikum {
@Test
public void test() throws IOException {
Server server = new Server();
/* Вернётся код 200,
ты имитируешь корректную работу нужного ресурса */
Mockito.when(serviceClass.sendGet(Mockito.anyString())).thenReturn(200);
int responseCode = serviceClass.sendGet("http://www.example.com/junk");
System.out.println("Код ответа от сервера: " + responseCode);
String status = server.checkServer(responseCode);
Assert.assertEquals("Сервер доступен", status);
}
}
Оценка покрытия
Покрытие кода (code coverage) говорит, какой процент программы выполняется во время тестов.
Можно смотреть на процент покрытых строк кода, условных операторов и методов.
import org.junit.Assert;
import org.junit.Test;
@Test
public void shouldCalculateSalaryWhenUnderLimit() {
SalaryService salaryService = new SalaryService();
int actual = salaryService.calculateSalary(50_000);
int expected = 2_500;
Assert.assertEquals(expected, actual);
}
}
А вот строка salary = salaryLimit; выполняется не всегда. Если зарплата не превышает лимит,
код внутри if не выполняется. Эта строка не покрыта.
Подключить плагин. Нужно добавить секцию build в pom.xml . В неё и записываются плагины —
с помощью тега plugin :
<groupId>ru.yandex.praktikum</groupId>
<artifactId>coverage</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<!--здесь настройки-->
</properties>
<dependencies>
<!--здесь зависимости-->
</dependencies>
</project>
Затем нужно указать groupId , artifactId , version — так же, как для dependency :
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
</plugin>
</plugins>
</build>
Цель плагина — это задача, которую он выполняет. Например, цель mvn compiler:compile —
скомпилировать код.
Первая цель — prepare-agent . Она нужна для корректной работы плагина. Вторая — report : она
генерирует отчёт.
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<executions>
<execution>
<!--id выбираешь самостоятельно-->
<id>prepare-agent</id>
<!--в какой фазе maven будет выполняться цель-->
<phase>initialize</phase>
<!--цель jacoco, которую нужно выполнить-->
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
Посмотреть отчёт. Самый простой способ посмотреть отчёт — открыть его в браузере. Выполни
команду mvn verify : для этого в IDEA нажми Ctrl дважды. Откроется окно: напиши в нём эту
команду.
Найди в папке target/site/jacoco/ файл index.html, нажми на него правой кнопкой мыши и выбери
Open In — Browser — твой браузер.
В отчёте отображается процент покрытых строк кода — столбец Missed Instructions. В примере
покрыто 90% строк.
Процент покрытых ветвей — столбец Missed Branches. В примере покрыто 50% ветвей.
Чтобы увидеть подробнее, какие именно строки и ветви не покрыты, зайди в пакет, класс и метод
внутри него:
Отчёт можно посмотреть и прямо в IDEA: для этого открой Run — Show Coverage Data. Нажми +
(Add) и выбери файл jacoco.exec.
import org.junit.Assert;
import org.junit.Test;
@Test
public void testSalaryUnderLimit() {
SalaryService salaryService = new SalaryService();
int actual = salaryService.calculateSalary(50_000);
int expected = 2_500;
Assert.assertEquals(expected, actual);
}
@Test
public void testSalaryOverLimit() {
SalaryService salaryService = new SalaryService();
int actual = salaryService.calculateSalary(1_000_000);
Assert.assertEquals(expected, actual);
}
}
Тонкости
Важно помнить: покрытие 100% не означает, что протестированы все возможные сценарии.
Инструменты оценки покрытия не учитывают, какие тестовые данные ты используешь.
Представь, что кто-то по ошибке изменил код метода, который вычисляет зарплату. Условие if
В код закралась ошибка, а тесты всё ещё проходят и покрытие равно 100%. Кроме
количественного покрытия должно быть и качественное. Поэтому когда пишешь тесты и
подбираешь тестовые данные, важно использовать техники тест-дизайна.