diff --git "a/.github/workflows/\btestAndDeploy.yml" "b/.github/workflows/\btestAndDeploy.yml" index 62d4f46dd..1eaf51e6f 100644 --- "a/.github/workflows/\btestAndDeploy.yml" +++ "b/.github/workflows/\btestAndDeploy.yml" @@ -1,15 +1,21 @@ name: testAndDeploy on: - pull_request_review: - types: [submitted] - branches: [ "be" ] + pull_request: + types: + - closed defaults: run: working-directory: ./BE/exceed jobs: + if_merged: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - run: | + echo The PR was merged build: runs-on: ubuntu-22.04 permissions: @@ -36,6 +42,15 @@ jobs: - name: Build with Gradle Wrapper run: ./gradlew build + - name: PR Comment on Jacoco Report + id: jacoco + uses: madrapps/jacoco-report@v1.2 + with: + title: 테스트 커버리지 리포트입니다 + paths: ${{ github.workspace }}/backend/build/reports/jacoco/test/jacocoTestReport.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 30 + - name: Send docker-compose.yml uses: appleboy/scp-action@master with: diff --git a/BE/exceed/build.gradle b/BE/exceed/build.gradle index 0b9df426c..20482e85e 100644 --- a/BE/exceed/build.gradle +++ b/BE/exceed/build.gradle @@ -12,6 +12,7 @@ plugins { id "org.asciidoctor.jvm.convert" version "3.3.2" id "me.champeau.jmh" version "0.7.2" id 'com.diffplug.spotless' version '6.23.3' + id 'jacoco' } group = 'com.gaebaljip' @@ -192,4 +193,20 @@ spotless { // 파일 끝에 새로운 라인 추가 endWithNewline() } +} + +test { + finalizedBy jacocoTestReport +} + +jacoco { + toolVersion = "0.8.8" // 버전 명시 +} + +jacocoTestReport { + dependsOn test // 리포트 생성 전에 test를 반드시 수행해야 한다! + reports { // 어떤 파일들을 생성할지, 어디에 생성할지 설정 + xml.required = true // xml과 html형식으로 결과물을 만들어내라! + html.required = true + } } \ No newline at end of file diff --git a/BE/exceed/docker-compose.yml b/BE/exceed/docker-compose.yml index 0ad6e2df8..79d665cb8 100644 --- a/BE/exceed/docker-compose.yml +++ b/BE/exceed/docker-compose.yml @@ -48,12 +48,12 @@ services: networks: - gaebaljip-network restart: - on-failure + no grafana: image: grafana/grafana:latest container_name: grafana - restart: always + restart: no ports: - "3000:3000" volumes: @@ -70,7 +70,7 @@ services: prometheus: image: prom/prometheus:latest container_name: prometheus - restart: always + restart: no ports: - "9090:9090" volumes: diff --git a/BE/exceed/resources/gaebaljip-develop-environment/mariadb-init/01_schma.sql b/BE/exceed/resources/gaebaljip-develop-environment/mariadb-init/01_schema.sql similarity index 100% rename from BE/exceed/resources/gaebaljip-develop-environment/mariadb-init/01_schma.sql rename to BE/exceed/resources/gaebaljip-develop-environment/mariadb-init/01_schema.sql diff --git a/BE/exceed/resources/gaebaljip-local-environment/mariadb-init/01_schma.sql b/BE/exceed/resources/gaebaljip-local-environment/mariadb-init/01_schema.sql similarity index 100% rename from BE/exceed/resources/gaebaljip-local-environment/mariadb-init/01_schma.sql rename to BE/exceed/resources/gaebaljip-local-environment/mariadb-init/01_schema.sql diff --git a/BE/exceed/resources/gaebaljip-local-environment/setting.yml b/BE/exceed/resources/gaebaljip-local-environment/setting.yml index d2f327b45..838085f83 100644 --- a/BE/exceed/resources/gaebaljip-local-environment/setting.yml +++ b/BE/exceed/resources/gaebaljip-local-environment/setting.yml @@ -36,7 +36,7 @@ services: image: grafana/grafana:latest container_name: grafana user: "$UID:$GID" - restart: always + restart: no ports: - "3000:3000" volumes: @@ -51,7 +51,7 @@ services: prometheus: image: prom/prometheus:latest container_name: prometheus - restart: always + restart: no ports: - "9090:9090" volumes: diff --git a/BE/exceed/src/test/java/com/gaebaljip/exceed/common/ContainerTest.java b/BE/exceed/src/test/java/com/gaebaljip/exceed/common/ContainerTest.java index 9fa96ed58..2e4570ee1 100644 --- a/BE/exceed/src/test/java/com/gaebaljip/exceed/common/ContainerTest.java +++ b/BE/exceed/src/test/java/com/gaebaljip/exceed/common/ContainerTest.java @@ -1,18 +1,12 @@ package com.gaebaljip.exceed.common; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; -import org.springframework.test.context.jdbc.Sql; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.MariaDBContainer; -@Sql("classpath:db/testData.sql") @ActiveProfiles("test") -@ExtendWith(DatabaseClearExtension.class) -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public abstract class ContainerTest { static final String MARIA_DB_IMAGE = "mariadb:10.6"; static final MariaDBContainer Maria_DB_CONTAINER; diff --git a/BE/exceed/src/test/java/com/gaebaljip/exceed/common/IntegrationTest.java b/BE/exceed/src/test/java/com/gaebaljip/exceed/common/IntegrationTest.java index 2b43df4d3..367c44243 100644 --- a/BE/exceed/src/test/java/com/gaebaljip/exceed/common/IntegrationTest.java +++ b/BE/exceed/src/test/java/com/gaebaljip/exceed/common/IntegrationTest.java @@ -7,8 +7,10 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.restdocs.RestDocumentationContextProvider; import org.springframework.restdocs.RestDocumentationExtension; +import org.springframework.test.context.jdbc.Sql; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; @@ -18,6 +20,9 @@ @AutoConfigureMockMvc @ExtendWith(RestDocumentationExtension.class) +@ExtendWith(DatabaseClearExtension.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@Sql("classpath:db/testData.sql") public abstract class IntegrationTest extends ContainerTest { @Autowired protected MockMvc mockMvc; diff --git a/BE/exceed/src/test/java/com/gaebaljip/exceed/common/SchemaValidationTest.java b/BE/exceed/src/test/java/com/gaebaljip/exceed/common/SchemaValidationTest.java new file mode 100644 index 000000000..0ad9b43da --- /dev/null +++ b/BE/exceed/src/test/java/com/gaebaljip/exceed/common/SchemaValidationTest.java @@ -0,0 +1,95 @@ +package com.gaebaljip.exceed.common; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.utility.DockerImageName; + +import com.gaebaljip.exceed.config.QueryDslConfig; + +@DataJpaTest(properties = "spring.jpa.hibernate.ddl-auto=validate") +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@Import(QueryDslConfig.class) +public class SchemaValidationTest { + + private static MariaDBContainer schemaValidationMariaDB; + private static GenericContainer redisContainer; + + private static String getAbsolutePath() { + String relativePath = "resources/gaebaljip-develop-environment/mariadb-init/01_schema.sql"; + String currentDir = System.getProperty("user.dir"); + return Paths.get(currentDir, relativePath).normalize().toAbsolutePath().toString(); + } + + @BeforeAll + public static void setUp() throws IOException, SQLException { + String schemaFilePath = getAbsolutePath(); + + if (!Files.exists(Paths.get(schemaFilePath))) { + throw new IOException("해당 경로에 스키마 파일이 존재하지 않습니다. : " + schemaFilePath); + } + + schemaValidationMariaDB = new MariaDBContainer<>(DockerImageName.parse("mariadb:10.6")); + schemaValidationMariaDB.start(); + + redisContainer = + new GenericContainer<>(DockerImageName.parse("redis:6-alpine")) + .withExposedPorts(6379); + redisContainer.start(); + + runInitScript(schemaValidationMariaDB, schemaFilePath); + } + + private static void runInitScript(MariaDBContainer container, String scriptPath) + throws SQLException, IOException { + String script = new String(Files.readAllBytes(Paths.get(scriptPath))); + String[] commands = script.split(";"); + + try (Connection connection = container.createConnection(""); + Statement statement = connection.createStatement()) { + // Start from the second command + for (int i = 1; i < commands.length; i++) { + String command = commands[i].trim(); + if (!command.isEmpty()) { + statement.execute(command); + } + } + } + } + + @AfterAll + public static void tearDown() { + if (schemaValidationMariaDB != null) { + schemaValidationMariaDB.stop(); + } + if (redisContainer != null) { + redisContainer.stop(); + } + } + + @DynamicPropertySource + static void configureProperties(DynamicPropertyRegistry registry) { + registry.add("spring.datasource.url", () -> schemaValidationMariaDB.getJdbcUrl()); + registry.add("spring.datasource.username", () -> schemaValidationMariaDB.getUsername()); + registry.add("spring.datasource.password", () -> schemaValidationMariaDB.getPassword()); + registry.add("spring.redis.host", () -> redisContainer.getHost()); + registry.add("spring.redis.port", () -> redisContainer.getMappedPort(6379).toString()); + } + + @Test + public void testSchemaValidity() {} +}