zero-wiki Help

테스트와 코드 품질 관리하기

테스트에 유의하자

p-233

주문과 주문 상세가 하나씩 매핑되는 경우를 간과하고, 1:N 관계에서 N을 하나로 두고 테스트를 진행했고, 뒤늦게 버그를 발견해 distinct 옵션을 추가한 이슈가 있습니다. 그래서 각 주문별로 3개씩 주문상세를 생성하도록 했습니다.

이를 통해 잘못된 테스트는 오히려 독이 될 수 있다라는 점을 알게 되었습니다. 테스트란 결국 프로그램이 정상 동작함을 증명할 수 있는 수단인데, 프로그램의 오류가 존재하는데 테스트가 통과한다는 모순이 생길 수 있습니다. 테스트를 작성하 때는 최대한 예외 케이스부터, 해피 케이스 순서로 다양한 경우를 커버할 수 있어야 한다는 생각이 들었습니다.

외부 라이브러리를 사용하는 것

p-238

멀미 모듈 과제를 진행하면서 외부 라이브러리를 사용했는데요, 외부 라이브러리를 선택할 때 받은 기준에 대한 피드백도 공유해봅니다.

  • 제어권의 유무: 직접 작성한 코드를 사용하는 것이 아니기에 외부 라이브러리를 수정하거나, 수정 요청하는 등의 작업이 가능해야 합니다. 직접적으로 코드를 제어할 수 있거나 수정 요청 시 빠르게 반영되는 것이 중요합니다.

  • 공식 지원 유무: 프레임워크 차원에서 외부 라이브러리의 의존성을 관리하고 지원하기 때문에 조금 더 안정성이 올라갈 수 있습니다.

  • 커스텀 지원: 사용자의 입맛에 맞게 확장할 수 있는 형태인지도 중요합니다. 확장 포인트가 잘 열려 있으며 사용하는 데 어려움이 없는 것도 중요합니다.

  • 안정성: 많은 사람이 사용하고 검증한 라이브러리인지 등 안정적으로 운영 중인지에 대한 요인들을 검토합니다.

  • 마지막 수정/커밋: 위에서 제시한 기준을 충족하려면 사용자가 요구하는 방향으로 지속해서 유지보수되어야 하기 때문에 마지막 커밋은 중요합니다.

기본에 충실한 개발자가 되자

p-244

비즈니스 요구사항보단, '어떤 설계가 더 나은 설계이고 어떻게 해야 더 나은 코드를 잘 수 있을까?'에 대한 고민이 늘 앞섰습니다. 물론 이런 고민이 나쁘다고 생각하지는 않지만 무엇보다 요구사항을 명확히, 그리고 당연한 것을 당연히 되도록 하는 일을 우선으로 해야합니다.

스스로 해내야 한다.

우아한테크코스에서는 늘 모두와 함께 고민하며 가장 치ㅗ적의 해를 찾아가는 과정이 일반적인데요, 현업에서는 항상 누군가와 함께할 수 없으며 문제를 해결할 때 스스로의 역량을 발휘하는 것이 필요합니다. 혼자서 해내는 것이 아직은 낯설지만 새로운 기술과 베스트 프랙티스를 늘 고민한다면 언젠가 빠르게 베스트 프렉티스를 적용할 수 있는 개발자가 되지 않을까라는 생각입니다.

내가 작성하는 코드는 레거시가 된다.

실무에 투입되면 제가 작성하는 코드 한 줄이 정산 시스템에서 작동합니다. 당연하지만 늘 가볍게 생각하고 코드를 작성하던 저에게는 또 다른 부담이자 기대감으로 다가옵니다. 그동안 유지보수하기 좋은 코드, 객체지향적인 코드 등 항상 이론으로만 혼자 하는 프로젝트에서만 적용해봤는데요, 이제 정말 내가 작성한 코드가 누군가가 유지보수할 대상이라고 생각하니 더욱 열심히 학습하고 고민하며 코드를 작성해야겠다고 느꼈습니다.

기존 작성된 코드에 테스트를 추가하는 방법.

