일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Neural Network
- 패턴인식
- 물걸레자동세척로봇청소기
- 신경회로망
- 하이퍼바이저
- 삼성전자 소프트웨어멤버십 SSM
- 나르왈프레오
- Google App Engine
- hopfield network
- 삼성소프트웨어멤버십
- 파이썬
- 신경망
- 동아리
- 빅데이터
- 갤럭시탭S8울트라
- 삼성
- 가상화
- BAM
- NarwalFreo
- 물걸레로봇청소기추천
- Bidirectional Associative Memory
- Friendship
- SSM
- 구글 앱 엔진
- 고려대학교
- 패턴 인식
- 인공지능
- 멤버십
- 증강현실
- Python
- Today
- Total
정보공간_1
[6기 수원 김병연] Node.js TDD & BDD 본문
Node.js TDD & BDD
이번 회차에서는 TDD와 BDD에 대해서 알아보도록 하겠습니다.
놀랍게도(저만 놀랐나요) TDD와 BDD는 단순한 테스트 기법이 아닌
소프트웨어 공학에서 사용되는 소프트웨어 개발 프로세스입니다.
-TDD의 개념
처음에는 TDD가 단순히 테스트를 하기 위한 방법인 줄 알았지만
TDD의 궁극적인 목표는 테스트에 있는 것이 아닙니다.
저번회에서 만들었던 numberPlus 함수가 기억나시나요?
예를들어 요구사항이
"돈이 불어나는 항아리가 있는데, 누군가 돈을 넣으면 1만원을 더해서 돌려주어야 합니다." 였다면
아마도 일반적으로 이 함수를 먼저 코딩한 후 이렇게 주석을 달겁니다.
"numberPlus 함수는 매개변수를 받아 그것을 for문 1만번 돌면서 증가시키고 Return 한다."
하지만 위와 같은 경우에 TDD는 코드가 없는 상태에서 먼저 시작합니다.
먼저 명세를 만듭니다.
- 항아리는 돈을 넣을 수 있다.
-
넣은 돈에 1만원을 더해 돌려줄 수 있다.
그리고 테스트 케이스를 작성합니다.
- 항아리에는 더할 수 있는 돈이 들어와야 합니다.
- 들어온 돈에 1만원이 잘 더해져야 합니다.
- 더해진 돈을 잘 돌려주어야 합니다.
이후, 최소한의 코드만을 작성하고 보수합니다.
대강 감이 오시나요?
-TDD 예제
개념에 대해 알아보았으니
이제 TDD를 이용해 실제 프로그래밍을 시작해 봅시다.
요구사항은 간단하게 위와 같다고 가정합니다.
방금 보았듯 무엇이 테스트 되어야 하는지 명세를 만든 후,
다음과 같이 코드보다 먼저 테스트 케이스를 작성합니다.
TDD.js
var assert=require('assert'); var testFile=require('./testFile'); //아직 testFile 도 없고 printNumber 함수도 없으므로 당연히 에러가 납니다. assert.equal(testFile.printNumber(10),"10010",'같지 않다!');
주석과 같이 testFile 도 없고 printNumber 함수도 없으므로
테스트를 위해 저번 포스팅에서 만들었던 js파일과 numberPlus함수를 외부에서도
사용 가능하도록 노출시켜 보겠습니다.
테스트를 위해서는 numberPlus 함수는 printNumber 라는 이름으로 노출해야겠군요.
testFile.js
function numberPlus(number){ for(var i=0; i<10000; i++){ number++; } console.log("testFile : number +10000 : ",number); return number; } //numberPlus 함수를 printNumber라는 이름으로 노출 시켜 보겠습니다. module.exports.printNumber=numberPlus;
그렇다면 이제 다른 js파일에서 numberPlus함수에 접근이 가능합니다.
TDD.js를 실행해 보면 이제 에러가 나지 않고
testFile : number +10000 : 10010
가 잘 뜨게 됩니다.
그런데 뭔가 이상하죠? 위에서 작성한 TDD.js 파일을 다시한번 살펴보면
assert.equal(testFile.printNumber(10),"10010",'같지 않다!');
로 되어있는데 10원을 넣었을 때 비교하는 대상이 문자열 "10010" 입니다.
즉 지금은 돈 10원을 넣었을 때 돈 10010원이 나오던 문자열 10010이 나오던 테스트가 통과하네요.
변수타입도 같아야 통과하는 강한 테스트가 필요하겠네요.
다시 한 번 작성해 보겠습니다.
TDD.js
var testFile=require('./testFile'); var assert=require('assert'); //이 테스트는 당연히 통과. assert.equal(testFile.printNumber(10),10010,'같지 않다!'); //이 테스트도 느슨한 비교라서 통과. assert.equal(testFile.printNumber(10),"10010",'같지 않다!'); //이 테스트는 통과하지 않습니다. assert.strictEqual(testFile.printNumber(10),"10010",'완전히 같지는 않다!');
위와 같은 경우에 strintEqual() 를 통해 엄격한 테스트를 할 수 있습니다.
덕분에 마지막 테스트는 통과하지 못하겠군요.
이처럼 기본적인 테스트를 하는데는 유용한 모듈이지만
비동기식 호출인 경우, 다른 방식이 필요합니다.
여기에서 자세하게 다루지는 않겠지만
TDD와 BDD를 모두 지원하는 Mocha나 Nodeunit을 사용하시면
비동기식 테스트가 가능하며 Nodeunit은 Assert 모듈의 모든 함수를 같은 명칭과 기능으로 지원합니다.
-BDD의 개념
위에서 TDD에 대해서 잠깐 살펴 보았는데요.
그렇다면 BDD는 뭘까요?
사실 BDD와 TDD는 크게 차이가 없지만 BDD는 조금 더 비즈니스적 요구사항에 맞추어
테스트 케이스를 작성하는것에 있습니다.
이것은 의도적으로 "Test"라는 말 대신 "Behavior" 를 쓰면서
테스트 함수가 무엇을 수행해야 하는지 좀 더 명확하게 나타내는데요.
만약 코드의 변경이 테스트 케이스에 문제를 일으킨다면
테스트 함수의 이름을 보는 것만으로 코드에 부여된 임무 즉 자신이 의도한 행위를 명확히 할 수 있습니다.
그리고 테스트 케이스에 "행위"를 서술 하기 때문에 누구나 이해 할 수 있고
개발자가 아닌 다양한 프로그래밍 지식을 가진 각양 각색의 비즈니스 관계자들도 테스트에 참여 할 수 있게 합니다.
-BDD 예제
BDD에도 굉장히 많은 모듈이 존재합니다.
하지만 여기서는 Eclipse 위에서 동작 가능한 Vows를 소개하도록 하겠습니다.
Vows 는 '10원을 집어넣는다면', '20원을 집어넣는다면'과 같은 문맥들이 있는데
문맥간 테스트는 완전히 비동기적으로 실행됩니다.
따라서 특정 순서에 따라 진행되는 테스트를 원한다면
vows.describe().addBatch(/*첫번째*/).addBatch(/*두번째*/).addBatch(/*세번째*/)
이런식으로 체인을 걸어 사용하시면 됩니다.
topic은 함수를 실행하고 리턴값을 갖게 되는데 이것을 이용해 테스트를 수행하면 됩니다.
물론 topic 자체에 값을 집어넣을 수도 있습니다.
비동기 함수를 실행하는 경우에는 어떻게 할까요?
이 때는 모든 topic에서 사용 가능한 this.callback 라는 함수를 통해 인자로 값을 전달하면 됩니다.
이 함수는 호출 될 때 마다 하나씩 테스트 함수의 인자로 값을 전달합니다.
백문이 불여일견.
여기서도 당연히 코드보다 테스트를 먼저 만듭니다.
BDD.js
var testFile=require('./testFile'); var assert=require('assert'); var vows=require('vows'); //BDD: Behavior Driven Development - 행위 테스트 //어떤 테스트인지 명시 vows.describe('1만을 더해주는 함수에 특정 숫자를 집어넣었을 때 잘 동작하는지 확인.').addBatch({ /* // 이것은 동기적인 함수일 경우 테스트입니다. '20원을 집어넣는다면':{ topic:testFile.printNumber(testcase), '1만원이 더해지므로':function(topic){ assert.equal(topic,10020,'10020만원이 되어야 한다!'); } }, */ //행위에 대해 명시 : '10원을 집어넣는다면':{ //이 테스트의 주제 : topic:function(){ testFile.printNumber(10,this.callback); }, //테스트에 대한 결과 : '1만원이 더해지므로':function(stat,err){ //넘어온 stat에 대해 엄격한 equal을 사용해 봅시다. assert.strictEqual(stat,10010,'10010원이 되어야 한다!'); } } }).run();
그리고 이번에는 1만원을 더해주는 함수를 비동기로 만들어 봅니다.
testFile.js
//1만을 더해주는 함수 function numberPlus(number,callback){ //함수를 저번처럼 비동기로 만들어 봅시다. setTimeout(function(){ for(var i=0; i<10000; i++){ number++; } callback(number);; },10); } module.exports.printNumber=numberPlus;
테스트가 잘 되는 것을 확인 할 수 있습니다.
이번 화에서는 TDD와 BDD에 대해 조금 알아보았는데요.
다음 프로젝트에는 BDD를 이용해 프로그래밍 해보시는게 어떨까요?
'IT 놀이터 > Elite Member Tech & Talk' 카테고리의 다른 글
[6기 강북 윤덕진]리눅스 쉘 스크립트 프로그래밍 #1 (0) | 2014.10.10 |
---|---|
[6기 강북 이보희] 디지털 영상처리 - Filter 편 #2 (0) | 2014.10.10 |
[6기 부산 정희록] Pillow #1 (0) | 2014.10.08 |
[6기 부산 정희록] Beautiful Soup #3 (0) | 2014.10.07 |
[6기 강북 전영진] 리눅스 커널 심층 분석 #2 (0) | 2014.10.06 |