본문 바로가기
반응형

테스트 코드16

1. 테스트하기 좋은 코드 - 테스트하기 어려운 코드 팀 분들과 함께 NextStep - 이펙티브 코틀린 강좌를 수강하고 있다. 최근에 과제 회고를 처음 진행했는데, 이때 나온 주제가 테스트 하기 좋은 코드였다. 이 주제는 사실 이미 너무 많이 회자된 주제이긴하다. 대표적으로 아래 2개가 가장 대표적이다. 정진욱님 - Testing, Oh my! 권용근님 - 무엇을 테스트할 것인가 이들을 다 보았다면, 굳이 이 글을 볼 필요는 없다. 이미 잘 정리된 글과 영상이지만, 현재 팀의 분들을 위해서 조금 정리하게 되었다. 뒤에 이어 쓸 Active Record vs Data Mapper의 빌드업이기도 하다. 이 글에서는 테스트하기 어려운 코드 대해 이야기해보려고 한다. 1. 테스트 하기 좋은 코드? 여기서 이야기하는 테스트는 단위 테스트를 의미한다. E2E 테스트.. 2022. 6. 11.
expect에서 false와 falsy 구분하기 Jest로 테스트 코드를 작성하다보면 습관적으로 IDE의 자동완성으로 toBeFalsy 와 toBeTruthy 를 사용하곤 했다. 저 둘이 아닌 toBe(false) 와 toBe(true) 는 한 번의 자동완성으로 안되기 때문에 굳이 사용하진 않았다. 그러다 팀 분의 의견을 받고 더이상 toBeFalsy() 는 사용하진 않고 있다. 물론 이에 맞는 쓰임새가 있겠지만, 모든 결과를 강타입으로 처리하는걸 선호하는 입장에서는 toBeFalsy() 는 선호하기가 어렵다. 다음과 같은 이유 때문이다. toBeFalsy() 는 JS에서 false로 판단되는 모든 값들을 기준으로 한다 내가 의도한것은 boolean 타입의 false 를 원했지만, 수행 결과가 0, undefined, null, '' 이면 toBeFa.. 2022. 4. 13.
단언문 (expect/assert) 안에서 비교하지 않기 간혹 코드를 보면 expect 에서 비교를 하는 코드를 보곤 한다. 이를테면 다음과 같은 경우이다. it('getCount의 결과는 5보다 크다', () => { const result = getCount(); expect(result > 5).toBe(true); }); 당장 봐서는 문제가 없어보인다. 오히려 비교값이 더 큰지 검증하는 jest 함수를 별도로 찾아보지 않아도 된다는 장점도 있어보인다. 비슷한 예제로 다음과 같은 코드도 종종 보게 된다. it('getCount의 값은 10과 동일하다', () => { const count = getCount(); expect(count === 10).toBe(true); }); 하지만 이 테스트 코드들은 크게 2개의 단점을 갖고 있다. (정확히는 잘못된 .. 2022. 4. 10.
Jest로 Error 검증시 catch 보다는 expect Jest를 통한 테스트를 작성하다보면 Exception에 대한 검증을 작성해야할 때가 있다. 이럴때 보통 2가지 방법 중 하나를 선택한다. try ~ catch expect.rejects.toThrowError 실제 코드로는 다음과 같다. // try ~ catch it("[try/catch] 주문금액이 -이면 BadParameter Exception 을 던진다.", async () => { try { await acceptOrder({amount: -1000}); } catch (e) { expect(e).toBeInstanceOf(BadParameterException); expect(e.message).toBe('승인 요청 주문의 금액은 -가 될 수 없습니다'); } }); // expect it(.. 2022. 3. 18.
테스트코드에서 Optional chaining(?.) 쓰지않기 여러 포스팅에서 언급한것처럼 테스트 코드는 빠르게 실패를 파악할 수 있어야 한다. 그런면에서 Optional chaining(?.) 은 테스트코드에 적합하지 않다. MDN의 설명을 가져오면 Optional chaining(?.)은 체이닝 연산자(.) 와 유사하게 작동하지만, 만약 참조가 nullish (null 또는 undefined)이라면, 에러가 발생하는 것 대신에 표현식의 리턴 값을 undefined로 반환한다. 따라서 참조가 누락될 가능성이 있는 경우 연결된 속성으로 접근할 때 더 짧고 간단한 표현식이 생성된다. 어떤 속성이 필요한지에 대한 보증이 확실하지 않는 경우 객체의 내용을 탐색하는 동안 도움이 될 수 있다. 안정적으로 객체 탐색이 가능하기 때문에 프로덕션 코드에서는 적극적으로 사용하는 편.. 2022. 3. 8.
조건부 (if~else) 로직 테스트코드에서 사용하지 않기 테스트 코드는 프로젝트의 생명 주기 보다 길때가 많다. 기존의 요구사항을 정리한것이 테스트 코드이기 때문에, 메인 코드보다 훨씬 더 읽기쉬워야만 한다. 만약 테스트 코드가 복잡한 경우 어떻게 작동하는지 이해하기가 어렵다. 그래서 테스트 코드는 주석이 필요 없을 정도로 간단해야 한다. 그런면에서 조건부 (if ~ else) 테스트 로직은 테스트를 실제보다 더 복잡하게 만드는 요인 중 하나다. 이번 글에서는 조건부 로직을 테스트에서 사용한 경우에 어떻게 개선할 수 있을지 알아본다. 1. 가변 결과를 검증하는 경우 1-1. 문제 첫번째 문제는 다음과 같이 테스트 실행때마다 결과가 달라지는 경우이다. it('[Bad] 가변결과 검증', () => { const now = LocalDateTime.now(); c.. 2022. 3. 7.

728x90
반응형