diff --git a/.github/workflows/test_coverage.yml b/.github/workflows/test_coverage.yml new file mode 100644 index 0000000..70916cc --- /dev/null +++ b/.github/workflows/test_coverage.yml @@ -0,0 +1,65 @@ +name: Test Coverage Validation + +on: + pull_request: + types: + [ opened, synchronize, reopened ] + +jobs: + Build-And-Test: + runs-on: ubuntu-latest + + steps: + - name: Github Repository 파일 불러오기 + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Setup Docker + uses: docker/setup-buildx-action@v3 + + - name: JDK 버전 21 설치 + uses: actions/setup-java@v5 + with: + distribution: corretto + java-version: 21 + + - name: Gradle Wrapper 실행 권한 부여 + run: chmod +x ./gradlew + + - name: 전체 빌드 및 테스트 + run: ./gradlew --info test + + - name: JaCoCo 커버리지 리포트 생성 + id: jacoco_report + uses: madrapps/jacoco-report@v1.7.2 + with: + paths: ${{ github.workspace }}/build/reports/jacoco/test/jacocoTestReport.xml + token: ${{ secrets.GITHUB_TOKEN }} + min-coverage-overall: 70 + min-coverage-changed-files: 70 + title: "🧪 테스트 커버리지 리포트" + update-comment: true + + - name: Close PR, if build fail + if: ${{ failure() }} + uses: actions/github-script@v8 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const pull_number = ${{ github.event.pull_request.number }} + const updated_title = `[VALIDATION FAIL] ${{ github.event.pull_request.title }}` + await github.rest.pulls.createReview({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: pull_number, + body: '빌드 또는 테스트 커버리지 검증에 실패했습니다.', + event: 'REQUEST_CHANGES' + }) + await github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: pull_number, + title: updated_title, + state: 'closed' + }) diff --git a/build.gradle b/build.gradle index 119c878..1f0eec0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java' + id 'jacoco' id 'org.springframework.boot' version '3.5.9' id 'io.spring.dependency-management' version '1.1.7' } @@ -34,10 +35,41 @@ dependencies { annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testRuntimeOnly 'com.h2database:h2' testImplementation 'io.rest-assured:rest-assured' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } tasks.named('test') { useJUnitPlatform() + finalizedBy jacocoTestReport } + +jacoco { + toolVersion = "0.8.14" +} + +jacocoTestReport { + reports { + html.required = true + xml.required = true + csv.required = true + } + + afterEvaluate { + classDirectories.setFrom(files(classDirectories.files.collect { + fileTree(dir: it, exclude: [ + "**/*Application*", + "**/common/**", + "**/exception/**", + "**/request/**", + "**/response/**", + "**/input/**", + "**/output/**", + "**/dto/**" + ]) + })) + } + dependsOn test +} + diff --git a/src/test/resources/application.yaml b/src/test/resources/application.yaml new file mode 100644 index 0000000..663411b --- /dev/null +++ b/src/test/resources/application.yaml @@ -0,0 +1,27 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL + driver-class-name: org.h2.Driver + username: sa + password: + + jpa: + hibernate: + ddl-auto: create-drop + properties: + hibernate: + format_sql: true + dialect: org.hibernate.dialect.H2Dialect + + mail: + host: localhost + port: 3025 + properties: + mail: + smtp: + auth: false + starttls: + enable: false + +auth: + base-url: http://localhost:8080