ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Nodejs: 테스트 코드 작성하기(feat. Jest)
    Nodejs 2021. 9. 8. 01:30

    이번 포스팅은 테스트 코드의 원칙과

    Jest를 이용한 단위 테스트 코드 작성에 대해 포스팅한다. 

     

     

     

    1. 테스트 코드란 무엇일까?

     

    테스트 코드는 말 그대로 우리가 작성한 코드에 문제가 없는지 테스트하기 위해 작성하는 코드다. 

     

    올바른 테스트 코드 작성을 위해선 흔히 기본 원칙이라 불리는 일곱 테스트 원칙을 따르는게 좋다. 

     

    < 일곱 테스트 원칙 >

     

    1. 테스팅은 결함의 존재를 보여주는 것이다. 

    2. 완벽한 테스트는 불가능하다.

    3. 테스트 구성은 가능한 빠른 시기에 시작한다.

    4. 결함은 군집되어 있다.

    5. 살충제 역설 - 비슷한 테스트가 반복되면 새로운 결함을 발견할 수 없다.

    6. 테스팅은 정황에 의존적이다.

    7. 오류 부재의 오해 - 사용되지 않는 시스템이나 사용자의 기대에 부응하지 않는

    기능의 결함을 찾고 수정하는 것은 의미가 없다. 

     

     

    < 일곱 테스트 원칙 >은 다음 링크에서 참조했습니다. 

     

    설마 아직도 테스트 코드를 작성 안 하시나요?

    가끔 욕을 먹고 싶을 때가 있을 수도 있죠. 가끔 지탄을 받고 꾸중을 들음으로써 자극을 받고 정신을 차리고 싶을 수도 있습니다. 아니면 혹은 그냥 아무 이유 없이 갑자기 한심한 눈초리를 받고

    ssowonny.medium.com

     

     

     

    < 테스트 코드의 종류 >

     

    1) 단위 테스트(Unit Test)

    가장 작은 규모의 기능을 테스트한다.

    (여기서 가장 작은 규모는 함수 정도라고 생각하자)

     

    2) 통합 테스트(Integration Test)

    여러가지 기능을 합쳤을때 생기는 문제를 방지하기 위한 테스트

     

    3) E2E 테스트(End-to-end Test)

    백엔드부터 시작해서 웹 페이지가 원하는대로 동작하며

    원하는 데이터를 잘 보여주는지 확인하는 테스트

     

     

     

    2. Testing 프레임워크 Jest

     

    Jest는 최근 주목받고 있는 자바스크립트 Testing 프레임워크 중 하나로

    이번 포스팅에서는 Jest를 이용해 간단한 함수 하나를 테스팅한다. 

     

     

    < Jest 시작하기 > 

     

    1. jest 모듈 설치하기 

    npm init
    npm i jest -D

     

     

     

    2. package.json 수정

     

    scripts를 다음과 같이 변경한다. 

      "scripts": {
        "test": "jest"
      },

    (npm run test시 jest를 실행한다는 뜻)

     

     

     

    3. 테스트할 간단한 함수 만들기 

     

    root 경로에 이메일의 유효성을 판단하는 함수를 생성하자.  

     

    <validation.js>

    module.exports = {
        isEmail: (value) => {
            // value가 이메일 형식에 맞으면 true, 형식에 맞지 않으면 false를 return 하도록 구현해보세요
            return false;
        },
    };

    (우선은 틀만 만들기 위해 위와 같이 대충 작성했다.)

     

     

     

    4. 단위 테스트 코드 파일 생성

     

    root에 [테스트할 파일 이름].spec.js로 파일을 생성한다.

     

    npm run test 커맨드 실행시 jest는 .spec.js 파일을 찾아 test를 시작한다. 

     

    <validation.spec.js>

    const { isEmail } = require('./validation');
    
    test('테스트가 성공하는 상황', () => {
        expect(isEmail('이메일이 아니에요')).toEqual(false);
    });
    
    test('테스트가 실패하는 상황', () => {
        expect(isEmail('my-email@domain.com')).toEqual(true);
    });

     

    - test(): 단위 테스트를 묶어주는 함수

    - expect(): 특정 값이 만족되는지(정상적인지) 확인하기 위한 표현식을 작성할수 있게 해주는 함수

     

     

     

    5. npm run test

     

    npm run test 나 npm test시 다음과 같은 화면이 출력된다. 

    > practice01@1.0.0 test /home/seung/nodejs/practice01
    > jest
    
     FAIL  ./validation.spec.js
      ✓ 테스트가 성공하는 상황 (1 ms)
      ✕ 테스트가 실패하는 상황 (2 ms)
    
      ● 테스트가 실패하는 상황
    
        expect(received).toEqual(expected) // deep equality
    
        Expected: true
        Received: false
    
          6 |
          7 | test('테스트가 실패하는 상황', () => {
        > 8 |     expect(isEmail('my-email@domain.com')).toEqual(true);
            |                                            ^
          9 | });
    
          at Object.<anonymous> (validation.spec.js:8:44)
    
    Test Suites: 1 failed, 1 total
    Tests:       1 failed, 1 passed, 2 total
    Snapshots:   0 total
    Time:        0.25 s, estimated 1 s
    Ran all test suites.
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! practice01@1.0.0 test: `jest`
    npm ERR! Exit status 1
    npm ERR! 
    npm ERR! Failed at the practice01@1.0.0 test script.
    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /home/seung/.npm/_logs/2021-09-07T15_32_04_777Z-debug.log

     

    위 예시를 test했을 때 2개의 테스트 중 하나의 테스트만 통과했다고 출력된다. 

     

    대략적인 틀을 확인했으니 본격적으로 파일을 수정한다. 

     

     

     

    6. validation.spec.js 수정 

     

    다음과 같은 요구사항을 추가한다. 

    const { isEmail } = require("./validation");
    
    test('입력한 이메일 주소에는 "@" 문자가 1개만 있어야 이메일 형식이다.', () => {
      expect(isEmail("my-email@domain.com")).toEqual(true); // 1개만 있는 상황
      expect(isEmail("my-email@@@@domain.com")).toEqual(false); // 여러개 있는 상황
      expect(isEmail("my-emaildomain.com")).toEqual(false); // 하나도 없는 상황
    });
    
    test("입력한 이메일 주소에 공백(스페이스)이 존재하면 이메일 형식이 아니다.", () => {
      expect(isEmail("myemail@domain.com")).toEqual(true);
      expect(isEmail("my email@domain.com")).toEqual(false);
    });
    
    test("입력한 이메일 주소 맨 앞에 하이픈(-)이 있으면 이메일 형식이 아니다.", () => {
      expect(isEmail("e-m-a-i-l@domain.com")).toEqual(true);
      expect(isEmail("-email@domain.com")).toEqual(false);
    });

     

     

     

    7. validation.spec.js에 맞게 validation.js 수정

    module.exports = {
        isEmail: (value) => {
            const email = (value || '');
    
            if (email.split('@').length !== 2) {
                return false;
            } else if (email.includes(' ')) {
                return false;
            } else if (email[0] === '-') {
                return false;
            }
    
            return true;
        },
    };

     

     

     

    8. npm run test 실행 

    > practice01@1.0.0 test /home/seung/nodejs/practice01
    > jest
    
     PASS  ./validation.spec.js
      ✓ 입력한 이메일 주소에는 "@" 문자가 1개만 있어야 이메일 형식이다. (2 ms)
      ✓ 입력한 이메일 주소에 공백(스페이스)이 존재하면 이메일 형식이 아니다.
      ✓ 입력한 이메일 주소 맨 앞에 하이픈(-)이 있으면 이메일 형식이 아니다.
    
    Test Suites: 1 passed, 1 total
    Tests:       3 passed, 3 total
    Snapshots:   0 total
    Time:        0.265 s, estimated 1 s
    Ran all test suites.

     

    테스트 결과  3개의 테스트 중 3개가 성공했으므로 isEmail함수가 어느정도 쓸만해졌다는 것을 알 수 있다.

     

    테스트 코드는 질 떨어지는 코드의 작성을 막아주며

    더 나은 테스트하려는 기능의 코드보다 기능을 테스트하는 테스트 코드가 많아야 모범사례라 할 수 있다. 

    반응형

    댓글

Designed by Tistory.