Skip to content

Commit

Permalink
✨ [Feature] 테스트 환경 개선 및 CI 추가 (#379)
Browse files Browse the repository at this point in the history
  • Loading branch information
middlefitting authored Dec 13, 2023
1 parent 0d27b69 commit e86632f
Show file tree
Hide file tree
Showing 61 changed files with 493 additions and 163 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/test-code-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: 💻 Test code validation

on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: ️👶 Unit Test with Gradle
run: ./gradlew --console verbose clean unitTestCoverage
- name: mv for separate report folder
run: mv ./build/reports/jacoco/test ./build/reports/jacoco/unitTest
- name: mv for separate report name
run: mv ./build/reports/jacoco/unitTest/jacocoTestReport.xml ./build/reports/jacoco/unitTest/unitTestReport.xml
- name: 📲 Upload unitTest coverage to Codecov
uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
files: ./build/reports/jacoco/unitTest/unitTestReport.xml
flags: unitTest
name: codecov-unit
verbose: true
- name: 👨‍👨‍👧‍👦 Integration Test with Gradle
run: ./gradlew --console verbose clean integrationTestCoverage
- name: 📲 Upload integrationTest coverage to Codecov
uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
files: ./build/reports/jacoco/test/jacocoTestReport.xml
flags: integrationTest
name: codecov-integration
verbose: true
146 changes: 145 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'java'
id 'jacoco'
}

