오늘의 학습 TDD !!
테스트 코드 흠,,, 너무 어려워요 ㅠ뿌에 뭔가 흐름이 이상하달까요? 어색해서 더 그런거겠징,,,,
이번 팀 프로젝트를 할 때 테스트코드가 어렵기도하고.. 시간부족으로 인해
못해봐서 아쉬웠는데 이렇게 TDD 제대로 공부할 시간이 생겼네욤 ㅎㅎ
그래서 해보니 네. 어려워서 크흠.... ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅎ
그럼 그 테스트 코드란?
- 원래 보통 코드 작성 시, main에 작성했다면 테스트 코드는 test 디렉터리에 작성한다!

요깅 ㅎㅎㅎㅎㅎ
테스트 코드 작성할 땐 given-when-then 패턴이 존재하는데 세단계로 구분해 작성하는 방식!
| 1. given: 테스트 실행을 위해 필요한 데이터를 준비하는 단계 2. when: 테스트를 진행하는 단계 3. then: when에서 수행한 테스트 결과를 검증하는 단계 |
@DisplayName("새로운 메뉴를 저장한다.")
@Test
public void saveMenuTest() {
// given : 메뉴를 저장하기 위한 준비 과정
String name = "카페라떼";
int price = 5500;
Menu latte = new Menu(name, price);
// when : 실제로 메뉴를 저장
long saveId = menuService.save(latte);
// then : 메뉴가 잘 추가되었는지 검증
Menu savedMenu = menuService.findById(saveId).get();
assertThat(savedMenu.getName()).isEqualTo(name);
assertThat(savedMenu.getPrice()).isEqualTo(price);
}
메뉴 저장하기 위해 준비과정인 given, 메뉴 저장하는 when절, 메뉴가 잘 추가되었는지 검증하는 then절 나누어져있도다!
여기서!
참고로, assertThat 인 메소드는 Import해야한다!
import static org.assertj.core.api.Assertions.*;
클래스를 static import 하면 사용가능!
테스트 종류
1. 단위 테스트(Unit Test)
단위 테스트는 소프트웨어의 가장 작은 단위 즉 함수, 메소드 또는 클래스 같은 개별적인 컴포넌트를 테스트하는 것
- 해당 컴포넌트의 동작이 올바른지 확인한다. 개발자가 작성한 코드가 예상대로 작동되는지 빠르게 확인가능!
-코드 변경으로 인한 예기치 않은 부작용을 미리 방지하고, 코드를 수정할 때마다 안정성을 유지할 수 있다.
2. 통합테스트(Integration Test)
통합테스트는 둘 이상의 단위가 결합된 시스템의 동작을 테스트 하는 것
- 보통 단위테스트 이후 수행한다.
단위테스트가 개별적으로 테스트하는거라면! 통합테스트는 컴포넌트들이 다같이 작동할 시, 상호작용이 잘 되는지 확인하는 과정인 것!
- 시스템의 전반적인 품질을 검증하는 데 중요한 역할을 한다.
= 단위 테스트와 통합테스트는 함께 사용되며, 소프트웨어의 품질 보장과 코드 변경 시, 안전하고 신뢰할 수 있도록 한다.
테스트 코드 장점
| 1. 신뢰성 향상 2. 안정감 상승 3. 문서화 4. 품질 향상 |
JUnit 테스트
JUnit은 자바언어를 위한 단위 테스트 프레임워크!
| JUnit의 특징 → 테스트 방식을 구분할 수 있는 어노테이션 제공 : @Test 어노테이션으로, 메소드를 호출할 때마다 새 인스턴스를 생성, 독립테스트 가능 → 예상 결과를 검증하는 Assertion 메소드 제공 → 사용 방법이 단순, 테스트 코드 작성 시간이 적음 → 자동 실행, 자체 결과를 확인하고 즉각적인 피드백을 제공 |
| @BeforeAll 어노테이션 전체 테스트를 시작하기 전에 처음으로 한 번만 실행합니다. 예를 들어 데이터베이스를 연결해야 하거나 테스트 환경을 초기화할 때 사용합니다. 이 어노테이션은 전체 테스트 실행 주기에서 한 번만 호출되어야 하기 때문에 메소드를 static으로 선언해야 합니다. @BeforeEach 어노테이션 테스트 케이스를 시작하기 전에 매번 실행합니다. 예를 들어 테스트 메소드에서 사용하는 객체를 초기화하거나 테스트에 필요한 값을 미리 넣을 때 사용할 수 있습니다. 각 인스턴스에 대해 메소드를 호출해야하므로 메소드는 static이 아니어야 합니다. @AfterAll 어노테이션 전체 테스트를 마치고 종료하기 전에 한 번만 실행합니다. 예를 들어 데이터베이스 연결을 종료할 때나 공통적으로 사용하는 자원을 해제할 때 사용할 수 있습니다. 전체 테스트 실행주기에서 한 번만 호출되어야 하므로 메소드를 static으로 선언해야 합니다. @AfterEach 어노테이션 각 테스트 케이스를 종료하기 전 매번 실행합니다. 예를 들어 테스트 이후에 특정 데이터를 삭제해야 하는 경우 사용합니다. @BeforeEach 어노테이션과 마찬가지로 메소드는 static이 아니어야 합니다. |

