CI/CD 파이프라인

CI/CD 파이프라인이 무엇인지는 아래 게시글에서 확인할 수 있다.

https://dratini.tistory.com/entry/DevOps-CICD-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8

[[DevOps] CI/CD 파이프라인

CI/CD 파이프라인은 소프트웨어 개발 프로세스에서 개발, 테스트 및 배포를 자동화하기 위한 과정을 말한다. 이 파이프라인은 개발자들이 소프트웨어 개발에 대한 변경 사항을 더욱 쉽고 빠르게

dratini.tistory.com](https://dratini.tistory.com/entry/DevOps-CICD-%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8)

이번엔 실제로 사용되는 CI/CD를 위한 툴들을 소개한다.

CI Tools


Jenkins

Wikipedia에 따르면 Jenkins는 다음과 같이 설명할 수 있습니다.

Jenkins는 오픈소스 자동화 서버입니다. 빌드, 테스트, 배포와 같은 소프트웨어 개발의 일부분을 자동화하는 데 도움을 주며, 지속적 통합과 지속적 배포를 돕습니다. 서버 기반의 시스템이며... (중략) ... Git과 같은 버전 관리 시스템을 지원합니다. 또한 쉘 스크립트를 실행할 수 있습니다.

https://www.jenkins.io/

 

Jenkins

Meet with Jenkins Community at cdCon + GitOpsCon 2023 The Continuous Delivery Foundation (CDF) is happy to host its fourth flagship event, cdCon, taking place on May 8–9, 2023 in Vancouver, Canada as cdCon + GitOpsCon, co-organized with the Cloud Native

www.jenkins.io

www.jenkins.io](https://www.jenkins.io/)

특징

  • 설치형: 별도의 서버가 필요합니다.
  • 다양한 플러그인을 활용할 수 있습니다.
  • 쿠버네티스, Docker 등과 호환됩니다.
  • 다양한 운영체제에서 사용이 가능합니다.

Travis CI

Wikipedia에 따르면 Travis CI는 다음과 같이 설명할 수 있습니다.

Travis CI는 호스트형(hosted) 배포 자동화 서비스로, GitHub 및 Bitbucket 등에서 호스팅되는 소프트웨어 프로젝트를 빌드하고 테스트하는 데 사용됩니다.

https://www.travis-ci.com/

 

Home – Travis-CI

Simple YAML configs

www.travis-ci.com

www.travis-ci.com](https://www.travis-ci.com/)

특징

  • 클라우드 서비스(SasS) 형태로 사용할 수 있습니다.
  • Travis 자체에서 호스팅을 해주기 때문에 관리적인 측면에서 편리합니다.
  • Clojure, Erlang, Groovy Haskell, Java, JavaScirpt, Node.js, Perl PHP, Rython, Ruby 등의 다양한 언어를 지원합니다.

GitHub Action

특징

  • GitHub 저장소를 기반으로 소프트웨어 개발 Workflow를 자동화할 수 있는 툴입니다.
  • GitHub 마켓 플레이스를 통해 여러 사람이 공유한 Workflow를 찾을 수 있으며, 자신이 직접 만들어 공유할 수도 있습니다.
  • 공개 저장소를 무료로 사용할 수 있으며, 비공개 저장소 같은 경우 무료 사용량 이후에 요금이 부과됩니다.
    • 한 달에 500MB 스토리지와 실행 시간 2,000분(minute)까지 제공됩니다.
  • GitHub Actions는 GitHub 리포지토리와 완벽하게 통합되어 있어, 별도의 서드파티 도구를 사용하지 않고도 CI/CD 파이프라인을 구축할 수 있습니다. 이로 인해, 설정 및 관리가 간편해지며 개발 프로세스가 더욱 통합됩니다.
  • Github Actions 레퍼런스: Learn GitHub Actions - GitHub Docs

https://github.com/features/actions

 

Features • GitHub Actions

Easily build, package, release, update, and deploy your project in any language—on GitHub or any external system—without having to run code yourself.

github.com

github.com](https://github.com/features/actions)


지속적 통합

소프트웨어 개발 분야의 설계 및 개발 방법론에 있어서 저명한 마틴 파울러는 지속적 통합에 대해 다음과 같이 정의합니다.

팀 구성원이 각자의 작업을 자주 통합하는 소프트웨어 개발 방식 - Martin Fowler

이 방법을 도입함으로써 얻을 수 있는 장점에 대해서는 앞서 다음과 같이 설명했습니다.

  • 버그를 일찍 발견할 수 있다. → 문제 조기 식별 가능
  • 빌드 및 테스트와 같이 사람이 해야 할 일들을 자동화할 수 있다. → 업무량 감소
  • 테스트가 완료된 코드에 대해 빠른 전달이 가능하다. → 업무 효율 증가
  • 지속적인 배포가 가능해진다. → 업무 안정성 증가
  • 개발자의 생산성을 향상할 수 있다. → 업무 효율 증가

지속적 통합 원칙

  1. 단일 소스 레파지토리를 유지해야 합니다.
    • 프로젝트에서 제품을 빌드하기 위해 함께 조정해야 하는 수많은 파일이 포함되기 때문에 추적하기 편하게 만들 기 위해서라도 단일 소스 레파지토리 구조를 유지해야합니다.
  2. 빌드를 자동화해야 합니다.
    • 사람들에게 이상한 명령을 입력하게 하거나 대화 상자를 클릭하게 하는 것은 시간 낭비입니다.
    • 빌드가 수동으로 진행된다면, 수많은 실수를 낳을 수 있습니다.
  3. 셀프 테스팅 빌드를 만들어야 합니다.
    • 빌드 프로세스에 자동화된 테스트를 포함 함으로써 버그를 더 빠르고 효율적으로 파악할 수 있습니다.
    • 지속적 통합의 일부인 테스트 주도 개발(TDD)을 통해 손상된 빌드를 즉시 확인, 수정할 수 있습니다.
  4. 매일 메인라인에 커밋을 해야 합니다.
    • 각자의 진행 상황을 추적하는 데 도움이 됩니다.
    • 짧은 주기로 커밋을 하므로, 충돌이 발생한 후 빠르게 충돌 상황을 감지할 수 있습니다.
      • 해당 시점에는 충돌이 많이 발생하지 않아 문제를 쉽게 해결할 수 있습니다.
      • 만약 통합의 빈도가 길어 충돌을 늦게 발견하게 된다면 문제를 해결하기 매우 어려울 수 있습니다.
  5. 메인라인: 시스템의 현재 상태를 의미합니다. 회사마다 어떤 브랜치를 메인라인으로 두는지는 조금씩 다르지만, 여기서는 master 브랜치를 메인라인으로 취급하도록 하겠습니다.
  6. 모든 팀원이 무슨 일이 일어나고 있는지 알아야 합니다.
    • 지속적 통합은 커뮤니케이션에 관한 것이므로 모든 사람이 시스템 상태와 시스템에 적용된 변경 사항을 쉽고 명확하게 확인할 수 있어야 합니다.

이 외에도 많은 원칙들이 있다. 해당 내용들은 아래 링크에서 확인할 수 있다.

https://www.martinfowler.com/articles/continuousIntegration.html

[Continuous Integration

Every developer integrates their work into mainline at least every day.

martinfowler.com](https://www.martinfowler.com/articles/continuousIntegration.html)


지속적 통합에서 테스트가 중요한 이유

테스트를 통해 결함과 버그를 조기에 발견할 수 있으며, 이는 개발자의 생산성을 향상할 수 있습니다.

제품의 결함과 버그를 발견하고 수정하는 것은 소프트웨어의 품질을 보증하고, 더 안정적이고 사용하기 쉽게 만듭니다.


테스트 주도 개발 (Test Driven Development, TDD)

테스트 주도 개발이란 테스트가 기능의 디자인을 주도하는 반복적인 개발 방법론을 뜻합니다.

테스트 주도 개발의 필요성을 알기 위해선 TDD 이전의 개발 방식에 대해 학습할 필요가 있습니다.


기존 개발과정

기존의 개발 프로세스는 아래와 같습니다.

  1. 요구사항 분석
  2. 요구 사항을 토대로 디자인(설계)을 진행
  3. 설계에 맞추어 기능을 개발.
  4. 구현 완료 후 수동으로 기능을 테스트
  5. 원하는 대로 동작하지 않거나 문제가 발생하면 디버깅을 통해 원인을 파악하고 수정
  6. 3 - 4의 과정을 개발이 완료될 때까지 반복

기존 개발과정의 문제점

수동 테스트와 디버깅: 기능 개발 완료 후 수동으로 테스트하고 디버깅을 통해 원인을 파악하고 수정하는 과정이 시간이 많이 소요되었습니다. 그래서 개발 및 배포 속도가 느려지고, 프로젝트 전반에 걸친 효율성이 저하되었습니다.

통합 문제: 개별적으로 개발된 코드들을 일정 시점에 통합하는 과정에서 발생하는 문제점들이 있었습니다. 이러한 통합 과정에서 호환성 문제나 버그가 발생하기 쉬워, 추가적인 디버깅과 수정 작업이 필요했습니다.

협업의 어려움: 팀 간의 협업이 제한적이어서, 코드 통합 과정에서 문제가 발생할 확률이 높았습니다.

높은 유지보수 비용: 코드의 변경이나 수정이 빈번하게 발생할 때마다 수동으로 테스트를 수행하고 디버깅을 해야 하므로 유지보수 비용이 높습니다. 이는 개발 비용과 시간을 증가시키는 요인이 됩니다.


테스트 주도 개발 과정

기존의 개발 프로세스를 보완하기 위해 태어난 테스트 주도 개발(TDD)의 프로세스는 아래와 같습니다.

  1. 요구사항 분석
  2. 요구 사항을 토대로 디자인(설계)을 진행
  3. 설계를 기반으로 기능 테스트 진행
    1. 실패 시 다시 설계
  4. 테스트가 성공했다면 개발 진행
  5. 3 - 4의 과정을 개발이 완료될 때까지 반복

기존 개발환경에서 개선된 점

설계 → 개발 → 테스트로 이어지던 기존의 개발 프로세스를 설계 → 테스트 → 개발의 프로세스로 변경하여 버그를 조기에 발견하고 해결할 수 있게 되었습니다.

TDD의 설계 → 테스트 → 개발의 프로세스는 변경 점에 따라 테스트를 진행해야 하는 상황에 대한 부담을 줄여 주었습니다.


테스트 주도 개발 사이클

TDD의 테스트는 큰 단위의 문제를 작은 단위로 나누어, 지속적인 피드백을 통해 목표를 개선해 나가는 방향으로 진행됩니다.


테스트 주도 개발의 장점

  1. 더욱 명확한 기능과 구조를 설계할 수 있습니다.
  2. 재사용성이 고려된, 모듈화된 코드를 작성할 수 있습니다.
  3. 설계 수정 시간과 디버깅 시간의 단축
    1. 단위 테스트 기반의 테스트 코드를 작성하기 때문에 추후 프로그램에 문제가 발생할 경우, 각각의 모듈별로 테스트를 진행하면서 문제 지점을 쉽게 찾아낼 수 있습니다.
  4. 완성도 높은 설계
    1. 코드의 기능, 정의 등 구조적인 문제에 대하여 명확하게 접근할 수 있으며 다양한 예외상황에 대해서도 고려하게 되므로 이는 완성도 높은 설계로 이어집니다.
  5. 유지 보수의 용이성
    1. 프로젝트에 어떤 기능을 추가하는 등의 유지 보수를 해야 하는 상황이라면 항상 기존 코드들에 끼칠 영향에 대해 생각해야 합니다.
    2. TDD 이전의 개발 방식에선 단순한 기능이라도 수정되거나, 추가되는 경우에는 많은 코드에 대하여 테스트를 진행해야 했으나, TDD를 진행한다면 변경 점에 따른 테스트를 진행해야 하는 상황에 대한 부담이 줄어들 수 있습니다.

테스트의 종류

TDD에 활용할 수 있는 테스트의 종류에 대해 알아봅니다. 단위 테스트와, 통합 테스트 그리고 E2E 테스트에 대해 알아봅니다.


단위 테스트

말 그대로 작은 단위의 테스트입니다.
검증이 필요한 코드에 대해 테스트 케이스를 작성하는 과정을 말합니다.
유닛 테스트의 장점으로는 즉각적인 피드백이 나오는 것을 들 수 있습니다. 다만, 하나의 메서드가 잘 작동함은 보장할 수 있지만 그들이 결합하는 시점에서도 잘 작동하는지에 대해서는 보장할 수 없기 때문에 염두에 두어야 합니다.

통합 테스트

모듈을 통합하는 과정에서 모듈 간 호환성의 문제를 찾아내기 위해 수행되는 테스트입니다.

그래서 단위 테스트에서 찾지 못하는 통합 시 발생하는 버그 등을 찾을 수 있습니다.


단위 테스트 및 통합 테스트 시 사용하는 도구

  • mocha, chai (JavaScript)
  • JUnit (Java)

E2E 테스트 (End To End Test)

전체 시스템이 제대로 동작하는지 확인하기 위한 테스트입니다.
그래서 사용자의 입장에서 사용자가 사용하는 상황을 가정하고 시뮬레이션을 진행합니다.

장점

실제 상황에서 발생할 수 있는 에러를 미리 발견할 수 있다.

단점

테스트 작성 시 들어가는 비용이 너무 많습니다.
수행 속도가 느립니다.
"실패했다"라는 결과만 있기 때문에 피드백의 질이 낮습니다.

 

E2E 테스트에 대해 더 공부하고 싶다면 아래 링크를 통해 공부하는 것도 좋다.

https://youtu.be/wycIcpuLkzU

https://stackify.com/3-best-practices-for-end-to-end-testing/

 


통합 테스트와 E2E 테스트의 차이

항목 통합 테스트 (Integration Testing) 종단간 테스트 (End-to-End Testing)
방식 앱 구성 요소들이 함께 잘 작동하는지 확인한다. 사용자 경험을 통해 제품을 테스트함.
범위 여러 구성 요소를 포함할 수 있지만 대부분 전체 스택은 아님. 테스트 범위가 넓고 전체 애플리케이션 기술 스택을 포함함.
목적 구성 요소들이 함께 작동할 때 연결 문제 발견을 위함. 앱의 사용자 경험을 확인하기 위함.
구현 비용 비교적 저렴함. 하드웨어와 소프트웨어 측면에서 구현 비용이 더 많이 듦.
테스트 수준 단위 테스트보다 상위 수준. 통합 테스트보다 상위 수준.
수행 속도 빠름. 느림.

 

표에서 통합 테스트와 종단간 테스트 각각의 목적, 범위, 이유, 구현 비용, 테스트 수준 및 수행 속도에 대한 차이를 확인할 수 있습니다.

+ Recent posts