springBoot {
Expand Down Expand Up @@ -57,7 +58,7 @@ dependencies {
testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'

/* lombok */
implementation 'org.projectlombok:lombok:1.18.20'
implementation 'org.projectlombok:lombok:1.18.26'
annotationProcessor 'org.projectlombok:lombok'
compileOnly 'org.projectlombok:lombok'

Expand Down Expand Up @@ -100,7 +101,150 @@ dependencies {

//testcontainers 추가
testImplementation "org.testcontainers:mysql:1.19.3"
testImplementation "com.redis:testcontainers-redis:2.0.1"
testImplementation "org.junit.jupiter:junit-jupiter:5.8.1"
testImplementation "org.testcontainers:testcontainers:1.19.3"
testImplementation "org.testcontainers:junit-jupiter:1.19.3"
}

//테스트 커버리지 측정도구
jacoco {
toolVersion = "0.8.8"
}

// dto, 외부 연동 서비스는 테스트에서 제외
def jacocoExcludes = [
'*Application*',
"**/config/*",
"**/security/*",
"**/dto/*",
"**/aws/*",
"*NotiMailSender*",
'*SlackbotService*',
]

//커버리지 리포트 생성
jacocoTestReport {

reports {
xml.enabled true
html.enabled true
csv.enabled false
}

afterEvaluate {
//dto 및 외부 연동 서비스는 테스트에서 제외
classDirectories.setFrom(files(classDirectories.files.collect {
fileTree(dir: it, exclude: jacocoExcludes)})
)
}
}

// 커버리지 검증 설정
jacocoTestCoverageVerification {

violationRules {
rule {
enabled = true
element = 'CLASS'

//브랜치 커버리지
limit {
counter = 'BRANCH'
value = 'COVEREDRATIO'
minimum = 0.00
}

//메소드 커버리지
limit {
counter = 'METHOD'
value = 'COVEREDRATIO'
minimum = 0.00
}

//라인 커버리지
limit {
counter = 'LINE'
value = 'COVEREDRATIO'
minimum = 0.00
}

//검증에서 제외할 패키지, 클래스
excludes = jacocoExcludes
}
}
}

//전체 테스트
test {
description = 'Runs the total tests.'
useJUnitPlatform()
}

//유닛 테스트
task unitTest(type: Test) {
group = 'verification'
description = 'Runs the unit tests.'
useJUnitPlatform{
includeTags 'UnitTest'
excludeTags 'IntegrationTest'
}

jacoco {
destinationFile = file("$buildDir/jacoco/test.exec")
}

}

//통합 테스트
task integrationTest(type: Test) {
group = 'verification'
description = 'Runs the integration tests.'
useJUnitPlatform{
includeTags 'IntegrationTest'
excludeTags 'UnitTest'
}

jacoco {
destinationFile = file("$buildDir/jacoco/test.exec")
}
}

//전체 테스트, 리포트 생성, 검증
task totalTestCoverage(type: Test) {
group 'verification'
description 'Runs the total tests with coverage'

dependsOn(':test',
':jacocoTestReport',
':jacocoTestCoverageVerification')

tasks['jacocoTestReport'].mustRunAfter(tasks['test'])
tasks['jacocoTestCoverageVerification'].mustRunAfter(tasks['jacocoTestReport'])
}

//유닛 테스트, 리포트 생성, 검증
task unitTestCoverage(type: Test) {
group 'verification'
description 'Runs the unit tests with coverage'

dependsOn(':unitTest',
':jacocoTestReport',
':jacocoTestCoverageVerification')

tasks['jacocoTestReport'].mustRunAfter(tasks['unitTest'])
tasks['jacocoTestCoverageVerification'].mustRunAfter(tasks['jacocoTestReport'])
}

//통합 테스트, 리포트 생성, 검증
task integrationTestCoverage(type: Test) {
group 'verification'
description 'Runs the integration tests with coverage'

dependsOn(':integrationTest',
':jacocoTestReport',
':jacocoTestCoverageVerification')

tasks['jacocoTestReport'].mustRunAfter(tasks['integrationTest'])
tasks['jacocoTestCoverageVerification'].mustRunAfter(tasks['jacocoTestReport'])
}
18 changes: 18 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
coverage:
status:
project:
unit:
target: 5%
flags:
- unitTest
integration:
target: 60%
flags:
- integrationTest
flags:
unitTest:
paths:
- src/main/java/com/gg/server/
integrationTest:
paths:
- src/main/java/com/gg/server/
2 changes: 2 additions & 0 deletions lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@


import com.gg.server.global.security.cookie.CookieUtil;
import com.gg.server.global.utils.ApplicationYmlRead;
import com.nimbusds.oauth2.sdk.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
import org.springframework.stereotype.Repository;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Repository
@RequiredArgsConstructor
Expand Down
6 changes: 2 additions & 4 deletions src/test/java/com/gg/server/ServerApplicationTests.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package com.gg.server;

import com.gg.server.utils.annotation.IntegrationTest;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDateTime;
import java.util.TimeZone;

@SpringBootTest
@IntegrationTest
class ServerApplicationTests {

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gg.server.admin.announcement.data.AnnouncementAdminRepository;
import com.gg.server.utils.annotation.IntegrationTest;
import com.gg.server.global.security.jwt.utils.AuthTokenProvider;
import com.gg.server.utils.TestDataUtils;
import lombok.RequiredArgsConstructor;
Expand All @@ -10,15 +11,14 @@
import org.junit.jupiter.api.Test;
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.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RequiredArgsConstructor
@SpringBootTest
@IntegrationTest
@AutoConfigureMockMvc
@Transactional
public class AnnouncementAdminControllerFailTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.gg.server.admin.announcement.data.AnnouncementAdminRepository;
import com.gg.server.admin.announcement.dto.AnnouncementAdminAddDto;
import com.gg.server.admin.announcement.dto.AnnouncementAdminListResponseDto;
import com.gg.server.utils.annotation.IntegrationTest;
import com.gg.server.domain.announcement.data.Announcement;
import com.gg.server.domain.announcement.exception.AnnounceNotFoundException;
import com.gg.server.global.security.jwt.utils.AuthTokenProvider;
Expand All @@ -20,13 +21,12 @@
import org.junit.jupiter.api.Test;
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.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@SpringBootTest
@IntegrationTest
@AutoConfigureMockMvc
@Transactional
class AnnouncementAdminControllerTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gg.server.admin.coin.dto.CoinUpdateRequestDto;
import com.gg.server.utils.annotation.IntegrationTest;
import com.gg.server.domain.user.data.UserRepository;
import com.gg.server.global.security.jwt.utils.AuthTokenProvider;
import com.gg.server.utils.TestDataUtils;
Expand All @@ -12,7 +13,6 @@
import org.junit.jupiter.api.Test;
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.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -21,7 +21,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RequiredArgsConstructor
@SpringBootTest
@IntegrationTest
@AutoConfigureMockMvc
@Transactional
class CoinAdminControllerTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gg.server.admin.coin.data.CoinPolicyAdminRepository;
import com.gg.server.admin.coin.dto.CoinPolicyAdminAddDto;
import com.gg.server.utils.annotation.IntegrationTest;
import com.gg.server.global.security.jwt.utils.AuthTokenProvider;
import com.gg.server.utils.TestDataUtils;
import lombok.RequiredArgsConstructor;
Expand All @@ -11,7 +12,6 @@
import org.junit.jupiter.api.Test;
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.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -20,7 +20,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RequiredArgsConstructor
@SpringBootTest
@IntegrationTest
@AutoConfigureMockMvc
@Transactional
public class CoinPolicyAdminControllerFailTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.gg.server.admin.coin.data.CoinPolicyAdminRepository;
import com.gg.server.admin.coin.dto.CoinPolicyAdminAddDto;
import com.gg.server.admin.coin.dto.CoinPolicyAdminListResponseDto;
import com.gg.server.utils.annotation.IntegrationTest;
import com.gg.server.domain.coin.data.CoinPolicy;
import com.gg.server.domain.coin.exception.CoinPolicyNotFoundException;
import com.gg.server.domain.user.data.User;
Expand All @@ -21,13 +22,12 @@
import org.junit.jupiter.api.Test;
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.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@SpringBootTest
@IntegrationTest
@AutoConfigureMockMvc
@Transactional
class CoinPolicyAdminControllerTest {
Expand Down
Loading

0 comments on commit e86632f

Please sign in to comment.