Протестируйте REST API с помощью Java
1. обзор
В этом руководстве основное внимание уделяется основным принципам и механикеtesting a REST API with live Integration Tests (с полезной нагрузкой JSON).
# # Основная цель - предоставить введение в тестирование базовой правильности API - и мы собираемся использовать последнюю версиюGitHub REST API для примеров.
Для внутреннего приложения этот вид тестирования обычно выполняется в качестве позднего шага в процессе непрерывной интеграции, потребляя REST API после того, как он уже развернут.
При тестировании ресурса REST обычно есть несколько ортогональных обязанностей, на которых должны сосредоточиться тесты:
-
HTTPresponse code
-
другой HTTPheaders в ответе
-
payload (JSON, XML)
Each test should only focus on a single responsibility and include a single assertion. Сосредоточение внимания на четком разделении всегда имеет преимущества, но при проведении такого рода тестирования черного ящика это еще более важно, поскольку общая тенденция заключается в написании сложных сценариев тестирования в самом начале.
Еще один важный аспект интеграционных тестов - соблюдениеSingle Level of Abstraction Principle - логика внутри теста должна быть написана на высоком уровне. Такие детали, как создание запроса, отправка HTTP-запроса на сервер, работа с IO и т. Д., Должны выполняться не встроенно, а с помощью служебных методов.
Дальнейшее чтение:
Интеграционное тестирование весной
Краткое руководство по написанию интеграционных тестов для веб-приложения Spring.
Тестирование в Spring Boot
Узнайте, как Spring Boot поддерживает тестирование, чтобы эффективно писать модульные тесты.
Руководство по гарантированному отдыху
Изучите основы REST-гарантированной - библиотеки, которая упрощает тестирование и проверку REST API.
2. Проверка кода состояния
@Test
public void givenUserDoesNotExists_whenUserInfoIsRetrieved_then404IsReceived()
throws ClientProtocolException, IOException {
// Given
String name = RandomStringUtils.randomAlphabetic( 8 );
HttpUriRequest request = new HttpGet( "https://api.github.com/users/" + name );
// When
HttpResponse httpResponse = HttpClientBuilder.create().build().execute( request );
// Then
assertThat(
httpResponse.getStatusLine().getStatusCode(),
equalTo(HttpStatus.SC_NOT_FOUND));
}
Это довольно простой тест -it verifies that a basic happy path is working, не усложняющий набор тестов.
Если по какой-либо причине он не работает, то нет необходимости искать какой-либо другой тест для этого URL, пока он не будет исправлен.
3. Проверка типа носителя
@Test
public void
givenRequestWithNoAcceptHeader_whenRequestIsExecuted_thenDefaultResponseContentTypeIsJson()
throws ClientProtocolException, IOException {
// Given
String jsonMimeType = "application/json";
HttpUriRequest request = new HttpGet( "https://api.github.com/users/eugenp" );
// When
HttpResponse response = HttpClientBuilder.create().build().execute( request );
// Then
String mimeType = ContentType.getOrDefault(response.getEntity()).getMimeType();
assertEquals( jsonMimeType, mimeType );
}
Это гарантирует, что ответ действительно содержит данные JSON.
Как вы могли заметить,we’re following a logical progression of tests - сначала код состояния ответа (чтобы убедиться, что запрос был в порядке), затем тип носителя ответа, и только в следующем тесте мы рассмотрим фактическую полезную нагрузку JSON.
4. Тестирование полезной нагрузки JSON
@Test
public void
givenUserExists_whenUserInformationIsRetrieved_thenRetrievedResourceIsCorrect()
throws ClientProtocolException, IOException {
// Given
HttpUriRequest request = new HttpGet( "https://api.github.com/users/eugenp" );
// When
HttpResponse response = HttpClientBuilder.create().build().execute( request );
// Then
GitHubUser resource = RetrieveUtil.retrieveResourceFromResponse(
response, GitHubUser.class);
assertThat( "eugenp", Matchers.is( resource.getLogin() ) );
}
В этом случае я знаю, что по умолчанию ресурсы GitHub представлены в формате JSON, но обычно заголовок ответа `++`Content-Type должен тестироваться вместе с заголовкомAccept запроса - клиент спрашивает для определенного типа представления черезAccept, который сервер должен соблюдать.
5. Утилиты для тестирования
Мы собираемся использовать Jackson 2 для демаршалинга необработанной строки JSON в типобезопасный объект Java:
public class GitHubUser {
private String login;
// standard getters and setters
}
Мы используем только простую утилиту, чтобы тесты были чистыми, удобочитаемыми и имели высокий уровень абстракции:
public static T retrieveResourceFromResponse(HttpResponse response, Class clazz)
throws IOException {
String jsonFromResponse = EntityUtils.toString(response.getEntity());
ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper.readValue(jsonFromResponse, clazz);
}
Обратите внимание наJackson is ignoring unknown properties, которые API GitHub отправляет нам - это просто потому, что представление пользовательского ресурса на GitHub становится довольно сложным - и нам здесь не нужна эта информация.
6. зависимости
Утилиты и тесты используют следующие библиотеки, все доступные в Maven central:
-
Hamcrest (необязательно)
7. Заключение
Это только одна часть того, каким должен быть полный комплект тестирования интеграции. Тесты сосредоточены наensuring basic correctness for the REST API, не вдаваясь в более сложные сценарии,
Например, не рассматриваются следующие вопросы: обнаружение API, использование разных представлений для одного и того же ресурса и т. Д.
[.iframe-fluid] ##
Реализация всех этих примеров и фрагментов кода можно найти вover on Github - это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.