Medium - How to get better at testing with TDD

원문 - Thomas Lombart in freeCodeCamp.org

Trend 파악을 Medium 기고문 요약 포스팅 - TDD를 통해 더 나은 테스트를 하는 법

500x400

테스트는 모든 개발자가 지녀야 할 매우 중요한 기술입니다. 아직도 어떤 개발자들은 테스트 하는 것을 꺼리지만요..

우리는 언젠가 이런 식으로 얘기하는 개발자들을 만난 적이 있을겁니다.

“테스트는 필요없어”, “그건 노력이 너무 많이 들어”, “난 내 코드를 의심하지 않는데 왜 시간을 낭비해야 하지?”

그들의 말을 듣지 마세요. 테스트는 매우 중요합니다.

테스트가 중요한 이유는 테스트가 당신의 코드를 더욱 안정적으로 만들고 버그가 발생하는 기회를 줄여주기 때문입니다.

당신은 당신이 작성한 코드를 모두 세세히 알고 있기 때문에 그렇지 않다고 생각할 수 있습니다.

그러니까, 당신이 그것을 작성했으니 당신이 매우 속속들히 알고 있는 것에 대해 왜 테스트를 해야하냐는 것이죠

그러면 당신이 날씨 관련 앱을 만들었다고 가정합시다. 당신은 며칠동안 혹은 몇주동안 코딩을 했고

당신이 작성한 코드에 대해 매우 잘 알고 있는 상태입니다.

그리고 당신이 이 앱을 빌드하는 것을 멈추고 몇 달이 지난 후에 다시 확인한다고 가정해 봅시다.

당신은 예전의 코드에 대한 모든 것을 기억하지 못할 것입니다. 당신이 어떤 것을 변경하려고 하면

이런, 문제가 발생했군요. 어떻게 고칠 것인가요? 당신이 작성한 모든 코드를 보면서 일을 다시 할 것가요?

그러한 방식도 문제를 해결할 수는 있겠죠. 그러나 이 파일을 수정하면서 다른 곳을 파괴하게 될겁니다.

그러면 당신은 이렇게 생각할 겁니다. “에라이, 어떻게 코드했는지 기억이 안나네 이 앱은 그대로 냅두고 다른걸 해야겠다”

다른 예를 한번 들어봅시다. 몇 달간 고군분투한 끝에 당신은 원하는 팀에 들어갈 수 있었습니다. 당신은 팀으로서

무언가를 만들기 시작하는 겁니다. 다른 팀원의 코드에 작업을 하고 팀원은 당신의 코드에 작업을 합니다. 그러면

모든 것이 박살날 겁니다. 팀이 앱에 테스트를 넣지 않는다면 디버깅 하는데 행운을 빌 수 밖에 없습니다.

모든 IT회사들은 그들이 소프트웨어나 앱을 만들 때 테스트를 작성합니다. 첫 주에 어떻게 테스트를 하는지

어떻게 테스트를 작성하는지 몰라서 고생하는 사람이 되고 싶으신건 아니죠?

그렇다면 테스트를 작성하는데 시간을 들이세요! 처음에는 어려울 겁니다. 앱을 만드는 것이 훨씬 재밌죠

그러나 테스트는 필수적인 요소이며 올바르게 구현될 경우 많은 시간을 절약해 줍니다.

따라서 오늘의 목표는 당신의 테스트 능력을 향상시키는 것 입니다. 시작해봅시다.

Unit testing

당신이 앱을 테스트 하기로 결정했다면 당신은 많은 종류의 테스트들과 맞닥뜨릴 것입니다. 단위 테스트, 통합테스트, 기능 테스트들 말이죠. 우리는 이 예제에서 단위 테스트에 초점을 맞출 것입니다. 물론 기능 테스트와 통합 테스트도 매우 중요하지만 그것은 단위 테스트 보다 구성 및 구현이 매우 힘듭니다. 게다가 당신은 유닛 테스트를 통해 많은 것을 얻게 될겁니다.

간단히 말해서 단위 테스트는 당신의 코드의 작은 부분들을 테스트 하는 것으로 구성되어 있습니다. 함수, 클래스의 메소드와 같은 것들 말이죠, 당신은 입력값을 넣고 당신이 기대하는 결과 값이 나오는지 확인 하는 것입니다.

다음은 단위 테스트의 장점입니다.

  • 코드를 안정적으로 만들어 준다.
  • 함수의 기술적 구현을 보다 쉽게 변경할 수 있다.
  • 당신의 코드를 문서화 하는 것이다
  • 당신이 좋은 코드를 설계하도록 강제한다. 왜냐하면 나쁜 구조는 매우 테스트 하기가 어렵다.

Test-Driven Development(TDD)

TDD를 이해하기 위해서는 2가지 규칙만 기억하시면 됩니다.

  • 코드를 작성하기 전에 테스트 실패를 작성한다
  • 그리고 실패한 테스트를 통과하기 위한 기준을 만족하는 코드를 작성한다.

