블로그
전체 22025. 03. 16.
0
[워밍업 클럽 3기 BE code] 2주차
테스트가 필요한 이유사람이 애플리케이션을 실행하면서 잘 작동되는지 확인하는 작업은 놓칠 수도 있고, 시간이 오래 걸려 비효율적이다.테스트 코드 작성의 이점빠른 피드백: 코드 수정 후 바로 검증 가능자동화: 반복적인 수동 테스트가 불필요안정성: 코드 변경이 발생해도 기존 기능이 정상 동작하는지 보장디버깅 용이: 문제 발생 시 원인 파악이 쉬움단위 테스트작은 코드 단위를 독립적으로 검증하는 테스트 → 검증 속도가 빠르고 안정적이다.관련 라이브러리JUnit5: 단위 테스트를 위한 테스트 프레임워크AssertJ: 테스트 코드 작성을 원활하게 돕는 라이브러리수동 테스트 vs 자동화된 테스트 비교수동 테스트사람이 직접 성공/실패를 판단실수 가능성 높음반복이 어려움시간이 오래 걸림자동화된 테스트시스템이 자동으로 판단실수 가능성 낮음반복이 쉬움소요 시간이 짧음 자동화된 테스트를 활용하면 수동 테스트의 한계를 극복할 수 있다.자동화 테스트를 작성하면 테스트 결과만 확인하면 되므로 빠르고 정확하다.테스트 케이스 세분화하기해피 케이스(정상 동작)*만 작성하지 않고 예외 케이스(예상하지 못한 상황)도 함께 테스트해야 한다.TDD (Test Driven Development)프로덕션 코드보다 테스트 코드를 먼저 작성하여, 테스트가 구현 과정을 주도하도록 하는 개발 방법론빠른 피드백을 통해 코드 품질을 높이고, 유연한 설계를 가능하게 함TDD의 장점내 코드의 피드백을 빠르게 받을 수 있음리팩토링이 쉬워짐 → 테스트가 있으므로 기존 기능이 정상 동작하는지 보장됨테스트 가능한 코드 설계 → 단일 책임 원칙(SRP)에 맞게 코드 구조를 고민하게 됨디버깅 시간 단축 → 기능 개발 중 발생하는 문제를 사전에 방지할 수 있음기능 구현 방식 비교방식 장점 단점선 기능 구현, 후 테스트 작성장점 : 구현이 직관적이고 빠르게 가능단점 : 테스트 누락 가능성, 특정 케이스만 검증, 잘못된 구현 발견 지연 선 테스트 작성, 후 기능 구현 (TDD)장점 : 테스트가 어려운 영역을 미리 발견하여 설계를 개선할 수 있음단점 : 초기 개발 속도가 다소 느릴 수 있음TDD의 핵심 원칙: Red → Green → Refactor1⃣ Red (실패하는 테스트 작성)테스트 코드를 먼저 작성하고 실행 → 아직 기능이 없으므로 테스트가 실패해야 한다.2⃣ Green (기능 구현하여 테스트 통과)테스트가 통과하도록 최소한의 기능을 구현한다.3⃣ Refactor (리팩토링)중복 제거, 코드 개선을 통해 더 나은 구조로 변경한다.리팩토링 후에도 테스트가 통과하는지 확인한다.테스트는 [문서]다테스트 코드는 해당 기능의 동작을 설명하는 문서 역할을 한다.@DisplayName을 활용하여 테스트 목적을 명확히 하자.@DisplayName("회원 가입 시 이메일이 중복되면 예외가 발생한다") @Test void 회원가입_이메일중복_예외발생() { // Given // When // Then }생각 정리테스트의 중요성에 대해서는 인지하고 있었지만 테스트 코드 작성이 항상 귀찮고 어렵게 느껴졌었다. 하지만 테스트 코드를 작성하고 결과를 확인하는 과정 자체가 더 나은 프로덕션 코드를 만드는 과정이 될 수 있다는 것을 깨달았다.특히 TDD의 경우에는 기능이 없는데 테스트 코드를 먼저 작성하는게 이해가 안 됐었는데 테스트를 실패하는 최소한의 기능을 먼저 만들고 점진적으로 더 나은 코드 작성 및 설계를 할 수 있도록 유도하는 과정이라는 것을 알게 되었다. 강의https://www.inflearn.com/course/practical-testing-%EC%8B%A4%EC%9A%A9%EC%A0%81%EC%9D%B8-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B0%80%EC%9D%B4%EB%93%9C/dashboard
2025. 03. 09.
0
[워밍업 클럽 3기 BE code] 1주차
잘 읽히는 코드 작성하기메서드 선언부를 잘 활용하자메서드 이름을 잘 짓는 것도 중요하지만 메서드 시그니처도 중요하다메서드 사용자가 쉽게 이해하고 사용할 수 있도록 적절한 타입을 활용하자특정 매개변수가 해당 메서드에서 어떤 행위를 위한 것인지 파악할 수 있도록 이름을 지어주는 것도 좋다void를 반환하는 메서드가 있다면 반환할 만한 값이 없는지 다시 한번 확인해보자메서드를 추출하고 끝이 아니라 여러 방면에서 계속 고민해보자단순히 코드가 짧아지는 것을 떠나서 메서드의 역할이 명확한지, 사용하는 쪽에서 읽기 쉬운지 고민해봐야한다리팩토링을 한 뒤에는 꼭 검증을 해서 프로그램이 잘 돌아가는지 확인해보자추상화 레벨주변과 동등한 추상화 레벨을 가져야 코드가 잘 읽힌다메서드를 호출하여 사용하는 쪽은 외부 세계 / 메서드가 구현되어 있는 쪽은 내부 세계로 나누어서 서로의 추상화 레벨을 동등하게 가져가자즉 메서드를 호출하는 코드가 계속 나열되다가 구체적인 조건을 따지는 코드를 읽으면 가독성이 떨어지게 된다특정 조건을 따지는 코드는 메서드로 추출해서 사용하는 외부 세계에서는 메서드명으로 행위를 유추하도록 하자Early return뇌는 하나의 작업만을 할 수 있는데 조건문을 이해하기 위해 여러 조건을 뇌 메모리에 올려두게 된다생각하던 걸 멈추고 다른 걸 생각해야 함Early return을 활용해 if 조건에 해당하면 return을 해버리자 -> 그럼 return되는 if 문만 기억하면 됨else를 사용하지 말자는게 아니라 굳이 사용이 필요하지 않다면 return 해버리자객체 설계하기setter를 지양막연하게 그래야 되는 구나 라고 생각하고 있었는데 데이터가 변하더라도 객체 자신이 자신의 데이터를 핸들링 해야 한다는 것, setter 메서드는 그 의미에서부터 맞지 않다는 것을 이해하게 되었다외부에서 해당 객체의 데이터를 핸들링하면 안된다 → 객체 지향 의미부터 완전히 맞지 않음데이터를 변경해야 하는 경우 네이밍 자체도 set ~이 아닌 update ~로 지어주는 것이 좋다getter 지양사실 코드를 작성하면서 getter를 자주 사용하는 편이었는데 객체에게 무례한 것이라는 말이 와닿았다person.get지갑.get신분증.findAge >= 19검증이 필요한 상황에서는 객체에 메서드를 만들어 메서드와 소통하는 것이 옳다객체 지향 프로그래밍 = 객체와 소통하며 협력하기person.isAgeGreaterThanOrEqualTo(19)SOLID 원칙SRP : 하나의 클래스는 변경의 이유가 하나만 존재하도록 단일 책임만 가진다OCP : 기존 코드를 수정하지 않고, 확장에는 열려 있고 수정에는 닫혀 있어야 한다LSP : 자식 클래스가 부모 클래스를 대체해도 기능은 깨지지 않고 의도대로 동작해야 한다ISP : 클라이언트가 자신이 사용하지 않는 기능에 의존하지 않도록 인터페이스를 작고 명확하게 분리한다DIP : 상위 계층은 하위 계층의 구현체가 아닌 추상체(인터페이스)에 의존하도록 설계한다강의https://www.inflearn.com/course/readable-code-%EC%9D%BD%EA%B8%B0%EC%A2%8B%EC%9D%80%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%82%AC%EA%B3%A0%EB%B2%95