Одним из основных аспектов архитектуры микросервисов является то, что приложение формируется как набор слабо связанных сервисов, каждый из которых может быть развернут независимо и связываться друг с другом с помощью некоторого легкого протокола.
Это связано с тем, что архитектура микросервисов — это распределенная система, которая затрудняет написание сквозных тестов. Предположим следующий простой пример, предоставленный Red Hat в качестве примера архитектуры микросервисов ( https://github.com/jbossdemocentral/coolstore-microservice ):
Теперь предположим, что вы хотите написать сквозной тест для службы корзины . Вы быстро увидите, что это совсем не просто, позвольте мне перечислить некоторые из причин:
- Служба Cart должна знать, как загрузить службу ценообразования, службу каталогов и MongoDB (и если вы хотите задействовать внешний интерфейс, а также Coolstore GW и WebUI ).
 - Служба корзины должна подготовить некоторые данные (данные) для обеих внешних служб.
 - Вы общаетесь со службами, используя сеть. Может случиться, что некоторые тесты не пройдут не из-за реального сбоя, а из-за проблемы инфраструктуры или из-за ошибки других служб. Таким образом, вероятность того, что эти тесты станут ненадежными и начнут давать сбои, не потому, что любые изменения, внесенные в текущую службу, выше.
 - В более сложных случаях выполнение этих тестов может быть дорогим с точки зрения стоимости (развертывание в облаке), времени (загрузка всей инфраструктуры и сервисов) и времени обслуживания.
 - Сложно запустить их на компьютере разработчика, так как вам нужны все компоненты, установленные на компьютере.
 
По этой причине сквозные тесты — не лучший подход для тестирования микросервиса, но вам все равно нужен способ тестирования от начала до конца сервиса.
Необходимо найти способ «симулировать» эти внешние зависимости, не вводя какой-либо фиктивный объект. Нам нужно обмануть тестируемый сервис, чтобы он действительно думал, что он взаимодействует с реальными внешними сервисами, а на самом деле это не так.
Метод, который позволяет нам это сделать, — это Service Virtualiztion. Виртуализация служб — это метод, позволяющий имитировать поведение компонентов приложений, таких как API.
Вы можете думать о виртуализации сервисов как о подходе, который вы использовали для реализации в ООП, но вместо симуляции на уровне объекта вы симулируете на уровне сервиса. Это издевательство над предприятием.
Существует множество инструментов виртуализации сервисов, но, по моему опыту, в экосистеме JVM одним из лучших инструментов является Hoverfly .
Давайте посмотрим, как выглядит «сквозной» тест для Cart Service.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
 | 
@RunWith(SpringRunner.class)@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,    properties = "CATALOG_ENDPOINT=catalog")public class CartServiceBoundaryTest {    @Autowired    private TestRestTemplate restTemplate;    @ClassRule    public static HoverflyRule hoverflyRule = HoverflyRule.inSimulationMode(dsl(        service("catalog")            .get("/api/products")            .willReturn(success(json(ProductsObjectMother.createVehicleProducts())))    ));    @Test    public void should_add_item_to_shopping_cart() {        final ShoppingCart shoppingCart = this.restTemplate.postForObject("/api/cart/1/1111/2", "", ShoppingCart.class);        assertThat(shoppingCart)            .returns(0.0, ShoppingCart::getCartItemPromoSavings)            .returns(2000.0, ShoppingCart::getCartItemTotal)            .returns(-10.99, ShoppingCart::getShippingPromoSavings)            .returns(2000.0, ShoppingCart::getCartTotal)            .extracting(ShoppingCart::getShoppingCartItemList)            .hasSize(1);    }} | 
  Этот сервис реализован с использованием Spring Boot , поэтому мы используем среду Spring Boot Test.  Важной частью здесь является то, что URL, на котором развернута служба каталогов, указывается с помощью 
  CATALOG_ENDPOINT свойство.  И для этого теста он установлен в каталог . 
