기초
1. 깃허브 레포지토리를 생성한다. 레포지토리를 private로 설정하고, gitignore을 Gradle로 설정한다.
2. ssh 키를 생성해야 한다. 운영체제가 윈도우라서 git bash에서 아래 명령어를 실행했다.
ssh-keygen
아래 명령을 실행하여 나온 값을 모두 복사한다.
cat ~/.ssh/id_rsa.pub
깃허브에 사용자 설정에서 SSH and GPG keys에서 New SSH key를 클릭한다.
그리고 아래의 화면에서 Key에 아까 복사한 값을 붙여넣는다.
3. 로컬 레포지토리를 생성한다.
아래 명령을 실행하여 일단 ssh 프로토콜로 깃허브 접속이 가능한지 확인한다.
ssh -T git@github.com
아래 사진처럼 레포지토리의 링크를 복사하여 터미널에서 클론 한다.
git clone git@github.com:ncherryu/calculator.git
4. https://start.spring.io에 접속하여 스프링 부트 프로젝트를 생성한다.
5. 로컬에서 빌드를 하기 위해 JDK를 설치한다.
https://www.oracle.com/kr/java/technologies/downloads/#java17에 접속하여 운영체제에 맞게 JDK를 다운로드한다.
6. 4에서 생성한 프로젝트를 압축을 풀고, 해당 폴더에 들어가서 빌드를 진행한다.
윈도우에서는 다음 명령을 입력한다.
gradlew build
7. 젠킨스에 접속하여 stage view라는 플러그인을 설치한다.
8. 젠킨스의 설정 - credentials에서 credential을 생성한다.
private key에는 2에서 생성한 비밀키를 입력한다. id_rsa.pub이 아니라 id_rsa에 있는 내용을 입력해야 한다.
9. 젠킨스 설정에서 Tools에 들어가면 JDK installations가 있다. 다음과 같이 설정한다.
10. 젠킨스 아이템을 Pipeline 타입으로 생성하여 Pipeline script에 다음과 같이 입력하고, 빌드를 진행한다.
pipeline {
agent {
kubernetes {
yaml'''
apiVersion: v1
kind: Pod
spec:
containers:
-name: jnlp
image: jenkins/inbound-agent
'''
}
}
tools {
jdk 'default-jdk'
}
stages {
stage("Checkout") {
steps {
git url: 'git@github.com:ncherryu/calculator.git',
branch: 'main',
credentialsId: 'github-credentials'
}
}
stage("Compile") {
steps {
sh "./gradlew compileJava"
}
}
}
}
11. 커스텀 에이전트를 구성한다.
Dockerfile을 다음과 같이 작성한다.
From ubuntu:22.04
RUN apt update
RUN apt install -y openjdk-17-jdk
터미널에서 다음 명령어를 수행한다.
docker build -t ncherryu/jenkins-agent-jdk-17
docker push ncherryu/jenkins-agent-jdk-17
pipeline script의 yaml의 spec 부분을 다음과 같이 수정한다.
spec:
containers:
-name: builder
images: ncherryu/jenkins-agent-jdk-17
command:
- cat
tty: true
Compile stage를 다음과 같이 수정하여 빌드를 진행한다.
stage("Compile") {
steps {
script {
container('builder') {
sh "./gradlew compileJava"
}
}
}
}
이미 jdk를 설치해놓은 이미지를 사용하여 빌드를 진행했기 때문에 Tool installation 과정이 없다.
단위 테스트
기본 파일 생성
1. Calculator.java 파일을 생성한다.
package.com.example.calculator;
import org.springframework.stereotype.Service;
@Service
public class Calculator {
public int sum(int a, int b) {
return a + b;
}
}
2. CalculatorController.java 파일을 생성한다.
/sum으로 들어오는 요청의 query string으로 주어지는 두 인자를 합한 결과를 문자열로 만들어 반환한다.
package.com.example.calculator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
class CalculatorController {
@Autowired
private Calculator calculator;
@ReqeustMapping("/sum")
String sum(@RequestParam("a") Integer a, @RequestParam("b") Integer b) {
return String.valueOf(calculator.sum(a, b));
}
3. 서버를 실행한다.
젠킨스가 8080에서 작동되고 있기 때문에 8888로 지정해준다.
gradlew bootRun --args="--server.port=8888"
4. 웹브라우저에서 다음의 url에 접속하면 화면에 9가 나타나는 것을 확인할 수 있다.
localhost:8888/sum?a=6&b=3
단위 테스트 작성
1. CalculatorTest.java 파일을 생성한다.
package.com.example.calculator;
import org.junit.Text;
import static org.junit.Assert.assertEquals;
public class CalculatorTest {
private Calculator calculator = new Calculator();
@Test
public void testSum() {
assertEquals(5, calculator.sum(2, 3));
}
}
2. build.gradle 파일에 dependencies 블록에 다음 내용을 추가한다.
testImplementation 'junit:junit:4.13'
testRuntimeOnly('org.junit.vintage:junit-vintage-engine')
3. build.gradle 파일에 다음 내용을 추가한다.
tasks.named('test') {
useJUnitPlatform()
}
4. 터미널에서 다음 명령어를 입력하여 테스트를 진행한다.
gradlew test
5. 작성했던 파일들을 깃허브에 올리고, pipeline script에 다음을 추가하고, 빌드한다.
stage("Unit Test") {
steps {
script {
container('builder') {
sh "./gradlew test"
}
}
}
}
6. 테스트 리포트는 pipeline script의 Unit Test 부분을 다음과 같이 수정하여 발행할 수 있다.
stage("Unit Test") {
steps {
script {
container('builder') {
sh "./gradlew test"
publishHTML(target: [
reportDir: 'build/reports/tests/test',
reportFiles: 'index.html',
reportName: 'JUnit Report'
])
}
}
}
}
코드 품질 확보
실행하기 전에 정의할 수 있는 코드 품질은 두 가지가 있다.
- 단위 테스트가 잘 마련되어 있는 코드는 테스트 커버리지로 측정한다.
- 규칙을 잘 따르는 코드는 컨벤션 준수 정도로 측정한다.
테스트 커버리지는 JaCoCo를 이용한다. 로컬 환경에서 Gradle 설정 후 테스트를 진행하며, 젠킨스 파이프라인 스테이지로 추가한다.
코딩 규약 준수 정도를 분석하는 데는 Checkstyle을 이용한다. 마찬가지로 로컬 환경에서 Gradle 설정 후 테스트를 진행하며, 젠킨스 파이프라인 스테이지로 추가한다.
테스트 커버리지 분석
1. build.gradle 파일에서 plugins에 아래 내용을 추가한다.
id 'jacoco'
2. build.gradle 파일에서 최하단에 아래 내용을 추가한다.
jacocoTestCoverageVerification {
violationRules {
rule {
limit {
minimum = 0.2
}
}
}
}
3. 터미널에서 다음 명령을 입력하면 테스트 결과를 확인할 수 있다.
gradle test jacocoTestCoverageVerification
4. 리포트 발행은 다음 명령어를 실행하여 작성할 수 있다.
gradlew test jacocoTestReport
5. 젠킨스에서 코드 커버리지 스테이지를 추가한다.
stage("Code Coverage") {
steps {
script {
container('builder') {
sh "./gradlew jacocoTestReport"
publishHTML(target: [
reportDir: 'build/reports/jacoco/test/html',
reportFiles: 'index.html',
reportName: 'JaCoCo Report'
])
sh "./gradlew jacocoTestCoverageVerification"
}
}
}
}
Checkstyle
1. https://github.com/naver/hackday-conventions-java/tree/master/rule-config 에서 아래 두 개의 파일을 다운로드한다.
- naver-checkstyle-rules.xml
- naver-checkstyle=suppressions.xml
2. 1에서 다운로드한 파일을 디렉토리를 만들어서 config/checkstyle 안에 배치한다.
3. build.gradle 파일의 plugin에 다음의 내용을 추가한다.
id 'checkstyle'
4. 터미널에서 다음 명령을 입력하면 테스트가 실행되어 테스트 결과가 출력된다.
gradlew test
5. 지금까지의 파일을 모두 깃허브에 push 한다.
6. 젠킨스의 pipeline script에 빌드(Compile) 스테이지 뒤에 다음 내용의 스테이지를 추가한 후에 빌드한다.
stage("Unit Test") {
steps {
script {
container('builder') {
sh "./gradlew test"
}
}
}
}
배운 점
- 깃허브에 있는 프로젝트로 CI 파이프라인을 진행하는 방법을 배웠다.
- Unit Test를 하는 방법과 리포트를 발행하는 방법을 배웠다.
- 테스트 커버리지와 Checkstyle을 사용하는 방법에 대해 알게 되었다.
'데브코스' 카테고리의 다른 글
[17주차 - DAY3] 인수 테스트 정리 (0) | 2024.06.19 |
---|---|
[17주차 - DAY3] 인수 테스트 (1) | 2024.06.19 |
[17주차 - DAY1] 쿠버네티스 사용 방법 정리 (0) | 2024.06.17 |
[17주차 - DAY1] 쿠버네티스, 젠킨스 (0) | 2024.06.17 |
[16주차 - DAY4] 도커 이미지 생성 (1) | 2024.06.13 |