[Sprint] 빌드 및 테스트 자동화

# 학습 목표

  • 지속적 통합의 필요성을 설명할 수 있다.
  • 빌드/테스트의 개념을 이해할 수 있다.
  • 릴리스의 개념을 이해할 수 있다.
  • CI 도구(여기서는 GitHub Action)를 이용하여 지속적 통합이 이루어지는 과정을 직접 구현할 수 있다
  • 다양한 CI 도구의 차이점을 이해할 수 있다.
  • 코드와 환경 변수를 분리해야 하는 이유를 설명할 수 있다.

# 해결 과제

Getting Started

  • node.js 프로그램의 테스트를 위해서는 npm test 명령어를 CI, 즉 GitHub Action 상에서 자동으로 실행해줘야 합니다.
  • 먼저 공식 문서를 통해 GitHub Action의 사용방법을 알아봅시다.
  • Actions 탭을 클릭하여 workflow가 제대로 작동했는지를 확인해 봅시다.
  • 레퍼런스를 참고하여 GitHub Action Node.js workflow를 만들고, 테스트가 통과하는지 확인하세요.

# 실습 자료

sprint-mini-node-server-with-github-action


# 과제 항목별 진행 상황

✏️ 1. 유닛 테스트를 통과시키세요.

먼저 테스트 주도 개발을 연습합니다. 직접 test/app.test.js를 수정하여 통과하지 않는 테스트를 모두 통과시키세요.

1. 테스트가 통과하는지 확인하려면 npm test 명령을 이용합니다.

oh@devops:~/codeStates/sprint-mini-node-server-with-github-action$ npm test

> mini-node-server@1.0.0 test
> mocha ./test

Server listening on http://localhost:4000


  유닛 테스트 101
    1) 결과에 대한 기대값(expectation value)를 비교하여 유닛 테스트를 할 수 있습니다
    2) 서버에 GET / 요청을 보내면 Hello World!라는 텍스트가 응답으로 옵니다
    3) 서버에 POST /upper 요청에 body를 실어 보내면 응답은 대문자로 돌려줍니다
    4) 서버에 POST /lower 요청에 body를 실어 보내면 응답은 소문자로 돌려줍니다


  0 passing (105ms)
  4 failing

  1) 유닛 테스트 101
       결과에 대한 기대값(expectation value)를 비교하여 유닛 테스트를 할 수 있습니다:
     AssertionError: expected 2 to equal '기댓값이 채워지지 않았습니다'
      at Context.<anonymous> (test/app.test.js:13:25)
      at process.processImmediate (node:internal/timers:476:21)

  2) 유닛 테스트 101
       서버에 GET / 요청을 보내면 Hello World!라는 텍스트가 응답으로 옵니다:

      AssertionError: expected 'Hello World!' to equal '기댓값이 채워지지 않았습니다'
      + expected - actual

      -Hello World!
      +기댓값이 채워지지 않았습니다
      
      at /home/oh/codeStates/sprint-mini-node-server-with-github-action/test/app.test.js:21:32
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

  3) 유닛 테스트 101
       서버에 POST /upper 요청에 body를 실어 보내면 응답은 대문자로 돌려줍니다:

      AssertionError: expected 'CODESTATES' to equal '기댓값이 채워지지 않았습니다'
      + expected - actual

      -CODESTATES
      +기댓값이 채워지지 않았습니다
      
      at /home/oh/codeStates/sprint-mini-node-server-with-github-action/test/app.test.js:31:32
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

  4) 유닛 테스트 101
       서버에 POST /lower 요청에 body를 실어 보내면 응답은 소문자로 돌려줍니다:

      AssertionError: expected 'codestates' to equal '기댓값이 채워지지 않았습니다'
      + expected - actual

      -codestates
      +기댓값이 채워지지 않았습니다
      
      at /home/oh/codeStates/sprint-mini-node-server-with-github-action/test/app.test.js:41:32
      at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

2. app.test.js 를 수정하여 test 를 통과시킵니다.

const { expect } = require('chai')
const request = require('supertest')
const { app, server } = require('../app')
const FILL_ME_IN = '기댓값이 채워지지 않았습니다'

describe('유닛 테스트 101', () => {

  after(() => {
    server.close()
  })

  it('결과에 대한 기대값(expectation value)를 비교하여 유닛 테스트를 할 수 있습니다', () => {
    expect(1 + 1).to.be.equal(2) // 기대값 추가
    expect(100 + 200).to.be.equal(300) // 기대값 추가
  })

  it('서버에 GET / 요청을 보내면 Hello World!라는 텍스트가 응답으로 옵니다', () => {
    return request(app)
      .get('/')
      .then(res => {
        expect(res.text).to.be.equal('Hello World!') // 기대값 추가
      })
  })

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

  it('서버에 POST /lower 요청에 body를 실어 보내면 응답은 소문자로 돌려줍니다', () => {
    return request(app)
      .post('/lower')
      .send('"coDeStaTes"')
      .set('Content-Type', 'application/json')
      .then(res => {
        expect(res.body).to.be.equal('codestates') // 기대값 추가
      })
  })
})
oh@devops:~/codeStates/sprint-mini-node-server-with-github-action$ npm test

> mini-node-server@1.0.0 test
> mocha ./test

Server listening on http://localhost:4000


  유닛 테스트 101
    ✔ 결과에 대한 기대값(expectation value)를 비교하여 유닛 테스트를 할 수 있습니다
    ✔ 서버에 GET / 요청을 보내면 Hello World!라는 텍스트가 응답으로 옵니다
    ✔ 서버에 POST /upper 요청에 body를 실어 보내면 응답은 대문자로 돌려줍니다
    ✔ 서버에 POST /lower 요청에 body를 실어 보내면 응답은 소문자로 돌려줍니다


  4 passing (91ms)

✏️ 2. GitHub Action을 이용해서 Node.js CI를 적용하세요.

1. node 버전은 16 버전으로 반드시 지정해야 합니다.

$ nvm install 16.13.0
$ nvm use 16.13.0

2. 다음 상황에서 GitHub Action이 트리거되어야 합니다.

.github/workflows 디렉토리에 workflow 파일 생성

master 로 push 테스트 – Success

master 로 push 테스트 – Fail

master 로 pull request 테스트


# TROUBLE SHOOTING LOG

💡 문제 내용

원인

해결 방안


# 피드백

오태경박찬규
DevOps의 상징 ‘자동화’ 를 처음으로 구현해보니 간단한 스크립트로도 개발자의 많은 수작업을 덜어줄 수 있다라는 것을 깨달았다.GitHub 공식문서를 보면서 학습하고 있었고 자동화 할 수 있는 방법이 많다는걸 알게됬다.

#References

Leave a Comment