오늘도 한주가 끝났다. 어쩌다보니 전혀 예정에 없던 줄서는 식당에 가버려서 거진 15시간만에 집에 도착했다. 그래도 좀있다 애 씻기고 맥주한잔 하기로 했다. 내일은 즐거운 주말. 출근만 안해도 이리도 행복할 줄이야.
이번 범위는 총 2장이다. 사실 "9장 단위 테스트"라고 되어 있으니 9장만 이야기한것 같기도 하지만....이왕 읽은거 경계도 같이 작성해본다.
현재 세상에서 하나의 언어를 선택해서 처음부터 끝까지 자신이 직접 작업한 코드로만 프로그램을 만드는건 사실상 불가능할 것이다. 각 언어의 표준 라이브러리는 그렇다 쳐도, Java에는 Maven, Python에는 PyPI, Node.JS는 npm 등. 기본적으로 우리는 다른 개발자가 만들어놓은 다른 코드를 활용하여 내가 만들고자 하는 기능을 제공하게 될것이다.
우리가 아무리 팀으로 활동하고, 팀의 규칙을 정하며 활동을 한다고 하더라도, 개발자는 결국 사람이다. 사람은 성격과 개성을 가지고 있으니, 세상의 모든 사람은 특별하다고 할 수 있다. 개발자가 작성한 코드도 마찬가지. 10명의 개발자가 모이면 아무리 규칙을 정한다고 하더라도, 규칙의 테두리 내에서 어떻게든 자신의 개성이 드러나는 코드를 작성하게 될것이다. 규칙을 벗어나거나
하물며 남이 작성한 코드가 얼마나 나의 스타일을 따라서 만들어져 있을까? 조금이라도 비슷하면 다행일 것이다. 8장 경계는 이런 다른 사람이 만든 코드를 좀더 안정적으로 나의 코드에 포함시키는 방법에 대한 논의라고 볼 수 있다.
9장 단위 테스트는 나의 죄악이다. 나는 정말 테스트 작성을 잘 못한다. 좀 해보겠다고 TDD도 사두었는데, 읽을때는 재밌지만 솔직히 적용하는건 정말 어려운 일인것 같다. 하지만 프로젝트를 하다보면 필요성은 확실히 느낄 수 있다. 관리되지 않은 테스트 코드를 가지고 있다면 나의 변경사항이 어떤 영향을 미치게 될지 누가 알 수 있을까? 어찌보면 8장의 이야기와도 일맥상통 하는데, 우리가 사용하는 라이브러리, 프레임워크 등이 안정적으로 잘 돌아가는 것을 보장하는것도 저자들이 작성한 테스트 코드들이다. 이번 챌린지가 끝나고 지금 작업중인 프로젝트가 마무리되면 테스트 코드 작성부터 다시 해봐야겠다.
시스템에 들어가는 모든 소프트웨어를 직접 개발하는 경우는 드물다.
패키지 제공자나 프레임워크 제공자는 적용성을 최대한 넓히려 애쓴다.
누군가가 자신이 만든 코드를 Maven이든 npm이든 올린다면 그건 보통 다른 개발자가 자신이 만든것을 사용하고 자신의 이름을 널리 펼치기 위해서일 것이다. 물론 순수하게 공익적 목적일 수도 있고. 어찌됬든 이런 코드의 생리는 어찌보면 장사의 생리와도 비슷한데, 결국 고객(개발자)를 얼마나 끌어들이느냐에 문제라는 이야기다.
그러니 우리 서비스의 특수한 구조, 우리만의 특별한 요구사항에 완벽히 대응되는 코드란 존재하기 어렵고, 마찬가지로 아주 특수한 기능을 제공하는 패키지는 많이 사용되기 어렵다. 그렇기 때문에 대부분 공개된 코드는 아주 일반적인 기능을 대부분 제한 없이 제공하기 마련이다.
가령 책에서 이야기한 Map
인터페이스 같은 것이다. Map
은 HashTable
등 Key - Value로 데이터를 저장하기 위한 객체들을 나타내는 인터페이스인데, Map
을 사용하도록 유도하는 입장에서는 데이터를 저장하는 put
만 제공하고 데이터를 회수하는 get
같은 메서드를 제공하지 않는다면 당연히 Map
을 사용하는 개발자는 없을것이다. 요즘이라면 ChatGPT한테 물어만 봐도 적당한 Map
구현체를 만들어줄텐데 말이다.
그래서 만약 Map
의 기능을 일부만 사용하고 싶다면, 책에서 나온것처럼 자신의 목적을 묘사한 별도의 클래스로 한번 감싸주어 일부 기능만 제공하는 방법이 있을것이다.
public class Sensors {
private Map sensors = new HashMap();
public Sensor getById(String id) {
return (Sensor) sensors.get(id);
}
}
어찌보면 Spring 등지에서 많이 활용하는 DAO도 비슷한 목적을 가지고 있다고 볼 수 있지 않을까? DAO 내부에서라면 순수 JDBC를 사용하던, MyBatis를 사용하던, JPA를 사용하던 큰 문제가 되지 않을 것이다. 또한 DAO를 인터페이스로 만든다면 기술 발전에 따라 다른 기술을 사용하던 구현체를 좀더 쉽게 교체할 수 있을것이다. 그것이 실행중에 실제 알고리즘을 결정하는, Strategy Pattern의 모습 아니었나? (물론 이 형식은 DAO에만 국한된 이야기가 아니지만)
암튼 결론은 Map
을 이용해 특정 클래스나 메서드 내부에서 사용하는 것은 괜찮지만, 데이터를 이리저리 주고받아야 하는 상황에는 Map
을 직접적으로 넘기는 것을 지양해야 한다는 의미이다.
그래서 외부 라이브러리를 사용하기 전에 단위 테스트 등으로 외부 코드가 어떻게 동작하는지 살펴보는 시간이 있으면 좋을것이다. 이를 학습 테스트라고 부른다.
외부 라이브러리를 사용하는 방법을 익히기 위한 학습 테스트는 결국 사용해야되는 외부 라이브러리의 사용법을 익히는 방법이다. 그리고 자연스럽게 자신의 목적에 맞는 동작을 하는지가 테스트 코드로 작성이 된다. 그러면 라이브러리의 업그레이드가 자신의 목적에 맞지 않을 경우 테스트 코드가 이를 감지할 수 있다.
아직 존재하지 않는 코드, 예를들어 다른 팀과 협업 중에 어떻게 코드를 사용할지 결정이 되어있지 않은 경우 추상화를 적극적으로 활용한다.
GOF는 수많은 디자인 패턴을 만들어냈고, 객체지향 진영의 발전에 눈부신 기여를 했다고 생각한다. 어댑터 패턴은 코드로 만드는 여행용 어댑터 같은 개념으로 생각하면 된다. 꽂는 구멍과 꽂아야 되는 구멍의 크기 차이를 효율적으로 변환해주듯이, 구현 클래스의 바깥의 사용법을 유지한채 실제 사용해야하는 코드를 격리하여 관리할 수 있게 해준다.
Mock을 만드는 것과 비슷하므로, 결국 테스트에도 도움을 주는 방식이다.
우리 분야는 지금까지 눈부신 성장을 이뤘지만 앞으로 갈 길은 여전히 멀다.
실제 코드가 진화하면 테스트 코드도 변해야 한다는 데 있다. 그런데 테스트 코드가 지저분할 수록 변경하기 어려워진다.
테스트 코드는 내 코드가 올바른 방향으로 유지되어 변경되었다는 지표라고 생각된다. 내가 기능을 만들고, 해당 기능이 정상적으로 동작하는지 확인하는 테스트 코드를 작성해두면, 추후 내가 코드를 변경했을 때 기능의 변경이 이전 동작을 해하는지 자동으로 확인해주는 것이 테스트 코드이다.
당연하지만 기능이 변하면 테스트 코드도 같이 변하기 마련이다. 하지만 대충 만든 테스트 코드는 새로운 기능이 추가될 때 더 많은 테스트를 작성하는데 걸림돌로 작용하게 된다. 그리고 개발자는 언젠가는 버려야할 레거시 코드마냥 테스트 코드를 폐기하게 될지도 모른다.
테스트 코드는 실제 코드 못지 않게 중요하다.
테스트 케이스가 있으면 변경이 두렵지 않으니까!
...
테스트 케이스가 있으면 변경이 쉬워지기 때문이다.
실제 환경과 테슽 환경은 요구사항이 판이하게 다르다.
우리가 작성한 코드는 여러 환경에서 실행될 가능성이 있다. 예를 들어 대부분의 부트캠프를 비롯한 과정에서는 AWS를 비롯한 클라우드를 활용하고, 가능하면 free tier에서 구성된 실습 환경을 활용하는 경우가 많다. AWS free tier의 경우 Ubuntu t2였나 t3였나를 micro 사이즈로 제공한다. 인터넷 속도는 둘째치코, micro의 메모리는 1GB이다. minikube도 간신히 돌아가....지 않는다. 엄밀히 말하면 2GB를 요구하는 minikube기 때문에.
하지만 테스트 환경은 어떤 컴퓨터에서 하더라도 괜찮으니 자원을 상대적으로 더 활용할 수 있다. 일반적으로 알고리즘 문제풀이에는 사용해서는 안되는 "반복문 내부의 String
concatenation"또한 큰 문제가 되지 않는다.
아...단위 테스트 부분이 너무 부실해 보인다. 아무래도 혼자 개발할때는 재미 위주의 개발이고, 단발성 발전 적은 프로젝트라 단위 테스트를 덜 작성해서 그런지 모르겠다. 반성하고, 앞으로라도 테스트 코드 꼼꼼히 작성해주자.
지금 현재 북클럽 챌린지를 함께하고 계신 분들 것을 살펴보았는데
https://mgcllee.github.io/ 이분이 블로그 열심히 작성하시면서 코드도 C 계열 코드로 재현하고 있어서 보는 재미가 있는것 같다.
https://nomadcoders.co/community/thread/10181 이분 글도 정성이 느껴져서 읽는 보람이 있다.
https://velog.io/@hjeong1200/posts 이분 TIL이 가볍게 읽기 좋은 느낌이다.