p-259

  1. 기존에 동작하는 코드를 기반으로 사용자 시나리오를 작성합니다. a 상황에 따라 어떻게 동작하는지를 전부 분류합니다. b 기존에 작성해준 조건들이 빈약하거나 고려하지 못했던 엣지 케이스를 발견할 수 있습니다. 추가로 정리해줍니다.

  2. 사용자 시나리오를 기반으로 테스트 코드를 작성합니다. a 1-b처럼 고렿지 못했던 엣지 케이스를 발견한 게 아니라면, 이미 동작하는 코드를 기반으로 테스트를 작성하는 거라 전부 성공 케이스가 나옵니다.

  3. 리팩터링 a 컴포넌트를 분리하고, 코드를 분리하고, 로직을 간단하게 변경합니다. b 여기서 테스크 코드의 강력함을 경험할 수 있습니다.

기존에 동작하는 코드를 기반으로 사용자 시나리오 작성

컴포넌트로 분리한 코드를 보면서 어떻게 동작하는지 사용자 시나리오를 정리합니다.

코드에서 if문이 있듯, 시나리오를 작성할 때도 특정 조건을 기준으로 분기하며 작성해줍니다. 코드에서 if문 안에 여러 조건이복잡하게 작성되어 있는 것을 하나씩 풀어서 분류해봅니다. 이 과정을 통해 내가 작성했던 맹점들을 발견하게 될 수도 있습니다.

앞에서 작성한 사용자 시나리오를 바탕으로 테스트를 작성합니다. if문 조건을 기준으로 컨텍스트를 나누고, 해당 컨텍스트 안에서 실행되어야 하는 테스트를 작성해서 하나씩 테스트합니다.

상태 관리 라이브러리에서 사용하는 값을 더미데이터를 이용해 원하는 대로 렌더링하여 테스트할 수 있습니다. 이미 작성된 코드를 검증하는 테스트 코드라 실패하는 것 없이 잘 통과합니다. 이제 테스트를 믿고 리팩터링을 할 수 있습니다.

효과는 굉장합니다.

p-266

테스트 코드를 통해 원하는 상황을 검증할 수 있습니다. 이를 통해 기존에 가지고 있던 두려움도 해소할 수 있었고 컴포넌트를 간결하게 분리한 덕분에 발주 상세페이지에서 정리되지 않은 코드에 새로운 것을 추가해야하는 위험이 사라졌고 테스트 코드가 기존 동작에 대해서 안정성을 보장해주니 새 기능을 추가하다 발생하는 부작용 걱정을 덜 수 있게 되었습니다.

테스트를 작성해보니 좋은 효과들이 있었습니다.

첫재, 컴포넌트를 분리해야하는 명확한 기준과 근거가 생겼습니다. 기존에는 '컴포넌트가 너무 크니까 적당하게 나눠야겠다'라고 생각했다면 이제는 테스트하기 좋은 코드를 기준으로 나누게 되었습니다. 그리고 이 기준은 같이 일하는 팀원들과 논의할 때도 공통의 기준으로 삼았습니다. 다른 기준을 가지고 '어떤 기준이 더 적합한가?'가 아니라, 같은 기준 안에서 '어떻게 하면 더 테스트 하기 좋은 코드일까?'를 고민하게 됐다는 점이 좋았습니다. 둘째, 기능동작에 대한 문서화를 따로 할 필요가 없어졌습니다. '나중에 이 부분에 대한 코드를 나 말고 다른 사람이 이해할 수 있을까?' 고민이 항상 있었는데, 테스트 코드가 곧 명세가 되어버리니 따로 코드를 설명하기 위해 문서화할 필요가 없어졌습니다. 셋째, 코드가 간결해졌습니다. 테스트를 작성하기 위해 컴포넌트를 나누게 되는데, 이때 '어디까지가 같은 역할을 하는 코드인가?'를 고민하고 이 고민은 자연스럽게 단일 책임 원칙을 지키는 방향으로 이루어집니다. 이를 통해 결과적으로 더 나은 구조로 컴포넌트를 분리해서 사용하게 됩니다. 마지막으로 MECE하게 시나리오를 작성하다 보니 숨겨진 엣지 케이스를 찾아내게 됐습니다. 처음 기능을 구현할 때부터 고려하고 작성했으면 좋겠지만 그러지 못했던 코드에 대해 테스트 코드를 작성하면서 고려하지 못한 경우를 찾아내게 됩니다.

Last modified: 07 August 2024