TDD를 쓸 때 우리는 Red/Green/Refactor 사이클에 대해 얘기합니다.

  • Red : 코드를 작성하지 않고 테스트를 실패하는 것에 대해 작성합니다.
  • Green : 간단하고 바보같은 코드라도 가장 간단하게 테스트를 통과하는 코드를 작성합니다.
  • Refactor : 필요한 경우 코드를 리팩토링 하는 것입니다. 당신은 테스트 한 항목이 확실한지 확인하고 싶을 것입니다. 코드를 리팩토링 하더라도 다른 것이 망가지거나 잘못될 염려는 하지 않아도 됩니다.

너무 이론적으로 들리나요? 걱정마세요 실습을 해봅시다.

Structuring a test file

Jest는 테스트를 구성하는 함수들을 제공해 줍니다.

  • describe : 테스트를 그룹핑하거나 함수,모듈,클래스를 기술하는데 사용합니다. 2개의 인자를 사용하며 첫번째는 그룹을 설명하는 것이고 두번째는 콜백 함수입니다.

  • it or test : 당신의 테스트 케이스 입니다. 인자값은 describe와 동일해야 합니다. 테스트의 이름은 Should로 시작하는 것이 통상적입니다.

  • beforeAll (afterAll) : 모든 테스트 시작 전과 후에 수행되는 함수 입니다. 테스트 전/후에 실행시킬 하나의 함수를 인자로 받습니다.

  • beforeEach (afterEach) : 각 테스트 시작 전/후에 수행될 함수를 매개변수르 받는 함수입니다.

당신은 테스트를 작성하기 전에 아래의 내용을 잘 따라야 합니다.

  • .skip을 사용하여 테스트를 컨너 뛸 수입니다. it.skip(…), describe.skip(…)

  • .only를 사용하여 정확히 특정 테스트들만 수행되게 할 수 있습니다. it.only(…), describe.only(…)

이것들은 테스트가 많거나 특정 테스트에 집중할 수 있을 때 매우 효과적입니다.

Setting up Jest

그럼 Jest의 함수들을 알아보았으니 설정을 해봅시다.

사전환경으로 Node.js와 npm이나 Yarn이 필요합니다.

디렉토리를 새로 만들고 초기화해 줍시다.

mkdir test-example && cd test-example
npm init -y
# OR
yarn init -y
yarn add jest --dev
#개발의존성에 jest를 추가해 줍시다.
#package.json에 아래의 내용을 추가해 줍시다.
"scripts": {
  "test": "jest"
}

yarn test 명령어로 테스트를 수행할 수 있습니다.

이것이 전부 입니다. 당신은 첫 테스트를 작성할 준비가 됬습니다.

via GIPHY

Matchers

당신이 테스트를 수행할 때 입력값에 대한 예상 결과값이 필요합니다. Jest의 matcher 함수가 이럴 때 쓰입니다.

expect(input).matcher(output)

많은 matcher가 Jest에 있지만 갖아 많이 쓰이는 것들을 소개하겠습니다.

  • toBe(===); 엄격하게 동일한지 비교
    expect(1 + 1).toBe(2)
    let testsAreEssential = true
    expect(testAreEssential).toBe(true)
    
  • toEqual ``` let arr = [1, 2] arr.push(3) expect(arr).toEqual([1, 2, 3]) let x= 1 x++ expect(x).toEqual(2)
* toBeTruthy (toBeFalsy) : 참/거짓 값 판별

expect(null).toBeFalsy() expect(undefined).toBeFalsy() expect(false).toBeFalsy() expect(“Hello world”).toBeTruthy() expect({foo: ‘bar’}).toBeTruthy()


* not : 위치한 매처의 결과값을 반대로 리턴한다.

expect(null).not.toBeTruthy() // same as expect(null).toBeFalsy() expect([1]).not.toEqual([2])


* toContain : 주어진 배열에 특정 요소가 있는지 확인한다

expect([‘Apple’, ‘Banana’, ‘Strawberry’]).toContain(‘Apple’)

* toThrow : 에러를 반환하는지 체크한다

function connect () { throw new ConnectionError() } expect(connect).toThrow(ConnectionError)


### First Tests

#example.spec.js 파일 내용 describe(‘Example’, () => { beforeAll(() => { console.log(‘running before all tests’) }) afterAll(() => { console.log(‘running after all tests’) }) beforeEach(() => { console.log(‘running before each test’) }) afterEach(() => { console.log(‘running after each test’) }) it(‘Should do something’, () => { console.log(‘first test’) }) it(‘Should do something else’, () => { console.log(‘second test’) }) }) ```

Summary

  • 개발자에게 테스트 능력은 매우 중요하다
  • 신입 개발자로서 테스트의 중요성과 테스트 능력을 향상 시켜야 한다.
  • TDD의 개념과 테스트 예제(Jest 사용)
  • 테스트를 작성하는 것은 코드의 퀄리티를 높여주고 코드의 문서화를 하는 것에 도움이 된다.

© 2019. All rights reserved.

Powered by Hydejack v8.1.1