IT STUDY LOG

[지속적 통합] 03. 테스트 본문

devops bootcamp 4/클라우드 서비스 운영

[지속적 통합] 03. 테스트

roheerumi 2023. 4. 20. 12:08

# 학습 목표

  • 지속적 통합의 필요성을 설명할 수 있다.
    • 지속적 통합 개념이 나오게 된 배경을 이해할 수 있다.
    • 지속적 통합의 장점을 설명할 수 있다.
    • 지속적 통합의 원칙을 이해할 수 있다.
  • 빌드/테스트의 개념을 이해할 수 있다.
    • 테스트 주도 개발(TDD)에 대한 정의와 필요성을 설명할 수 있다.
    • 테스트 주도 개발(TDD) 사이클을 설명할 수 있다.
    • 테스트의 종류 (단위 테스트, 통합 테스트, E2E 테스트)를 설명할 수 있다.
  • 릴리스의 개념을 이해할 수 있다.
  • CI 도구(여기서는 GitHub Action)를 이용하여 지속적 통합이 이루어지는 과정을 직접 구현할 수 있다
  • 다양한 CI 도구의 차이점을 이해할 수 있다.
  • 코드와 환경 변수를 분리해야 하는 이유를 설명할 수 있다.

 


# 학습 내용

1.  테스트 주도 개발

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

-  테스트가 기능의 디자인을 주도하는 반복적인 개발 방법론
 

기존의 개발 과정

출처 : 코드스테이츠 데브옵스 부트캠프 과정

기존의 개발 프로세스

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

 

기존 개발 프로세스의 문제점

불안정한 릴리스

- 기존의 개발 프로세스에서는 릴리스 주기가 길어서 신규 기능을 출시하기까지 오랜 시간이 소요되었고, 이로 인해 릴리스가 불안정한 경우가 많음

통합 과정의 복잡성

- 개발자들이 개발한 코드를 통합하는 과정에서 충돌이 발생하기도 했고, 이를 해결하기 위해 많은 노력이 필요했음

수동적인 테스트

- 기존의 개발 프로세스에서는 테스트가 수동적으로 이루어졌기 때문에 시간과 비용이 많이 소요
- 테스트가 불완전하여 버그가 발견되기 어려움

환경 일치 문제

- 각 개발자가 개발 환경을 독립적으로 구성하다보니, 각각 다른 버전의 소프트웨어를 사용하고 있어 문제가 발생

적극적인 배포 불가

- 기존의 개발 프로세스에서는 릴리스 주기가 길어서 새로운 기능이나 버그 수정 사항이 릴리스되기까지 오랜 시간이 소요됨
- 이로 인해 사용자들의 요구사항에 대응하기 어려움

작업의 불필요한 중복

- 개발자들은 서로 다른 기능을 담당하면서도 동일한 작업을 반복하는 경우가 많음
- 개발자들의 시간과 노력이 낭비
 

테스트 주도 개발 과정

출처 : 코드스테이츠 데브옵스 부트캠프 과정

테스트 주도 개발(TDD)의 프로세스

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

 

TDD이 해결해준 기존 개발 프로세스의 문제점

- 기존 개발 프로세스 : 설계 → 개발 → 테스트
- TDD 개발 프로세스 : 설계 → 테스트 → 개발
∴ 버그를 조기에 발견하고 해결 가능
- TDD의 설계 → 테스트 → 개발의 프로세스는 변경 점에 따라 테스트를 진행해야 하는 상황에 대한 부담 감소
 

테스트 주도 개발 사이클

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

출처 : 코드스테이츠 데브옵스 부트캠프 과정

 

테스트 주도 개발의 장점

더욱 명확한 기능과 구조를 설계할 수 있음
재사용성이 고려된, 모듈화된 코드를 작성할 수 있음
설계 수정 시간과 디버깅 시간의 단축

- 단위 테스트 기반의 테스트 코드를 작성하기 때문에 추후 프로그램에 문제가 발생할 경우, 각각의 모듈별로 테스트를 진행하면서 문제 지점을 쉽게 찾아낼 수 있음

