3주차 리팩토링 스터디에서는 테스트의 중요성과 구축 방법에 대해 알아보았습니다. Mocha.js와 같은 테스트 프레임워크를 통해 어떻게 테스트를 구성하는지, 어느 부분에서 테스트를 추가하는지 등의 주된 내용입니다. 본문에선 책의 내용보단 스터디를 진행하며 나왔던 곁들이면 좋을 내용들을 위주로 포스팅합니다. 책에 실려있던 내용들은 리팩토링 스터디 #2.5 - 내용 미리보기를 참고해주세요.
테스트 코드
챕터의 주제가 테스트인 만큼 어느때보다 테스트 자체에 대한 이야기가 많이 나왔습니다. 필요성에 대해서는 크게 의견이 갈리지는 않았습니다만, TDD(Test-Driven Development, 테스트 주도 개발) 에 대해서는 호불호가 꽤 나뉘었다고 합니다. 필드에서는 책에서의 예들이 완전히 적용되지않는 다양한 상황이 있으니 이해가 되는 부분이었습니다. 하지만 테스트 코드를 포함해 반드시 알아둬야 할 개념임에는 변화가 없는 것 같습니다.
저자가 책에서 테스트부터 작성하는 방식으로 프로그래밍을 했을 때 얻을 수 있는 이점으로 언급한 내용 중 구현보다는 인터페이스에 집중하게 해준다 라는 말이 있습니다. 심지어 (무조건 좋은 일이다) 라고 덧붙이며 두 번이나 강조를 했던 내용이기에 짚고 넘어갔는데, 인터페이스에 대한 개념이 확실하게 잡혀있지 않다면 언뜻 와닿지 않을 수 있는 표현이어서 이해를 돕기위한 구체적인 예가 몇 가지 제시되었는데 다음과 같습니다.
사용하는 쪽에서 어떤 인터페이스를 사용할 것인지 확인할 수 있어 코드끼리 올바른 협력관계를 맺도록 도와줍니다.
외부에는 인터페이스만 노출되어야 하는데, 자칫 상세한 구현부를 노출하게 되는 경우가 있을 수 있습니다. 이런 부분들은 앞 장에서 이야기했었던 코드에서 나는 악취가 될 수 있습니다.
이 외에도 외부에서 호출해서 사용할 때 필요한 부분만 가져가서 사용하는 구조를 만들기 쉽다는 장점 등이 있습니다. 다만 테스트 코드를 작성하는데 너무 자주 바뀌거나 막힌다면 지금 테스트 하고 있는 부분이 올바른 구조로 작성되어있는지 생각해 보는 것이 좋다고 합니다. 한 함수에 하나의 기능이라는 기본적인 틀을 생각해보면 받아들이기에 그리 어렵지 않을 것 같습니다.
테스트 프레임워크
이 책에서는 테스트 프레임워크로 모카(Mocha.js)를 사용하였습니다. 사실 모카도 이름만 들어봤지 사용해 본 적이 없어서 낯설었는데, 다른 종류의 테스트 프레임워크의 이름도 몇 가지 들어볼 수 있었습니다. 조금 정리해보겠습니다.
모카는 대표적인 자바스크립트 테스트 프레임워크입니다. 다양한 어썰션(assertion) 라이브러리를 불러와서 사용할 수 있습니다. 대표적으로는 차이(Chai.js)가 있습니다. 커뮤니티 생태계가 주도하여 개발되는 오픈소스라는 특징이 있습니다. 누구든 개발에 참여하거나, 후원금을 보내는 식으로 유지보수에 기여할 수 있습니다.
제스트는 단순함에 초점을 둔 자바스크립트 테스트 프레임워크입니다. 페이스북의 개발자들이 주도하여 개발하였으며 적절하게만 사용한다면 거의 모든 범위를 테스트 할 수 있습니다. 이전부터 존재하던 프레임워크인 Jasmine을 기반으로 만들어졌습니다.
간단히 사용 방법을 정리한 포스팅도 있습니다.
본문의 예제는 모카를 이용하였지만, 프로젝트에 어울리는 프레임워크를 사용하여 테스트를 진행하시면 될 것 같습니다. 이 책을 이해하는데 도구는 그리 중요한 요소가 아닙니다. 예시의 언어를 자바스크립트로 선택한 것도 단순히 많은 개발자들이 읽고 이해하기 쉬워서니까요.
자바스크립트의 몇 가지 특징
리팩토링과 직접적으로 관련이 있지는 않지만, 코드에 관한 질문도 있었습니다.
short-circuit evaluation이라고 부르는 OR 연산자 ( || ) 를 다음과 같이 사용하는 이유에 대한 이야기였는데요.
this._production = data.production || 0;
this의 _production 에게 data.production의 값을 대입하고, 만약 대입할 수 없는 경우 0을 넣어주라는 의미까지는 알았습니다. 단순히 코드를 해석하기에는 문제가 없어서 그냥 넘어갔었는데 왜 하필 0을 넣어야 했는지에 대한 이유가 있었습니다.
자바스크립트에서는 값을 찾을 수 없을 때 호출하게되면 undefined로 처리하게 됩니다. 이렇게 undefined를 반환하는 대신 프로그래머가 예측 가능한 값인 0을 넣어주는 것이 방어적인 프로그래밍을 하는데 도움이 된다고 하네요.
연산자에 대한 이야기로 시작해서인지 못보던 연산자들이 더 등장했습니다.
let element = a ?? 0
물음표 두개 ( ?? ) 로 이루어진 이 연산자는 널 병합 연산자(nullish coalescing)라고 부릅니다. 좌측의 피연산자가 null 또는 undefined이면 오른쪽의 피연산자를 반환하고, 그렇지 않을 경우 좌측의 피연산자를 반환합니다. 우리가 아는 익숙한 코드로 풀어쓰면 이렇게 됩니다.
let element = a ? a : 0
삼항 연산자 ( ? ) 는 많이 보셨을거라고 생각합니다. 저는 이렇게 보니 바로 알 것 같네요.
옵셔널 체이닝( ?. ) 이라고 불리는 연산자도 있습니다. 체인에 대한 검증 없이 연결된 객체의 속성 값을 반환합니다.
// 이 코드는
a?.b()
// 이 코드와 같습니다
if (a !== undefined && a != null) a.b()
참조하는 (위 코드에서는 a) 객체가 null이나 undefined를 반환하면(nullish 하면) 똑같이 undefined를 반환해주고, 아니라면 속성 값을 반환합니다.
널 병합 연산자와 옵셔널 체이닝의 경우 표준이 된지 얼마 안 된 연산자들입니다. (ES2020에서 표준으로 추가되었습니다.) 혹시 사용하게 된다면 Babel을 준비해두시는게 좋을 것 같네요. 아직까지도 ie를 고려하지 않을 수 없는 현실입니다...
마치며
추석 연휴를 앞두고 진행된 스터디여서 내용이 평소보다 짧았습니다. 그만큼 정리하는 포스트의 길이도 짧아졌네요. 다음 스터디는 한 주 쉬어가고, 그 후에 본격적인 리팩토링 기법을 다루어봅니다. 2주 후에 각종 리팩토링 스킬들로 뵙겠습니다.
'기타' 카테고리의 다른 글
리팩토링 스터디 #4 - 기본적인 리팩터링 (0) | 2020.11.03 |
---|---|
리팩토링 스터디 #3.5 - 내용 미리보기 (0) | 2020.10.12 |
리팩토링 스터디 #2.5 - 내용 미리보기 (0) | 2020.09.26 |
리팩토링 스터디 #2 - 리팩토링 원칙 & 코드에서 나는 악취 (2) | 2020.09.21 |
리팩토링 스터디 #1.5 - 내용 미리보기 (2) | 2020.09.19 |
댓글