От “А” до “Веб-приложения” (Серия из 2 частей)
Ошибки – неизбежная, нежелательная часть программирования. Тестируя и кодируя в тандеме, вы можете устранить множество ошибок и быть более уверенными в своем коде.
Существуют различные стратегии и инструменты, которые вы можете использовать для тестирования веб-приложений, я разберу их для вас и протестирую приложение из моего предыдущего поста. Хотя я тестирую приложение Spring Boot, многое из того, что я обсуждаю, может быть применено к любому веб-приложению, написанному на Java.
- Что мы должны проверить?
- Модульные тесты
- Что такое единица измерения?
- Общительный или Одинокий?
- Интеграционные тесты
- Сколько тестов достаточно?
- Тестовые библиотеки, которые вы можете использовать
- Тестирование приложения
- Как писать тестовые примеры
- Модульный тест для пользователя
- Должен ли я тестировать POJOs
- Написание тестового класса
- Время выполнения пользовательского теста
- Модульный тест для пользовательского контроллера
- Тестовые примеры для пользовательского контроллера
- получить пользователей (счастливый путь)
- получить пользователей (несчастливый путь)
- Время выполнения для UserControllerTest
- Тестовые примеры для пользовательского контроллера
- Интеграционный тест для пользовательского контроллера
- Написание интеграционного теста с реальным сервером
- Тестовые примеры для пользовательского контроллера IT
- получить пользователей (счастливый путь)
- получить пользователей (несчастливый путь)
- Время выполнения для пользовательского контроллера
- Напишите набор тестов
- исходный код
- Заключительные Слова
- Рекомендации
Что мы должны проверить?
Основное внимание в этой статье уделяется написанию тестов в качестве разработчика.
Как разработчики, мы пишем тесты во время написания кода, чтобы добиться более уверенного прогресса. Тесты дают нам обратную связь о том, что мы ничего не сломали на этом пути и что наш код работает достаточно хорошо. Тесты также служат бесценными “документами” для других разработчиков и для вас самих в будущем, чтобы понять, что делает приложение.
Разработчики обычно пишут модульные тесты и интеграционные тесты. Помимо этого, это, как правило, входит в обязанности по тестированию или обеспечению качества.
Прежде чем мы пойдем дальше, давайте определим, что такое модульные тесты и интеграционные тесты, чтобы не запутаться. Условия открыты для толкования! Затем мы можем коснуться того, какие тесты вы “должны” написать.
Модульные тесты
В чем большинство людей сходятся во мнении, так это в том, что модульные тесты:
- Сосредоточьтесь на небольшой части приложения.
- Как правило, они автоматизированы и написаны разработчиками.
- Ожидается, что они будут значительно быстрее, чем другие виды тестов.
Что такое единица измерения?
Объектно-ориентированные программы, как правило, рассматривают класс как единицу, но не всегда. Это ваше решение – определить, что такое единица измерения. Нет необходимости определять одну атомарную единицу для всего вашего приложения, вы можете столкнуться с ситуациями с различными требованиями.
Общительный или Одинокий?
Один из способов определить, какую единицу вы выбираете, – это решить, являются ли ваши тесты одиночными или общительными.
Социальные тесты проверяют подразделение и его сотрудничающие подразделения вместе. Часто для того, чтобы подразделение выполняло свое поведение, требуется сотрудничество с другими подразделениями, поэтому эта группа может служить “вашим логическим подразделением”, если вы хотите.
Одиночные тесты фокусируются на изолированном подразделении и исключают его сотрудничающие подразделения. Это делается с помощью тестовых двойников (Фиктивные объекты, Заглушки, Шпионы, Насмешки и тому подобное) вместо сотрудничающих подразделений.
Если вы хотите протестировать свою систему только с помощью социальных тестов, это не всегда практично, вы можете столкнуться с такими ситуациями, как асинхронное сотрудничество (HTTP-запросы) или одновременные действия (потоки), которые могут потребовать использования одиночного теста.
Интеграционные тесты
Грань между интеграционными тестами и модульными тестами спорна . Я считаю, что интеграционное тестирование связано с тестированием того, как группа системных блоков работает вместе с минимальными тестовыми двойниками .
Термин интеграционный тест применяется к различным сценариям. Ниже приведен спектр того, что некоторые люди считают интеграционным тестом:
- Тест, охватывающий несколько “единиц измерения”. Он проверяет взаимодействие между этими блоками.
- Тест, который охватывает несколько уровней приложения. На самом деле это особый случай первого случая. Например, в веб-приложении это может охватывать взаимодействие между уровнем сервиса и уровнем сохраняемости.
- Тест, который охватывает полный путь через приложение. Например, в веб-приложении он может охватывать все типы запросов к определенной конечной точке, например
/пользователи
. - Интеграция всего вашего приложения.
Я считаю, что максимальный объем интеграционных тестов соответствует сценарию 3 выше.
Что-то, что вам следует учитывать при проведении интеграционных тестов, – это конфигурация, вы можете отключить или изменить некоторые параметры, чтобы упростить тесты или увеличить время выполнения тестов. Обычно для тестирования создаются профили конфигурации. Вам необходимо найти баланс между созданием быстрых тестов, которые поддерживают ваш процесс разработки, и созданием реалистичных тестов, которые ближе к производственной среде.
Сколько тестов достаточно?
Общепринятая мудрость заключалась в том, чтобы писать в основном модульные тесты и меньше интеграционных тестов. Как правило, чем больше у вас тестов, тем больше у вас шансов обнаружить ошибки, но это случай уменьшения отдачи по мере приближения к 100 % охвату кода.
Вы должны решить, какую часть своего кода вы будете покрывать тестами, основываясь на различных ограничениях проекта, взвешивая затраты и выгоды. Стив Сандерсон [^3] выступает за выборочное модульное тестирование, основанное на сложности кода и стоимости его тестирования, что кратко представлено на диаграмме ниже.
Кент Бек выступает за написание не слишком большого количества тестов, и чтобы большинство тестов были интеграционными тестами [^4].
Я склонен согласиться с Кентом Беком и пытаюсь написать больше интеграционных тестов, но Я уделяю приоритетное внимание функциям и стараюсь найти правильный компромисс между скоростью и точностью при принятии решения о написании модульных тестов или интеграционных тестов.
Тестовые библиотеки, которые вы можете использовать
Вы можете использовать для тестирования любые библиотеки, какие захотите. В предыдущем посте я говорил об использовании Spring Initializr для создания скелета проекта, по умолчанию он включает зависимость теста spring boot starter и исключает модуль vintage engine , который используется для поддержки тестов, написанных в JUnit 3 и 4.
В Maven зависимость выглядит следующим образом:
org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine
Эта начальная зависимость объединяет совместимую коллекцию библиотек тестирования. Он включает в себя:
- JUnit 5 : Самая популярная библиотека для модульного тестирования. Это то, что большинство людей использует для выполнения своих тестов. JUnit 5 внес некоторые существенные изменения по сравнению с предыдущими версиями, в частности, изменились аннотации. Он предлагает поддержку синтаксисов JUnit 3 и JUnit 4 через свой модуль vintage engine , включите это, если вы хотите использовать один из этих синтаксисов. Документы довольно хороши, я предлагаю вам прочитать их, чтобы лучше ознакомиться с основами.
- Mockito : Используется для создания макетов объектов. Он предлагает простой API. Вы можете использовать аннотации, такие как
@Mock
для переменных, и это создаст для вас макет объекта. - Hamcrest : Используется для объявления правил “совпадений”, которые легче читать, например,
утверждать, что(Math.sqrt(-1), является(не числом()));
. - JSONPath : Используется для запроса объектов JSON с использованием выражений пути, например
$ .имя
|/будет ссылаться имя в{имя: "роб о'лири, возраст: 20}
. - JSONAssert : Позволяет выполнять утверждения с данными JSON с меньшим количеством кода например,
JSONAssert.assertEquals (ожидаемый JSON, фактический JSON, строгий режим);
. - JacksonTester : Создайте сопоставитель объектов для преобразования объектов в JSON и из него.
Вы увидите, что разные люди предпочитают одни библиотеки и стили другим, или они могут смешивать и сочетать их. Так что не пугайтесь, если вы увидите тестовые примеры, которые выглядят совсем не так, как вы уже привыкли, цели те же.
Тестирование приложения
Я внес одно изменение в код из предыдущего поста, я удалил фиктивные данные из UserController
. Код, который мы обсуждаем в этом посте, доступен в новой ветке в том же репозитории github под названием with-tests
.
Как писать тестовые примеры
Каждый тестовый случай должен иметь некоторую форму из следующих трех шагов:
- Подготовка: Настройте все данные, необходимые для выполнения тестируемого метода.
- Выполнение: Выполните фактический тестируемый метод.
- Проверка: Сравните фактическое поведение тестируемого метода с ожидаемым поведением.
Попробуйте написать тестовый пример для каждого метода, охватывающий счастливый путь (наиболее распространенный, безошибочный сценарий) и некоторые исключительные сценарии.
Модульный тест для пользователя
Тестирование классов моделей, как правило, является простым.
Должен Ли Я Протестировать POJOs?
Возможно, вы слышали о ссылке на Простые старые объекты Java (POJOs) раньше это обычно относилось к очень простой структуре классов, обычно к классу, у которого есть только некоторые атрибуты, получатели и установщики.
Мнения о том, следует ли вам тестировать POJOs, разнятся. Аргумент против их тестирования обычно заключается в том, что поведение тривиально и вряд ли сломается. Личное правило дяди Боба таково:
Правило в TDD (Разработка на основе тестов) “Тестируйте все, что может сломаться” Может ли добытчик сломаться? Как правило, нет, поэтому я не утруждаю себя проверкой. Кроме того, код, который я делаю тестирую, обязательно вызовет геттер, поэтому он будет протестирован.
Мое личное правило заключается в том, что я напишу тест для любой функции, которая принимает решение или выполняет более чем тривиальный расчет. Я не буду писать тест для i+1
, но, вероятно, напишу для если (i<0)...
и определенно будет для (-b+математика.sqrt(b*b - 4*a*c))/(2*a)
Аргумент в пользу тестирования POJOs заключается в том, что вы должны тестировать интерфейс, а не реализацию. Вы не должны основывать тесты на том, какие решения принимаются в рамках теста, и написание тестов для них – это способ обеспечить выполнение контрактов на методы . [^1] Некоторые люди хотят иметь высокий охват тестированием, поэтому они будут тестировать практически все.
Вы можете сами решить, хотите ли вы проводить модульное тестирование POJOs.
Написание тестового класса
Для модульного тестирования достаточно использовать JUnit, я буду использовать JUnit 5 только для тестирования Пользователь
.
- В проекте maven расположение тестов по умолчанию – src/test/java .
- Соглашение заключается в том, чтобы называть наши тестовые классы “*className*Test”, наш тестовый класс для
Пользователя
будет называтьсяПользовательский тест
. Вы можете называть это как вам угодно! Преимущество заключается в том, что когда вы создаете набор тестов для группировки тестов, вы просто включаете пакет, и поведение по умолчанию заключается в том, что программа выполнения тестов будет включать только те тесты, в названии которых есть “Тест”. - Вы можете включить подготовку, общую для каждого тестового случая, и запускать ее перед каждым тестовым случаем в методе “Настройка” с аннотацией
@Перед
(JUnit 4) или@перед классом
(JUnit 5). - Вы аннотируете тестовый случай с помощью
@Test
, чтобы его запустил тестировщик. - Наиболее распространенными утверждениями JUnit 5 являются
assertEquals
,assertNotEquals
,assertTrue
, иassertNull
. Вы найдете их вorg.junit.jupiter.api. Утверждения
пакет. - Вы можете включить общие задачи очистки, выполняемые после каждого тестового случая, в метод “демонтажа” с аннотацией
@После
(Junit 4) или@AfterClass
(JUnit 5).
Это пакет org.junit.jupiter.api
, который вы используете для тестирования.
В методе setUp
мы каждый раз создаем новый объект User
, это гарантирует, что наши тестовые случаи начинаются с одного и того же состояния по умолчанию и могут оставаться независимыми друг от друга. Вы не должны полагаться на тесты, выполняемые в определенном порядке.
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import java.util.ArrayList; public class UserTest { User testUser1 = null; @BeforeEach void setUp() { testUser1 = createNewUser(); } @AfterEach void tearDown() { testUser1 = null; } User createNewUser(){ return new User(1,"Rob OLeary", 33); } //naming convention I follow is: MethodName_StateUnderTest_ExpectedBehavior @Test void getId_1_ReturnValue(){ Assertions.assertEquals(1, testUser1.getId()); } //more test cases }
Тестовые примеры довольно просты и не требуют объяснений. Вы можете выбрать соглашение об именовании для своих методов если хотите, я в общих чертах следую соглашению Имя_меТода_СтатеЙ_для_экспЕртизы_вЫражения .
В большинстве IDE вы можете запускать свои тесты так же, как вы запускаете класс, и он покажет бегун теста, который показывает выполнение различных тестов.
Время выполнения пользовательского теста
Время выполнения составляет 371 мс для 9 тестов. На рисунке ниже показано, как выглядит бегун тестировщика в IntelliJ.
Модульный тест для пользовательского контроллера
Чтобы максимально приблизиться к одиночному модульному тесту, мы хотим смоделировать среду MVC и исключить встроенный сервер. В нашем методе Setup
мы создаем Автономный MockMvc и регистрируем в нем наш контроллер. Думайте об автономном режиме как о минимальной настройке среды.
Для каждого теста мы используем наш Экземпляр MockMvc
для выполнения требуемых нам фиктивных запросов мы получаем в ответ MockHttpServletResponse
, который мы можем использовать для утверждений.
Неявно UserController
использует библиотеку Джексона для преобразования Пользовательских
объектов в JSON и из него. Поскольку это минимальная среда, мы должны преобразовать наши Пользовательские
объекты в JSON, когда это необходимо. Мы используем Jacksontester
для этого.
public class UserControllerTest { private MockMvc mvc; private JacksonTesterjsonUser; private String basePath = "/users"; private final User TEST_USER = new User(1, "Rob OLeary", 21); private final User TEST_USER_2 = new User(2, "Angela Merkel", 20); @BeforeEach public void setup() { JacksonTester.initFields(this, new ObjectMapper()); // MockMvc standalone approach mvc = MockMvcBuilders.standaloneSetup(new UserController()).build(); } //test cases }
Тестовые примеры для пользовательского контроллера
Для тестовых утверждений я использую сопоставители Hamcrest и JacksonTester.
Я объясню тестовые примеры для привыкайте
, чтобы дать вам представление о том, как проверить себя.
получить пользователей (счастливый путь)
Это счастливый путь для Пользователи
. В ответе мы ожидаем получить всех пользователей в виде массива JSON и статус HTTP OK.
@Test public void getUsers_2UsersExist_ReturnOK() throws Exception{ //data prep addUsers(); // execute MockHttpServletResponse response = mvc.perform( get(basePath).accept(MediaType.APPLICATION_JSON)) .andReturn().getResponse(); // verify assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value()); String jsonUser1 = jsonUser.write(TEST_USER).getJson(); String jsonUser2= jsonUser.write(TEST_USER_2).getJson(); String jsonUserArray = "[" + jsonUser1 + "," + jsonUser2 + "]"; assertThat(response.getContentAsString()).isEqualTo(jsonUserArray); }
- Подготовка: Мы пишем вспомогательный метод
добавить пользователей
для создания пользователей для настройки данных. - Выполнение: Статический импорт используется для того, чтобы мы могли вызывать статические методы для выполнения запросов. Например,
статический импорт org.springframework.test.web.servlet.запрос.MockMvcRequestBuilders.get;
позволяет нам создать макет запроса GET с помощьюget()
. Мы цепляем методы, чтобы сократить наш код. - Проверьте: я использую сопоставители Hamcrest для утверждений. Я строю строку ожидаемого результата, используя
JacksonTester
.
В качестве альтернативы, некоторые люди, использующие JSONPath
для утверждений при работе с JSON, я использую JacksonTester
потому что Spring использует Джексона для функциональности преобразования, поэтому он немного ближе к реальной функциональности.
Это тот же тестовый случай с использованием JSONPath
.
/* These are the related import statements: import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.hamcrest.Matchers.hasSize; */ @Test public void getUsers_2UsersExist_ReturnOK() throws Exception{ //data prep addUsers(); //execute and verify mvc.perform(get(basePath)) .andExpect(status().isOk()) .andExpect(content().contentType("application/json")) .andExpect(jsonPath("$", hasSize(2))) .andExpect(jsonPath("$[0].id").exists()) .andExpect(jsonPath("$[0].name").exists()) .andExpect(jsonPath("$[0].age").exists()); }
получить пользователей (несчастливый путь)
Мы также хотим протестировать противоположный сценарий, когда у нас нет пользователей. Мы ожидаем пустой массив и статус Http OK в нашем ответе.
@Test public void getUsers_NoUsers_ReturnOKEmptyArray() throws Exception{ // no data prep required // execute MockHttpServletResponse response = mvc.perform( get(basePath).accept(MediaType.APPLICATION_JSON)) .andReturn().getResponse(); // verify assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value()); assertThat(response.getContentAsString()).isEqualTo("[]"); }
Мы охватываем каждый тестируемый метод аналогичными тестовыми случаями.
Время выполнения для UserControllerTest
Время выполнения для 14 тестовых случаев в UserControllerTest
составляет 12 секунд . Как вы можете видеть ниже, большая часть времени уходит на первый тестовый случай, последующие тестовые случаи выигрывают от кэширования, что позволяет им работать за 100 мс или около того.
Интеграционный тест для пользовательского контроллера
Существует несколько стратегий создания интеграционных тестов в зависимости от того, как вы определяете область применения интеграционного теста.
- Если вы используете аннотацию
@extendwith(SpringExtension.class)
, вы можете использовать контекст приложения . Это похоже на модульный тест, но у вас есть возможность автоматической проводки объекты. - Если вы используете аннотацию
@SpringBootTest
без параметров или@SpringBootTest(веб-среда. ИЗДЕВАТЬСЯ)
, * вы можете использовать контекст приложения * . Это похоже на модульный тест, но у вас есть возможность автоматической проводки объекты. Это сложный подход, чтобы сделать все правильно, и он не рекомендуется. - Вы можете использовать аннотации
@SpringBootTest(веб-среда.СЛУЧАЙНЫЙ ПОРТ)
или@SpringBootTest(веб-среда. ОПРЕДЕЛЕННЫЙ ПОРТ)
для использования реального HTTP-сервера . В этом случае вам необходимо использоватьRestTemplate
илиTestRestTemplate
для выполнения запросов, так как это внешний тест.
Вы можете прочитать Руководство по тестированию контроллеров в Spring Boot [^2], чтобы более подробно ознакомиться с этими стратегиями. Я буду использовать стратегию 3.
Написание интеграционного теста с реальным сервером
Я назвал свой класс интеграционного теста как Пользовательский контроллер IT
. Он имеет те же тестовые примеры, что и UserControllerTest
.
Аннотация @рАсширяЕтся с помощью(SpringExtension.class )
использует расширение JUnit 5 с именем Spring Extension
, которое инициализирует контекст Spring. Аннотация @SpringBootTest(веб-среда. RANDOM_PORT)
запускает сервер на случайном порту.
@ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class UserControllerIT { @Autowired private TestRestTemplate restTemplate; private String basePath = "/users"; private final User TEST_USER = new User(1, "Rob OLeary", 21); private final User TEST_USER_2 = new User(2, "Angela Merkel", 20); //test cases }
Тестовые примеры
В тестовых случаях я использую экземпляр TestRestTemplate
который был сделан с учетом интеграционных тестов. У него есть удобные методы getForEntity (URL-адрес URL, класс Тип ответа)
и postForEntity(URL-адрес URI, запрос объекта, тип ответа класса)
, которые упрощают выполнение запросов GET и POST соответственно, возвращая ответ, который преобразует тело в объект, который мы определяем в универсальном типе .
Существуют методы put (URL-адрес URI, запрос объекта)
и удалить (URL-адрес URI)
для выполнения запросов PUT и DELETE, но они возвращают ответы. Если вам нужен ответ для утверждений, вам нужно использовать один из методов exchange(..)
и указать метод HTTP в качестве одного из параметров.
Для тестовых утверждений я использую JSON Assert
утверждения. В качестве внешнего теста мне имеет смысл протестировать тела ответов в формате JSON, аналогично внешнему потребителю веб-службы. Вы можете использовать другие стили утверждений, если хотите!
Я объясню те же тестовые примеры, что и для UserControllerTest
.
получить пользователей (счастливый путь)
@Test public void getUsers_2UsersExist_ReturnOK() throws Exception{ //data prep postUsers(); // execute ResponseEntityresponse = restTemplate.getForEntity(basePath, String.class); // verify assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); String expected = "[{id:1,name:\"Rob OLeary\",age:21},{id:2,name:\"Angela Merkel\",age:20}]"; JSONAssert.assertEquals(expected, response.getBody(), JSONCompareMode.STRICT); //cleanup deleteUser( 1); deleteUser( 2); }
- Подготовка: Мы пишем вспомогательный метод
публиковать пользователей
для создания пользователей для настройки данных. - Выполнение: Мы указываем тип в виде строки при использовании
getForEntity (URL-адрес URL, класс Тип ответа)
, поэтому мы можем использоватьJSONAssert
для утверждений в теле ответа. - Проверьте: Использование
JSON Assert.assertEquals()
довольно просто, мы можем сравнить его непосредственно с ожидаемой строкой JSON, которую мы пишем. Вы можете объявить режим сравнения строгим или мягким.
получить пользователей (несчастливый путь)
Мы также хотим протестировать противоположный сценарий, когда у нас нет пользователей. Мы ожидаем пустой массив и статус Http OK в нашем ответе.
@Test public void getUsers_NoUsers_ReturnOKEmptyArray() throws Exception{ // no data prep required // execute ResponseEntityresponse = restTemplate.getForEntity(basePath, String.class); // verify assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); JSONAssert.assertEquals("[]",response.getBody(),JSONCompareMode.STRICT); }
Время выполнения для пользовательского контроллера
Общее время выполнения инициализации сервера и 14 тестовых случаев составляет 39 секунд (в первый раз) и около 28 секунд при последующих запусках. Эквивалентный модульный тест занял в общей сложности 12 секунд!
Напишите набор тестов
Вы можете сгруппировать тесты вместе, чтобы они выполнялись вместе как набор тестов . Вы можете создать любую группу, какую пожелаете, я напишу набор тестов для совместного выполнения наших пользовательских модульных тестов .
К сожалению, тестировщик в JUnit 5 не может запустить ваш набор тестов (пока). Вам необходимо добавить отдельный модуль JUnit4testrunner с именем Платформа JUnit для запуска наборов тестов в среде IDE, что означает, что вы также должны включить модуль vintage engine JUnit 5. Ниже показано, какие тестовые зависимости maven у вас должны быть.
org.springframework.boot spring-boot-starter-test test org.junit.platform junit-platform-runner test
В аннотации @selectpackages
указываются пакеты, в которых содержатся ваши тесты, Платформа JUnit
обнаружит и выполнит все тесты в пакете и его подпакетах. По умолчанию он будет включать только тестовые классы, имена которых либо начинаются с Тест
, либо заканчиваются Тест
или Тесты
.
import org.junit.platform.runner.JUnitPlatform; import org.junit.platform.suite.api.SelectPackages; import org.junit.runner.RunWith; @RunWith(JUnitPlatform.class) @SelectPackages("net.roboleary.user") public class UserTestSuite { }
В пакете org.junit.platform.suite.api доступны дополнительные параметры конфигурации для обнаружения и фильтрации тестов.
Вы можете запустить свой набор тестов с помощью Gradle, Maven или средства запуска консоли , если хотите.
исходный код
Код доступен в ветке исходного репозитория github под названием “с-тестами” .
Заключительные Слова
Я надеюсь, что это даст более подробное объяснение тестирования веб-приложения. Вначале я нашел это немного дезориентирующим, я не мог найти учебники с четкими различиями между синтаксисами и библиотеками, которые они использовали, и четкими целями в отношении их методологии тестирования.
Когда у вас есть веб-приложение с большим количеством уровней, таких как уровень сохраняемости и уровень сервиса, вам нужно немного больше работать с тестами, но это всего лишь вариация того, что мы уже сделали в основном. Обсуждение этого с полным приложением – самый наглядный способ узнать об этом.
Дайте ❤ , если вам понравилась статья или она показалась вам полезной. Если у вас есть вопросы или отзывы, обязательно дайте мне знать! 🙂
Счастливого кодирования! 👩 Личный праздник
Для создания изображения баннера были использованы два изображения, они были сделаны Фрипик от от .
Рекомендации
- Зачем тестировать POJOs? автор: Скотт Шипп : Зачем тестировать POJOs?
- Руководство по тестированию контроллеров в Spring Boot : Существуют различные способы тестирования классов контроллера (веб-уровня или уровня API) в Spring Boot, вы можете писать модульные тесты, а другие более полезны для интеграционных тестов.
- Выборочное модульное тестирование – Затраты и преимущества : Для определенных типов кода модульное тестирование работает блестяще, но для других типов кода написание модульных тестов требует огромных усилий, не оказывает существенной помощи в проектировании и вообще не уменьшает количество дефектов.
- Пишите тесты. Не слишком много. В основном интеграция Кента Доддса : Обсуждает стратегию тестирования и выступает за написание в основном интеграционных тестов.
От “А” до “Веб-приложения” (Серия из 2 частей)
Оригинал: “https://dev.to/robole/from-a-to-web-app-test-an-api-in-java-5di7”