완성도 높은 설계

- 코드의 기능, 정의 등 구조적인 문제에 대하여 명확하게 접근할 수 있으며 다양한 예외상황에 대해서도 고려하게 되므로 이는 완성도 높은 설계 가능

유지 보수의 용이성

- 프로젝트에 어떤 기능을 추가하는 등의 유지 보수를 해야 하는 상황이라면 항상 기존 코드들에 끼칠 영향에 대해 생각해야 함
- TDD 이전의 개발 방식에선 단순한 기능이라도 수정되거나, 추가되는 경우에는 많은 코드에 대하여 테스트를 진행해야 했으나, TDD를 진행한다면 변경 점에 따른 테스트를 진행해야 하는 상황에 대한 부담이 줄어들 수 있음
 

2. TDD에 활용할 수 있는 테스트의 종류

단위 테스트

- 작은 단위의 테스트
- 검증이 필요한 코드에 대해 테스트 케이스를 작성하는 절차 혹은 프로세스
- 유닛 테스트의 장점으로는 즉각적인 피드백이 가능하다는 점이나, 하나의 메서드가 정상 작동하는 여부는 보장할 수 있으나 모듈을 통합했을 때 작동할 수 있는지는 보장 불가
 

단위 테스트 예시

// 만일 sum(x, y) 와 같이 두 숫자를 더하는 함수를 테스트하려면,

it('sum에 두 수를 인자로 입력하면, 두 수의 합이 리턴됩니다', () => {
  expect(sum(1,1)).to.be.equal(2)    // sum(1,1)의 리턴값은 2가 될 것이라고 기대한다
  expect(sum(100, 200)).to.be.equal(300)
})

 

통합 테스트

- 모듈을 통합하는 과정에서 모듈 간 호환성 문제를 찾기 위해 수행하는 테스트
- 단위 테스트에서 찾지 못하는 통합 시 발생하는 버그를 발견 가능

 
단위 테스트 예시

// 서버에 API 요청을 보냈을 때, 정확한 응답이 오리라고 기대하는 경우
// 아래의 코드가 백엔드 입장에서는 단순 유닛 테스트라고 볼 수도 있지만
// 서버와 클라이언트 코드가 별도로 작성되어 있고, 서버-클라이언트의 통합을 테스트해야 한다면, 이는 통합 테스트

it('서버에 POST /upper 요청에 body를 실어 보내면 응답은 대문자', () => {
  return request(API서버)
    .post('/upper')
    .send('"coDeStaTes"')
    .set('Content-Type', 'application/json')
    .then(res => {
      expect(res.body).to.be.equal('CODESTATES')
    })
})

 

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

  • mocah, chai (Javascript)
  • JUnit (Java)

 

E2E 테스트 (End To End Test)

- 전체 시스템이 제대로 동작하기 위한 테스트
- 사용자 입장에서 사용자가 사용하는 상황을 가정하고 시뮬레이션 진행

 

장점

- 실제 상황에서 발생하는 에러를 사전 발견 가능

 

단점

- 테스트 작성 시 투입되는 비용이 고비용
- 수행 속도 느림
- 실패했다는 결과만 존재하므로 피드백 질이 낮음

 

E2E 테스트 시 사용하는 도구

  • Cypress
  • Nightwatch
  • TestCafe

 
E2E 테스트 예시

 

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

Integration TestingEnd-to-End Testing
Testing to make sure app components work well together.Testing the product as a user would experience it.
The scope could span multiple components but won’t span the entire stack most of the time.Testing scope is wider and spans the entire application technology stack.
Done to discover connectivity issues between components when they are working together.Done to have a feel of the user experience of the app.
Less expensive to implement.More expensive to implement, both in terms of hardware and software.
Higher-level than unit testing.Higher-level than integration testing.
Faster to perform.Slower to perform.

 

# References

- 챗 GPT

Comments