#java #unit-testing #elasticsearch #junit #elasticsearch-query
#java #модульное тестирование #elasticsearch #junit #elasticsearch-запрос
Вопрос:
Итак, я пишу модульные тесты java (mockito) для класса, который создает запросы elasticsearch. Текущий способ, которым это делается, довольно неаккуратен, обновлять тесты при каждом внесении изменений — такая утомительная работа. К сожалению, похоже, что официальная документация ES для тестирования Java мертва, поэтому я надеюсь, что у кого-нибудь есть несколько советов относительно того, как лучше написать мои тесты.
Исходный класс — довольно сложный запрос, и модульные тесты, по сути, создают экземпляр класса и сериализуют его в JsonNode. Затем выполняется обход JsonNode и утверждается ожидаемое значение. Кажется, что этот стиль тестирования граничит с жестким кодом. Вот пример теста:
@Test
public void toQueryBuilder_initialQuery() {
// queryValue defined here.
JsonNode result = QueryBuilderSerialization.toJsonNode(new QueryConstraintA(queryValue)
.toQueryBuilder());
// assert expected queries
assertEquals(EXPECTED_MIN, result
.get("bool")
.get("filter").get(0)
.get("function_score")
.get("min_score")
.asInt());
assertEquals(EXPECTED_LOWER_BOUND, countQuery.get(7)
.get("function_score")
.get("query")
.get("nested")
.get("query")
.get("constant_score")
.get("filter")
.get("bool")
.get("filter").get(0)
.get("bool")
.get("filter").get(0)
.get("bool")
.get("should").get(0)
.get("range")
.get(RANGE_FIELD_NAME)
.get("from")
.asInt());
}
В этом стиле написано примерно 1000 строк тестов, только в этом файле. Итак, вы можете себе представить, насколько сложно изменять исходный запрос. У кого-нибудь есть предложения относительно того, как это можно сделать лучше? Заранее спасибо за любое время, потраченное на это.
Ответ №1:
Я не рекомендую писать тесты такого рода. Вместо проверки того, что запрос выглядит нормально, вы действительно хотите проверить, возвращает ли он правильный вывод при запуске. Это намного больше работы, но в нашем магазине мы выполняем фактические запросы к локальному экземпляру Elasticsearch в Docker. Это проверяет, что запросы не искажены и что они действительно выполняют то, что должны. Это также делает их более устойчивыми, когда кто-то рефакторирует запрос (для улучшения задержки), не внося никаких изменений в логику.
Комментарии:
1. Я вроде как хочу провести интеграционный тест, но я действительно не хочу запускать локальный экземпляр Docker на сервере сборки, что на самом деле не является лучшим решением для аппаратного обеспечения. Прошел год с момента вашего сообщения, нашли какие-либо другие хорошие решения для тестирования клиента?
2. Не совсем 🙂 Я все еще думаю, что локальный ES docker — это правильный путь. Другой вариант — где-нибудь разместить небольшой сервер разработки ES. В настройке теста сгенерируйте индекс со случайным именем, поместите в него некоторые данные и удалите его при удалении. Поскольку имена тестов являются случайными, вы запускаете несколько человек, и они не будут конфликтовать друг с другом. Однако, если сервер разработки не работает, CI будет нарушен для всех, поэтому я предпочитаю вариант локального docker.