From 481b3b92e6345238c0de8fa4fa07cb3621f1536f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Fernando=20Garci=CC=81a=20Q?= <105936384+lglabs@users.noreply.github.com> Date: Sat, 2 Nov 2024 22:36:24 +0100 Subject: [PATCH] [LG-64] - update docs for acceptance test module - And remove liquibase migration on acceptance test module --- .../src/main/resources/application.yml | 0 .../src/test/resources/application-test.yml | 2 + .../db/changelog/db.changelog-master.yaml | 3 - .../resources/db/changelog/ddl-v.0.0.1.yaml | 34 --- blank-support/app/docs/atdd-module.md | 289 +++++++++++++++--- 5 files changed, 254 insertions(+), 74 deletions(-) delete mode 100644 blank-acceptance-test/src/main/resources/application.yml delete mode 100644 blank-acceptance-test/src/test/resources/db/changelog/db.changelog-master.yaml delete mode 100644 blank-acceptance-test/src/test/resources/db/changelog/ddl-v.0.0.1.yaml diff --git a/blank-acceptance-test/src/main/resources/application.yml b/blank-acceptance-test/src/main/resources/application.yml deleted file mode 100644 index e69de29..0000000 diff --git a/blank-acceptance-test/src/test/resources/application-test.yml b/blank-acceptance-test/src/test/resources/application-test.yml index 0e4ba2a..8a72344 100644 --- a/blank-acceptance-test/src/test/resources/application-test.yml +++ b/blank-acceptance-test/src/test/resources/application-test.yml @@ -25,6 +25,8 @@ blanksystem: spring: datasource: url: jdbc + liquibase: + enabled: false logging: level: diff --git a/blank-acceptance-test/src/test/resources/db/changelog/db.changelog-master.yaml b/blank-acceptance-test/src/test/resources/db/changelog/db.changelog-master.yaml deleted file mode 100644 index 64ac92c..0000000 --- a/blank-acceptance-test/src/test/resources/db/changelog/db.changelog-master.yaml +++ /dev/null @@ -1,3 +0,0 @@ -databaseChangeLog: - - include: - file: db/changelog/ddl-v.0.0.1.yaml \ No newline at end of file diff --git a/blank-acceptance-test/src/test/resources/db/changelog/ddl-v.0.0.1.yaml b/blank-acceptance-test/src/test/resources/db/changelog/ddl-v.0.0.1.yaml deleted file mode 100644 index a184e15..0000000 --- a/blank-acceptance-test/src/test/resources/db/changelog/ddl-v.0.0.1.yaml +++ /dev/null @@ -1,34 +0,0 @@ -databaseChangeLog: - - changeSet: - id: 01_blank_create_schema - author: lg - changes: - - sql: - sql: "CREATE SCHEMA IF NOT EXISTS blank" - - changeSet: - id: 02_blank_create_blank_table - author: lg - changes: - - createTable: - schemaName: blank - tableName: blank - columns: - - column: - name: id - type: UUID - constraints: - primaryKey: true - nullable: false - - column: - name: name - type: VARCHAR(50) - constraints: - nullable: true - - column: - name: insert_timestamp - type: timestamp - constraints: - nullable: true - - column: - name: update_timestamp - type: timestamp \ No newline at end of file diff --git a/blank-support/app/docs/atdd-module.md b/blank-support/app/docs/atdd-module.md index d69b65f..ba56270 100644 --- a/blank-support/app/docs/atdd-module.md +++ b/blank-support/app/docs/atdd-module.md @@ -50,14 +50,15 @@ For more details, read more about [Hexagonal Architecture(Spanish)][2]. Dependencies: > _Lg5 tries to simplify dependencies but the power is the same._ 👌 -```xml title="acceptance-test-module(pom.xml)" linenums="1" hl_lines="3" +```xml title="acceptance-test-module(pom.xml)" linenums="1" hl_lines="4" + com.lg5.spring - lg5-spring-integration-test + lg5-spring-acceptance-test test ``` -It is recommended to create the following `boot/` directory on your test directory. +It is recommended to create the following `boot/` directory on your `test` directory as `com.[blanksystem].[blank].service/boot`. ```markdown hl_lines="4" └── test/ ├── java/ @@ -73,63 +74,108 @@ To get started, you need to add the following classes: === "TestContainers Loader" > Important the image name and use the correct version. For instance: `com.blanksystem/blank-service` with version `1.0.0-alpha`. - ```java title="TestContainersLoader.java" linenums="1" hl_lines="32" + ```java title="TestContainersLoader.java" linenums="1" hl_lines="38" + import com.lg5.spring.kafka.config.data.KafkaConfigData; + import com.lg5.spring.testcontainer.config.AppContainerCustomConfig; + import com.lg5.spring.testcontainer.config.ContainerConfig; import com.lg5.spring.testcontainer.config.KafkaContainerCustomConfig; import com.lg5.spring.testcontainer.config.PostgresContainerCustomConfig; - import com.lg5.spring.testcontainer.config.WireMockGuiContainerCustomConfig; import com.lg5.spring.testcontainer.config.WiremockContainerCustomConfig; import com.lg5.spring.testcontainer.container.AppCustomContainer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; - import org.testcontainers.containers.BindMode; + import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.KafkaContainer; import org.testcontainers.containers.PostgreSQLContainer; import org.wiremock.integrations.testcontainers.WireMockContainer; + import java.util.HashMap; + import java.util.List; import java.util.Map; - - import static com.lg5.spring.testcontainer.config.DataBaseContainerCustomConfig.JDBC_URL_CUSTOM; - import static com.lg5.spring.testcontainer.config.KafkaContainerCustomConfig.BOOTSTRAP_SERVERS_CUSTOM; - import static com.lg5.spring.testcontainer.util.Constant.APP_PORT_DEFAULT; + import java.util.function.Consumer; @Import({ PostgresContainerCustomConfig.class, KafkaContainerCustomConfig.class, WiremockContainerCustomConfig.class, - WireMockGuiContainerCustomConfig.class + AppContainerCustomConfig.class }) - public class TestContainersLoader { + public final class TestContainersLoader { + + private final KafkaConfigData kafkaConfigData; + + private final List containerConfigs; + + public TestContainersLoader(KafkaConfigData kafkaConfigData, List containerConfigs) { + this.kafkaConfigData = kafkaConfigData; + this.containerConfigs = containerConfigs; + } @Bean - public AppCustomContainer apiContainer(PostgreSQLContainer postgresContainer, + public AppCustomContainer apiContainer(AppCustomContainer appCustomContainer, + PostgreSQLContainer postgresContainer, KafkaContainer kafkaContainer, - WireMockContainer wireMockContainer) { + WireMockContainer wireMockContainer, + GenericContainer schemaRegistryContainer) { + + appWithEnvBuilder(appCustomContainer.getEnvMap(), postgresContainer, kafkaContainer, + wireMockContainer, schemaRegistryContainer); - AppCustomContainer appCustomContainer = new AppCustomContainer("com.blanksystem/blank-service:1.0.0-alpha"); - appCustomContainer.withFileSystemBind("./target/logs", "/logs", BindMode.READ_WRITE); - appCustomContainer.withAppEnvVars(appWithEnvBuilder(postgresContainer, kafkaContainer, wireMockContainer)); appCustomContainer.start(); appCustomContainer.initRequestSpecification(); + updateKafkaConfigData(kafkaContainer); + return appCustomContainer; } - private Map appWithEnvBuilder(PostgreSQLContainer postgreSQLContainer, - KafkaContainer kafkaContainer, - WireMockContainer wireMockContainer) { + private void updateKafkaConfigData(KafkaContainer kafkaContainer) { + kafkaConfigData.setBootstrapServers(kafkaContainer.getBootstrapServers()); + } + + private void appWithEnvBuilder(Map envMap, PostgreSQLContainer postgreSQLContainer, + KafkaContainer kafkaContainer, + WireMockContainer wireMockContainer, + GenericContainer schemaRegistryContainer) { + + final Map, Consumer>> configActions = new HashMap<>(); + + + addPostgresConfig(postgreSQLContainer, configActions); + + + addWiremockConfig(wireMockContainer, configActions); + + addKafkaConfig(kafkaContainer, schemaRegistryContainer, configActions); + + configActions.forEach((configClass, action) -> action.accept(envMap)); - return Map.of( - "SERVER_PORT", String.valueOf(APP_PORT_DEFAULT), - "SPRING_DATASOURCE_URL", postgreSQLContainer.getEnvMap().get(JDBC_URL_CUSTOM), - "SPRING_DATASOURCE_USERNAME", postgreSQLContainer.getUsername(), - "SPRING_DATASOURCE_PASSWORD", postgreSQLContainer.getPassword(), - "KAFKA-CONFIG_BOOTSTRAP-SERVERS", kafkaContainer.getEnvMap().get(BOOTSTRAP_SERVERS_CUSTOM), - "THIRD_JSONPLACEHOLDER_URL", wireMockContainer.getBaseUrl(), - "log.path", "/logs" - ); } - } + private void addKafkaConfig(KafkaContainer kafkaContainer, GenericContainer schemaRegistryContainer, Map, Consumer>> configActions) { + configActions.put(KafkaContainerCustomConfig.class, + map -> containerConfigs.stream() + .filter(KafkaContainerCustomConfig.class::isInstance) + .findFirst() + .ifPresent(config -> map.putAll(((KafkaContainerCustomConfig) config) + .initializeEnvVariables(kafkaContainer, schemaRegistryContainer)))); + } + + private void addWiremockConfig(WireMockContainer wireMockContainer, Map, Consumer>> configActions) { + configActions.put(WiremockContainerCustomConfig.class, + map -> containerConfigs.stream() + .filter(WiremockContainerCustomConfig.class::isInstance) + .findFirst() + .ifPresent(config -> map.putAll(config.initializeEnvVariables(wireMockContainer)))); + } + + private void addPostgresConfig(PostgreSQLContainer postgreSQLContainer, Map, Consumer>> configActions) { + configActions.put(PostgresContainerCustomConfig.class, + map -> containerConfigs.stream() + .filter(PostgresContainerCustomConfig.class::isInstance) + .findFirst() + .ifPresent(config -> map.putAll(config.initializeEnvVariables(postgreSQLContainer)))); + } ``` @@ -142,11 +188,12 @@ To get started, you need to add the following classes: import io.cucumber.spring.CucumberContextConfiguration; import org.springframework.context.annotation.Import; - @CucumberContextConfiguration @Import(TestContainersLoader.class) + @CucumberContextConfiguration public class CucumberHooks extends Lg5TestBootPortNone { } + ``` @@ -174,34 +221,200 @@ To get started, you need to add the following classes: @IncludeEngines("cucumber") @SelectClasspathResource("features") @ConfigurationParameters({ - @ConfigurationParameter(key = Constants.PLUGIN_PROPERTY_NAME, value = "pretty, json:target/atdd-reports/cucumber.json, " + - "html:target/atdd-reports/cucumber-reports.html"), - @ConfigurationParameter(key = Constants.GLUE_PROPERTY_NAME, value = "com.blanksystem.blank.service") + @ConfigurationParameter(key = Constants.PLUGIN_PROPERTY_NAME, value = "pretty, json:target/atdd-reports/cucumber.json, " + + "html:target/atdd-reports/cucumber-reports.html"), + @ConfigurationParameter(key = Constants.GLUE_PROPERTY_NAME, value = "com.blanksystem.blank.service") }) class AcceptanceTestCase { - + @Test void test() { File feature = new File("src/test/resources/features"); assertTrue(feature.exists()); } } + ``` +=== "Features" + + > 1. Create a directory called`src/test/resources/features` + > 2. Create the feature file in `example.feature` + > 3. Create new step definition file + + ```gherkin title="example.feature" linenums="1" hl_lines="2 5" + Feature: + I as a customer want to create a blank using the repository template + + Scenario: the blank should be CREATED when use the repository template + Given a repository template + When blank is created + Then the blank will be created using the repository template + + ``` + + + ```java title="MyStepdefs.java" linenums="1" hl_lines="2 6 10" + public class MyStepdefs { + @Given("a repository template") + public void aRepositoryTemplate() { + } + + @When("blank is created") + public void blankIsCreated() { + } + + @Then("the blank will be created using the repository template") + public void theBlankWillBeCreatedUsingTheRepositoryTemplate() { + } + } + ``` + +=== "Application Test Properties" + + With `destination.path: ./target/logs` where stored logs file from blank-service aftet that tests finished. + Replace some name by your system and domain name: `blanksystem` and `blank`. + + > `application.image.name: your-docker.images:version + + ⚠️ Please attention to highlighted lines!!! + ⚠️ Disabled liquibase migrations, only test(NOT PRODUCTION). + + ```yaml title="application-test.yml" linenums="1" hl_lines="5 10 15 22 43 41 53 54" + application: + server: + port: 8080 + image: + name: com.blanksystem/blank-service:1.0.0-alpha + traces: + console: + enabled: false + file: + enabled: true + log: + source: + path: /logs + destination: + path: ./target/logs + + blanksystem: + blank: + events: + journal: + blank: + topic: blank.1.0.event.created + consumer: + group: blank-topic-consumer-acceptance-test + spring: + datasource: + url: jdbc + liquibase: + enabled: false + + logging: + level: + com.blanksystem: INFO + io.confluent.kafka: ERROR + org.apache: ERROR + + third: + basic: + auth: + username: admin + password: pass + jsonplaceholder: + url: https://jsonplaceholder.typicode.com + basic: + auth: + username: admin + password: pass + + wiremock: + config: + folder: "wiremock/third_system/template.json" + url: "third.jsonplaceholder.url" + port: 7070 ``` !!! tip "When do you like to use some TestContainer" if you use some TestContainer CustomConfig enabled, you would added the following properties for each one: - * Postgres Container + * Postgres Container + * Add liquibase files with migrations. * Kafka Container * `${kafka-config.bootstrap-servers}` * SchemaRegistry Container - * `${kafka-config.schema-registry-url}` + * `${kafka-config.schema-registry-url}` + * KAFKA MODELS + * If you must have kafka models, So, CREATE AVRO DIRECTORY For instance: `src/test/resources/avro/example.avsc` * Wiremock Container * Specify third system url `${wiremock.config.url}`. * Indicate a port binding to connect: `${wiremock.config.port}`. * Directory where stored the mock req/res http `${wiremock.config.folder}`. + * CREATE WIREMOCK DIRECTORY and a TEMPLATE base, For instance: `src/test/resources/wiremock/third_system/template.json`. + +## Needs the Spring Context + +Add a classic application main with Spring Boot: + +> Stay alert with the `scanBasePackages` for your tests, in this case principal package the current system and extras as kafka. + +```java title="Application.java" linenums="1" hl_lines="6" +package com.blanksystem.blank.service; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = {"com.blanksystem", "com.lg5.spring.kafka"}) +public class Application { + + public static void main(String[] args) { + + SpringApplication.run(Application.class, args); + } +} +``` + +### More dependencies +If you must have Kafka(avro plugin), database, etc. Please include more dependencies. +```xml linenums="1" hl_lines="5 10 15 22 41 49 50 51" + + ... + + + com.lg5.spring + lg5-spring-data-jpa + + + + com.lg5.spring.kafka + lg5-spring-kafka-model + + + + com.lg5.spring.kafka + lg5-spring-kafka-producer + + + + com.lg5.spring.kafka + lg5-spring-kafka-consumer + + ... + +... + + + + + org.apache.avro + avro-maven-plugin + + + +``` + + Read more at [Lg5Spring Wiki][2]. ## Project structure @@ -223,10 +436,12 @@ Read more at [Lg5Spring Wiki][2]. │ │ ├── CucumberHooks.java │ │ └── TestContainersLoader.java │ └── resources/ +| └── application-test.yml │ ├── features/ │ │ └── blank-service.feature │ └── wiremock/ │ └── placeholder/ +│ └── target(autogenerate)/ └── atdd-reports/ ├── cucumber-reports.html