AssertJ로 검증문 가독성 높이기
AssertJ로 가독성 높여보자!
Assertions.assertEquals(sum, a + b);
원래는 이렇게 기댓값과 실제값이 구분되지 않았다면 AssertJ를 사용하면?
assertThat(a + b).isEqualTo(sum);
a b를 더한것이 sum과 같아야한다는게 명확해졌도다!!!~~~~~~~~~~~
|
메소드 이름
|
설명
|
|
isEqualTo(A)
|
A 값과 같은지 검증
|
|
isNotEqualTo(A)
|
A 값과 다른지 검증
|
|
contains(A)
|
A 값을 포함하는지 검증
|
|
doesNotContains(A)
|
A 값을 포함하지 않는지 검증
|
|
startsWith(A)
|
A 값으로 시작하는지 검증
|
|
endsWith(A)
|
A 값으로 끝나는지 검증
|
|
isEmpty()
|
비어있는 값인지 검증
|
|
isNotEmpty()
|
비어있지 않은 값인지 검증
|
|
isPositive()
|
양수인지 검증
|
|
isNegative()
|
음수인지 검증
|
|
isGreaterThan(1)
|
1보다 큰 값인지 검증
|
|
isLessThan(1)
|
1보다 작은 값인지 검증
|
다양한 메소드가 있다는거 ㅎㅎㅎㅎ
테스트 주도 개발의 진행 방식
TDD를 이용한 개발은 크게 질문 > 응답 > 정제 단계를 반복적으로 이루어진다.
질문 : 테스트 작성을 통해 시스템에 질문합니다. (테스트 수행 결과는 실패)
응답 : 테스트를 통과하는 코드를 작성해서 질문에 대답합니다. (테스트 성공)
정제 : 아이디어를 통합하고, 불필요한 것은 제거하고, 모호한 것은 명확하게 해서 대답을 정제합니다. (리팩토링)
반복 : 다음 질문을 통해 대화를 계속 진행합니다.

단계를 은행계좌 송금/출금 서비스로 실습해보았답니다!!!
<구현단계>
1. 계좌 생성
2. 잔고 조회
3. 입금/ 출금
public class AccountTest {
@BeforeEach
void setUp(){
Account account = new Account(10000);
}
/*
//1. 계좌 생성
@DisplayName("계좌 생성 테스트")
@Test
void 계좌_생성() throws Exception{
Account account = new Account(10000); //먼저 작성 후,
}
*/
//2, 잔고 조회(10000원으로 계좌 생성 > 잔고 조회 결과 일치)
@DisplayName("잔고 조회")
@Test
void 잔고_조회(){
Account account = new Account(10000);
assertEquals(account.getBalance(), 10000);
account = new Account(100);
assertEquals(account.getBalance(),100);
account = new Account(9000);
assertEquals(account.getBalance(),9000);
}
//3. 입금 가능
@Test
void testDeposit(){
Account account = new Account(10000);
account.deposit(1000);
// if (account.getBalance() != 11000){
// throw new Exception("입금 실패");
// }
assertEquals(account.getBalance(), 11000);
}
//출금가능
@Test
void testWithdraw(){
Account account = new Account(10000);
account.withdraw(1000);
assertThat(account.getBalance()).isEqualTo(9000);
}
}
public class Account {
private int balance;
public Account(int seed) {
balance = seed;
}
public int getBalance() {
return balance;
}
public void deposit(int money) {
balance += money;
}
public void withdraw(int money) {
balance -= money;
}
}
여기서 코드 정제를 한다면, 반복적으로 Account 객체를 초기화 하는 Account account = new Account(10000);
이 부분을 @BeforeEach 어노테이션을 사용하여 공통코드로 뽑아내면 코드가 더욱 깔끔해진다는거!!!
이렇게 코드 정리하고 리팩토링하는 정제가 마지막단계 ㅎㅎ
종합적으로 정리하면,
질문 - “코드가 예상대로 동작하는지 판단해줘” 코드로 질문 했고, 시스템은 에러메시지를 보여주며 “실패했으니 수정해”
응답 - 시스템이 보여준 에러메시지에 응답 = 테스트 케이스에 성공하도록 메인 코드 작성
정제 - 코드 정리, 리팩토링
이것이 TDD!!!
오늘은 이렇게 테스트 코드에 대해 짧게 배웠는데
흠 이해는 가지만 프로젝트때 써보라 하면 못하겠는??????
더 연습이 필요하다는 거겠졍 ㅎㅎㅎ 테스트 코드 관련해서 강사님께서 책을 추천해주셨는데
기회가 되면 사서 공부해봐야겠어요!!! ㅎㅎㅎ
오늘도 열심히 했구!
내일도 파이팅!!!!!!!!!!!!!

'[4기] 백엔드 개발자 부트캠프 "오르미" ~ing > [4기] 백엔드 개발자 부트캠프 오르미 수업 복습' 카테고리의 다른 글
| [4기] 109일차 Github중급 (0) | 2024.04.19 |
|---|---|
| [4기] 108일차 TDD (Mockito) (2) | 2024.04.19 |
| [4기] 106일차 Docker2 (0) | 2024.04.16 |
| [4기] 105일차 Docker1 (0) | 2024.04.15 |
| [4기] 73일차 AWS( 클라우드 서버 (2) | 2024.03.14 |