Web Front-end/JavaScript

[JS/Basic/TDD,BDD] 자바스크립트 테스팅 연습

자기 프로그램을 테스트를 안하는 프로그래머가 있을까요 ?? 이건, 음식점을 하는데 간을 보지 않는것과 같습니다.

  • 컴파일을 하면서  출력값을 보는 것도 일종의 테스트입니다. 실제로, 출력값을 중간 중간에 찍는건 아주 좋은 테스트 방법이죠. 그리고, 알고리즘 문제를 풀 때도, 다양한  테케(테스트케이스)를 넣어보는 연습을 하고, 아주 극단적인 상황의 테스트 케이스를 넣어보곤 합니다.
  • 프로그램을 작성할 때 Error를 검출하고, Bug를 막기 위해서 Test는 필수입니다. (실제로 Mapin도 최소한 아주 극단적인 입력값을 넣는 정도는 하고 프로그램을 완성합니다.)
  • 실제로, 

하지만, 프로젝트가 매우 크고 , TestCase가 엄청 많아진다면 "Test"하는 것 또한 쉽지않은 일이 되어버립니다. 따라서, TDD,BDD등의 개념이 굳이 "따로" 등장을 하게 된겁니다.

 

* 여기서 꿀팁! 

더보기

공부하다 느끼게 된건데 (정확하지 않을 수 있습니다) ,  대부분 문제는 "너무 많아서" 발생합니다! .예를 들어,  "대용량 처리"," 대용량 트래픽","대용량 데이터","대규모 프로젝트","많은 개발인원" 등  "너무 많아서" 발생하는 문제들이 많습니다. 원인은 대부분 "너무 많아서"로 찍으면 80%는 맞을거 같습니다! 

TDD(Test Driven Development)

  • 테스트를 먼저 작성하고, 테스트가 정상적으로 돌아갈 때 까지 테스트를 하면서, 코드를 작성하는 방법입니다.
  • 원하는 작업이 제대로 돌아갈 때 까지, 테스트와 코드 작성을 무한으로 반복하여 개발을 합니다.
  • 입력값 -> 기댓값을 미리 정해놓고, 로직을 테스트하는 과정으로 작성됩니다. 주로, 누가봐도(널리 알려진) 아닌 것들 위주로 먼저 작성합니다. 예를들어, 모든 숫자는 0으로 나눌 수 없는것 처럼요.

여러가지 Test방법이 있습니다. Unit,E2E ..등 하지만,  하나하나 중요한 개념이니까 , TDD,BDD에 대해서는  따로 천천히 글을 적으려고 합니다. 물론 , 하나하나 다 작성을 하기에는 엄청난 노력과 시간이 들기 때문에, 언어마다 잘 만들어진 여러가지 라이브러리가 있습니다(KoTest,Mockk,JUnit,Mocha.js,Chai.js....)

Test가 가능하다는 의미 (TDD의 장점) 

  • Test가 가능하다는 의미는 해당 모듈의 역할이 명확해지는 것을 의미합니다.  그래야 테스트가 가능하니까요. 모든 케이스를 고려한 테스트는 불가능하기 때문입니다.
  • 모듈의 역할이 명확해지면, 모듈끼리의 커플링(coupling)을 방지할 수 있습니다. 
  • 또한, TC(Testcase)를 생각하는 과정에서 사용자의 입장에서 발생하는 Error를 미리 차단할 수있고, 이는 곧 소프트웨어의 품질을 높일 수 있게 됩니다.

TDD의 단점

  • 완벽한 TestCase를 만들어내는건 매우매우 어렵고, TC(TestCase)를 작성하는데 오랜시간이 걸립니다. 또, 예외적인 TC가 지속적으로 나올 수 있습니다.
  • TC를 작성하는데 시간이 걸려서, 제품의 출시도 늦어지고, 결국 Test를 제대로 못하고 배포하는 악순환에 빠질 수 있습니다. 
  • 기획,설계 단계에서 일정부분이 수정되면 , 또 TC를 다시 설계해야한다. (추가비용 발생 , 안하느니 못한 상황이 될 수 있다)

BDD(Behavior Driven Development) 

행동 주도 개발이라고 하는데, 사실 내가 느끼기에는 "기획서 꼼꼼하게 잘 읽어서, 기획서 단계에서 예외상황들을 미리 생각해서 코드로 옮겨놓자"입니다. 같은 문제를 TDD,BDD로 비교하면 좀 더 뚜렷하게 차이가 나타납니다.

 

계산기가 있고, Add라는 더하는 Module이 있다고 합시다.

  • TDD :  Add(1,1)이 2(기대한 값)인지 확인
  • BDD :  사용자가 행동(1을 누르고, +를 누르고, 1을 또 누르고, =를 눌러서) , "2"가 화면에 뜨는 모든 과정을 Test한다.

보통, 사용자의 Action이 들어가기 때문에, FE에서는 BDD를 많이 채용합니다. 하지만, BDD와 TDD는 상호보완의 느낌이므로, 같이 써야하는 개념입니다. Module만을 평가할 때는 TDD가 적합하니까요. Given(상황) - When(행위) - Then(결과)의 구조가 일반적입니다. 하지만, 라이브러리마다 다르게 구현될 수 있습니다.

BDD의 장점

  • Testcase 작성에 시간이 오래걸리지 않는다. (기획서를 참조한 상태로 진행)
  • 기획서를 통해서, 예외적인 상황을 쉽게 떠올릴 수 있게 된다. 그리고, 예외적인 상황들을 그대로 코드로 반영하면 된다. 기획단계부터 좀 더 탄탄해지는 효과를 얻을 수 있다.
  • 사용자의 측면까지 고려하여, 예외상황을 작성할 수 있다. 서비스에 대한 이해도가 증가할 수 밖에 없다.

 

Mocha.js로 테스트 연습

 

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MochaTesting</title>
    <link rel ="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css">
    <!-- mocha 라이브러리 선언 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.js"></script>
    <script>
        mocha.setup('bdd'); //setup 
    </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>
    <script>let assert = chai.assert;</script>
</head>
<body>
    <script>
        function pow(x, n){
            let res=1;
            for (let i=0;i<n;i++){
                res *=x;
            }
            return res;
        }
    </script>
    <script src="test.js"></script>
    <div id="mocha"></div>
    <!-- mocha 라이브러리 실행 -->
    <script>
        mocha.run();
    </script>
</body>
</html>

test.js

describe("pow",function(){
    describe("x를 세 번 곱합니다.",function(){
        function makeTest(x){
            let expected = x*x*x;
            it(`${x}을 세 번 곱하면 ${expected}입니다.`,function(){
                assert.equal(pow(x,3),expected);
            })
        }
        for (let x=1;x<=5;x++){
            makeTest(x);
        }
    })
})

 

참고 사이트

https://ko.javascript.info/

 

모던 JavaScript 튜토리얼

 

ko.javascript.info