- 테스트 자동화는 앞으로 풀어야 할 과제에서뿐만 아니라 현업에서도 광범위하게 쓰입니다.
테스트는 왜 해야 하는가?
- 개발 중엔 콘솔 창 등을 이용해 실제 실행 결과가 기대했던 결과와 같은지 계속 비교하면서 원하는 기능이 잘 구현되고 있는지 확인할 겁니다.
- 실제 실행 결과가 기대했던 결과와 다를 땐, 코드를 수정하고 다시 실행해 그 결과를 기대했던 결과와 다시 비교해 볼 겁니다. 원하는 기능을 완성할 때까지 이 과정을 계속 반복하겠죠.
- 코드를 수동으로 ‘재실행’ 하면서 테스트를 하면 무언가를 놓치기 쉽습니다.
Behavior Driven Development
- BDD는 테스트(test), 문서(documentation), 예시(example)를 한데 모아놓은 개념입니다.
개발 순서
실제 개발에 착수하면 아래와 같은 순서로 개발이 진행됩니다.
- 명세서 초안을 작성합니다. 초안엔 기본적인 테스트도 들어갑니다.
- 명세서 초안을 보고 코드를 작성합니다.
- 코드가 작동하는지 확인하기 위해 Mocha라 불리는 테스트 프레임워크를 사용해 명세서를 실행합니다.(Mocha에 대해선 아래에서 다룰 예정입니다.) 이때, 코드가 잘못 작성되었다면 에러가 출력됩니다. 개발자는 테스트를 모두 통과해 에러가 더는 출력되지 않을 때까지 코드를 수정합니다.
- 모든 테스트를 통과하는 코드 초안이 완성되었습니다.
- 명세서에 지금까진 고려하지 않았던 유스케이스 몇 가지를 추가합니다. 테스트가 실패하기 시작할 겁니다.
- 세 번째 단계로 돌아가 테스트를 모두 통과할 때까지 코드를 수정합니다.
- 기능이 완성될 때까지 3~6단계를 반복합니다.
스펙 실행하기
.
.
.
<script>
// chai의 다양한 기능 중, assert를 전역에 선언합니다.
let assert = chai.assert;
</script>
</head>
<script>
function pow(x, n) {
/* 코드를 여기에 작성합니다. 지금은 빈칸으로 남겨두었습니다. */
}
</script>
<!-- 테스트(describe, it...)가 있는 스크립트를 불러옵니다. -->
<script src="test.js"></script>
<!-- 테스트 결과를 id가 "mocha"인 요소에 출력하도록 합니다.-->
<div id="mocha"></div>
<!-- 테스트를 실행합니다! -->
<script>
mocha.run();
</script>
요약
BDD에선 스펙을 먼저 작성하고 난 후에 구현을 시작합니다. 구현이 종료된 시점에는 스펙과 코드 둘 다를 확보할 수 있습니다.
스펙의 용도는 세 가지입니다.
- 테스트 – 함수가 의도하는 동작을 제대로 수행하고 있는지 보장함
- 문서 – 함수가 어떤 동작을 수행하고 있는지 설명해줌. describe와 it에 설명이 들어감
- 예시 – 실제 동작하는 예시를 이용해 함수를 어떻게 사용할 수 있는지 알려줌
테스트를 하지 않고 코드를 작성해왔다면 개발자들은 둘 중 한 갈래의 길로 빠져버리고 맙니다.
- 아무 대책 없이 코드를 변경합니다. 부작용을 생각하지 않고 함수를 수정했기 때문에 어디선가 버그가 발생하고 맙니다.
- 수정이나 개선을 기피하게 됩니다. 버그의 대가가 가혹하기 때문이죠. 코드가 구식이 되어도 그 누구도 코드를 건드리려 하지 않습니다. 좋지 않은 상황이죠.
테스트를 작성하려면 함수가 어떤 동작을 하는지, 입력값은 무엇이고 출력값은 무엇인지 정의하고 난 후에 구현을 시작합니다.
코드는 정의된 사항을 뒷받침 할 수 있게 작성해야 하죠. 구현을 시작하는 순간부터 이미 좋은 아키텍처가 보장됩니다.
사실, 매번 이런 절차를 따라 구현한다는 게 쉽지만은 않습니다.
함수가 어떻게 동작해야 하는지 확신이 서지 않는 상황에서 코드를 작성하기도 전에 스펙을 작성해야 하므로 익숙하지 않을 수 있습니다.
그렇지만 테스트를 작성하면 일반적으로 개발 속도가 빨라지고 이전보다 코드를 더 안정적으로 작성할 수 있습니다.