Следующим важным моментом является раздел правил класса Hoverfly. В этом правиле указаны следующие вещи:
- Прокси-сервер Http запускается перед тестированием, и весь исходящий трафик из JVM перенаправляется на этот прокси-сервер.
 - Он записывает, что когда запрос к каталогу хоста выполнен и путь к нему равен / api / products, он должен вернуть результат успеха с данным документом json.
 
Сам тест просто использует TestRestTemplate (это клиент отдыха) и проверяет, что вы можете добавить некоторые элементы в корзину.
Обратите внимание, что вам не нужно настраивать, где запущен прокси-сервер Http, или настраивать любой порт, потому что Hoverfly автоматически настраивает сетевые параметры JVM, поэтому любой сетевой обмен данными осуществляется через прокси-сервер Hoverfly.
Так что обратите внимание, что теперь вам не нужно знать, как загружать службу каталога или как настроить ее с правильными данными.
Вы тестируете весь сервис в его границах, от входящих сообщений до исходящих сообщений другим сервисам, без насмешек над любым внутренним элементом.
Возможно, вы задаетесь вопросом: «Что происходит в случае, если текущий сервис также зависит от сервера базы данных?»
В этом случае вы делаете это как обычно, поскольку сама служба знает, какой сервер баз данных использует и какой тип данных ему требуется, вам нужно только загрузить сервер базы данных, заполнить необходимые данные (фикстуры) и выполнить тесты. Для этого сценария я предлагаю вам использовать Arquillian Cube Docker для загрузки службы базы данных из контейнера Docker, чтобы вам не нужно было устанавливать ее на каждом компьютере, для которого нужно запустить тесты, и Arquillian Persistence Extension для поддержания базы данных в известном состоянии.
В следующем примере сервиса оценки вы можете кратко увидеть, как использовать их для тестов на постоянство:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
 | 
public class ApueCubeRatingServiceTest {  // Starts in local dockerhost (docker machine or native) mongo docker image before running the test class  @ClassRule  public static ContainerDslRule mongodbContainer = new ContainerDslRule("mongo:3.2.18-jessie")      .withPortBinding(27017);  //Defines APE (Arquillian Persistence Extension to work as rule)  @Rule  public ArquillianPersistenceRule arquillianPersistenceRule = new ArquillianPersistenceRule();  // Defines to use MongoDb as NoSql Populator  @MongoDb  @ArquillianResource  NoSqlPopulator populator;  @Test  public void should_calculate_average_rating_when_adding_an_already_inserted_item() {    createPopulatorConfiguration()                .usingDataSet("single_rating_with_double.json")                .execute();         // Execute test       }     @After  public void tearDown() {    createPopulatorConfiguration().clean();  }     private NoSqlPopulatorConfigurator createPopulatorConfiguration() {          return populator.forServer(              mongodbContainer.getIpAddress(),              mongodbContainer.getBindPort(27017))              .withStorage(TEST_DATABASE);  }} | 
При таком подходе вы гарантируете, что все внутренние компоненты службы работают вместе, как и ожидалось, и избегаете беспорядочной природы сквозных тестов в микросервисах.
Таким образом, сквозное тестирование в любом микросервисе — это не то же самое, что сквозное тестирование в монолитном приложении, вы все еще тестируете весь сервис, а просто поддерживаете контролируемую среду, в которой тестирование зависит только от компонентов в пределах границы сервиса. ,
Как контрактные тесты подходят для этого? На самом деле, все, что показано здесь, может быть использовано на стороне клиента и поставщика при тестировании контракта, чтобы избежать необходимости загружать какие-либо внешние сервисы. Таким образом, как утверждают многие авторы, если вы используете контрактные тесты, они становятся новым сквозным тестом.
Вы можете увидеть полные проекты, где оба теста используются здесь и здесь.
Мы продолжаем учиться,
|   Опубликовано на Java Code Geeks с разрешения Алекса Сото, партнера нашей программы JCG .  См. Оригинальную статью здесь: Написание сквозного теста для архитектуры микросервисов 
 Мнения, высказанные участниками Java Code Geeks, являются их собственными.  | 
