DAY5
18
2024-01
Пятизвездочный генерал Макартур однажды сказал: «По сравнению с контрактным тестом интегрированный тест — всего лишь младший брат».
один
Давайте расскажем историю
Сегодня я поругался со своей девушкой (при условии, что у тебя есть девушка).
Сегодня вечером я снова сплю один на диване.,этим вечером,ты лежишь на диване,Не могу спать по ночам
Решил поделиться сегодняшней темой - придерживаться соглашениятест
Если посмотреть на этап создания договора,Существующие данные показывают, что самая ранняя дата может быть прослежена до «Дела Цю Вэй Дянь Тянь на третьем году правления короля Гуна династии Чжоу» во времена династии Западная Чжоу.,Вырежьте слова контракта на судне,Это необходимо для того, чтобы содержание, предусмотренное в документе, было признано и соблюдалось многими сторонами.,«Вечное сокровище на тысячи лет». Итак, сам договор,Просто чтобы сохранить это,Это установление доверительных отношений. Честность,Это прекрасная традиция, присущая нашей стране.,Это также национальная добродетель, существующая на протяжении тысячелетий.,В китайской конфуцианской идеологической системе,Это одна часть этического содержания.
Однако сейчас дела обстоят не так прекрасно. На самом деле многим людям не хватает духа контракта.
Однако в области тестирования программного обеспечения снова был использован острый инструмент контракта.
Для тестирования эта пирамида — лучшая метафора для понимания уровней тестирования. Эта пирамида впервые была использована в .
Майк Кон в своей книге «Успех с помощью Agile» читаем снизу вверх.
Модульные тесты обычно являются наиболее распространенными тестами, добавляемыми в проект. Цель — проверить код на уровне функции или метода. Если у вас есть функция суммы, вы хотите проверить ее на 5 + 5 = 10. Обычно такие тесты легко писать и поддерживать.
/**
* the function to test
*/
const sum = (a, b) => {
return a + b;
};
/**
* the unit test
*/
test("adds 5 + 5 to equal 10", () => {
expect(sum(5, 5)).toBe(10);
});
Интегрированный тест (или систематест) проверяет интерфейсы между компонентами. Вы можете протестировать весь класс или Служить,Обычно это предполагает имитацию внешнего интерфейса, который невозможно воспроизвести в тестовой среде. Написание интеграции немного сложно,Потому что здесь задействовано больше кода,И затраты на обслуживание выше. один разпроверить много кодов,Поэтому отслеживание проблемы может занять некоторое время.
3. Сквозной тест (E2E) — наиболее полный тест, поскольку его цель — смоделировать конечного пользователя продукта. Обычно вам необходимо создать полную комплексную среду, содержащую все компоненты приложения (все компоненты, внутреннее хранилище и т. д.). Вы можете использовать Postman Ожидание инструментов для моделирования REST позвоните или воспользуйтесь Cypress Ожидание инструментов для моделированияпроходить Web Использование интерфейса приложения. Обычно вы будете писать меньше E2E Тесты, поскольку они занимают много времени как с точки зрения времени выполнения, так и времени обслуживания.
Однако есть очевидная проблема:
Хотя те, кто находится на вершине пирамиды, лучше отражают качество обслуживания клиентов, у них также есть некоторые болезненные недостатки. их:
Итак, контрактный тест должен решить эту проблему.
Обычно имеет свойства, противоположные интеграционным тестам e2e:
так,контрактный тестчасконтрактный тестдаодинвид программного обеспечениятестметод,Сосредоточьтесь на проверке взаимодействия между различными компонентами, службами или системами в распределенной архитектуре. Этот подход полезен в сценариях, где имеется несколько компонентов или компоненты разрабатываются и поддерживаются разными командами.,и убедитесь, что они общаются правильнои Совместная работа имеет решающее значение。Короче говоря, контрактный Тестирование — это способ гарантировать, что две независимые системы (например, два микросервиса) совместимы и могут взаимодействовать друг с другом.
Архитектура, ориентированная на микросервисы, является противоположностью более традиционному монолитному подходу. Вместо создания единого программного обеспечения (например, приложения, работающего на сервере), вы можете создать набор слабосвязанных сервисов. Микросервисная архитектура имеет такие преимущества, как меньшая база кода и лучшая гибкость и масштабируемость.
Но микросервисы создают некоторые проблемы для тестирования. Вы можете каждый тест тестировать отдельно (по аналогии с интегрированным тестодином), а можете тестировать весь стек сквозным способом.
К сожалению, тестирование каждого сервиса по отдельности не гарантирует, что приложение будет корректно работать для пользователей. Если сервис A зависит от макета сервиса B в версии 1.4.0, но сервис B переключается на другую реализацию API 1.5.0, то вы можете без проблем прервать производство на этом уровне.
Комплексный тест требует от вас создания полноценной среды, содержащей все необходимое.,и выполнение теста может занять секунды или минуты,Это зависит от сложности. Потому что много слоев,Так что у вас может возникнуть много проблем,И сложно отследить, какие именно компоненты вышли из строя.
Хотя 5-секундный тест имеет множество применений, наиболее распространенными темами являются:
Эти вопросы очень важны,Потому что если бы одна страница могла быстро и легко передать всю эту информацию,Тогда больше шансов привлечь целевых пользователей. Это ключевой фактор при разработке улучшений, направленных на повышение коэффициентов конверсии и вовлеченности. в частности,Подобная оптимизация целевой страницы может оказать существенное влияние на ваши показатели успеха. Вы можете создавать варианты дизайна коллекции one.,им руководитьтест,Затем быстро выполните итерацию, чтобы найти лучшее решение.
Вот почему тестирование на основе контрактов так распространено в архитектурах микросервисов.
Контрактное тестирование (CBT) не является новым подходом, но эту концепцию легко понять в мире микросервисов. Предположим, у вас работает один только два микросервиса A и B. Простая система:
А потребляет услугу Б. А – потребитель, Б – производитель. Разговоры между службами — это простые вызовы HTTP REST, включающие обмен информацией.
А запрашивает информацию о пользователе:
GET /users/julien
B предоставляет информацию о пользователе:
{
slug: "julien",
fullname: "Julien Bras",
twitter: "_julbrs"
}
Этот разговор является контрактом. Б Ожидайте конкретного пути ( /users/{slug}) руководить HTTP Запрос,А Ожидаемый ответ с ключом и полным именем. JSON объект твиттер.
Идея CBT состоит в том, чтобы положиться на этот контракт и проверить стороны с помощью информации в контракте:
Каждый тест прост и самодостаточен (включает только один элемент). Служить можно только для проверки каждой стороны каждого отношения. Этот тестовый тест также работает для сложных отношений (например, «Служить» с несколькими ссылками на «Служить» или веб-интерфейса, использующего «Служить»).
до этого,Давайте сначала поймем один,Эти три отношения
Контрактный тест в основном проверяет, удовлетворяет ли каждый Служит «контракту» общения с другими Служить, моделируя взаимодействие между ними.
первый,Каждому «Служить» необходимо определить один контракт для своей внешней связи. Этот контракт содержит формат запроса и формат ожидаемого ответа, которые должна удовлетворить сторона Служить. Например,Если один Служить принимает конкретный HTTP-запрос и отвечает данными в формате JSON,Затем URL-адрес запроса, метод (POST, GET и т. д.), возможные заголовки запроса и возможные поля в теле запроса.,И определяет соответствующий код ответа, заголовок ответа и содержимое тела ответа.,Все это будет определено в договоре.
Как только контракт определен, пришло время его реализовать. контрактный тест в основном включает в себя следующие два этапа.
Для потребительского и провайдерского тестов обычно используются некоторые популярные контрактные контракты. Такие инструменты тестирования, как Pact, Spring Cloud Контракт и т. д.
Используйте этот способ, контрактный тест может гарантировать, что взаимодействие между Служить соответствует ожиданиям, независимо от того, была ли система развернута и в каком состоянии она находится, он только фокусируется наодининдивидуальныйиз Служитьили подключите,Остальные части системы игнорируются. Это позволяет нам проверить корректность взаимодействия Служить на раннем этапе системы.,Избегайте обнаружения проблем во время развертывания или системы.,Повышенная эффективность и надежность во время разработки и развертывания.
Предположим, что есть две Служить: заказ Служить (Поставщик) и Служить инвентарь (Потребитель). Роль инвентаризации Служить заключается в уменьшении соответствующего количества товаров при получении запроса на заказ. Взаимодействие между двумя Служить будет осуществляться через HTTP APIруководить.
в этом сценарии,Определенный нами «контракт» может иметь следующую форму: Когда заказ Служить отправляет POST-запрос в инвентарь Служить.,Этот запрос содержит детали заказа (например,,Идентификатор продукта и количество),нравиться:
POST /inventory/update
Content-Type: application/json
{
"productId": "123",
"quantity": 3
}
Инвентарь Служить должен вернуть код статуса один 200,и подтвердите уменьшенное количество,нравиться:
200 OK
Content-Type: application/json
{
"productId": "123",
"quantity": 3,
"status": "success"
}
После того как этот контракт определен, мы можем руководитьконтрактным тестом.
контрактный на стороне производителя (заказать Служить) тест,Сымитируем запрос отправленный инвентарем Служить,Затем проверьте, соответствует ли договору отзыв приказа Служить. Например, мы сконструируем один запрос,Содержит идентификатор продукта как «123».,количество 3,Затем проверьте, является ли возвращенный ответ кодом состояния 200.,возвращатьсяJSONданет Содержит идентификатор продукта как «123».,количество 3а такжеstatusдля"success"。
контрактный на потребителе (складе Служить) конец тест,Смоделируем заказ Служить,отправлятьодининдивидуальный Содержит идентификатор продукта как «123».,количество 3изответ,Затем посмотрите, сможет ли инвентарь Служить правильно обработать этот ответ. Например,После получения этого ответа требуется инвентаризация Служить,Уменьшите количество товара с идентификатором «123» на 3.
Вот пример контрактного теста для заказа Служить (Провайдер):
from pact import Consumer, Provider
from requests.api import post
# Создайте один объект Пакта. Потребитель – это инвентарь Служить, а Поставщик – заказ Служить.
pact = Consumer('InventoryService').has_pact_with(Provider('OrderService'))
# Определение взаимодействий
pact.start_service()
pact.given(
'A request from InventoryService for order update'
).upon_receiving(
'A POST request for order update'
).with_request(
method='POST',
path='/inventory/update',
body={
'productId': '123',
'quantity': 3
}
).will_respond_with(
status=200,
body={
'productId': '123',
'quantity': 3,
'status': 'success'
}
)
# контрактный тест
with pact:
result = post(pact.uri, json={'productId': '123', 'quantity': 3})
# Проверить результаты
assert result.json() == {'productId': '123', 'quantity': 3, 'status': 'success'}
pact.stop_service()
В приведенном выше коде,Сначала мы определяем контракт между Потребителем (Инвентаризация Служить) и Поставщиком (Заказ Служить). Затем мы приступили к моделированию Провайдера Служить.,и определяет одно взаимодействие,Это взаимодействие определяет, каким должен быть запрос из инвентаря Служить и каким должен быть ответ от заказа Служить. наконец,Выполняем контрактный тест в контекстном менеджере Pact,Отправьте запрос и проверьте, соответствует ли ответ ожидаемому. Если все проверки пройдены,Тогда мы сможем подтвердить, что заказ Служить выполняет договор с инвентарем Служить. в противном случае,Нам нужно будет отремонтировать заказ Служить для выполнения контракта.
Итак, как в этом примере служба заказов обрабатывает запрос от службы инвентаризации?
Обычно в системе микросервисов в реальных сценариях заказ Служить будет иметь специальную функцию маршрутизации и обработки для обработки запроса из инвентаря Служить. Предположим, мы используем фреймворк Flask и показываем пример простой обработки запроса POST.
from flask import Flask, request, jsonify
app = Flask(__name__)
# Этот словарь используется для хранения информации о запасах продуктов.
inventory = {"123": 10}
@app.route("/inventory/update", methods=["POST"])
def update_inventory():
# Получить запрос JSONданные
data = request.get_json()
# Получите идентификатор продукта и количество, которое необходимо обновить.
product_id = data["productId"]
quantity = data["quantity"]
# Обновить информацию о наличии товара
inventory[product_id] -= quantity
# Обратный ответ
return jsonify({
"productId": product_id,
"quantity": quantity,
"status": "success"
})
if __name__ == "__main__":
app.run()
В приведенном выше коде,Я определил маршрут «/inventory/update»,Этот маршрут принимает только запросы POST. При заказе Служить поступает запрос на наличие Служить,Функция update_inventory будет выполнена. Эта функция сначала анализирует JSONданный запрос, чтобы получить идентификатор продукта и количество, которое необходимо обновить.,Затем обновите информацию об инвентаре. наконец,В ответ верните одни данные JSON, содержащие обновленную информацию. Так реализована одна из возможных функций обработки заказов.
CBT может стать отличным дополнением к вашему арсеналу. При правильном использовании он может заменить значительную часть вашего существующего E2Etest.
Вышеизложенное — это весь контент на сегодня. Надеюсь, он будет полезен всем. Я также надеюсь, что все будут оставлять больше комментариев, ставить лайки, смотреть и пересылать «Четыре любви подряд» для поддержки. Увидимся в следующей статье, пока~👋