๑ `⌃´ ๑
Spring
비관적 락 / SELECT ... FOR UPDATE / PESSIMISTIC_WRITE
2026.08.31
Spring
비관적 락 / SELECT ... FOR UPDATE / PESSIMISTIC_WRITE
2026.08.31
비관적 락은 “이 데이터는 충돌할 가능성이 높다”고 보고, 한 트랜잭션이 수정하려는 데이터를 잡고 있는 동안 다른 트랜잭션이 기다리게 만드는 방식Transaction ASELECT ... FOR UPDATE→ Product 행 Lock 획득Transaction B같은 Product 조회 시도→ 기다림A재고 차감COMMIT→ Lock 해제B이제 조회→ A가 반영한 최신 재고 확인→ 차감 1. 왜 이름이 "비관적" 락일까?처음부터 "여러 사용자가 같은 데이터를 동시에 수정하면 충돌할 가능성이 높다"고 생각하기 때문.그래서 충돌이 실제로 일어난 뒤 처리하는 것이 아니라, "아예 먼저 잠가놓고 다른 트랜잭션이 기다리게 하자"는 접근 2. 문제 상황DB stock = 100Transaction ASELECT ..
비관적 락 / SELECT ... FOR UPDATE / PESSIMISTIC_WRITE
2026.08.31
비관적 락은 “이 데이터는 충돌할 가능성이 높다”고 보고, 한 트랜잭션이 수정하려는 데이터를 잡고 있는 동안 다른 트랜잭션이 기다리게 만드는 방식Transaction ASELECT ... FOR UPDATE→ Product 행 Lock 획득Transaction B같은 Product 조회 시도→ 기다림A재고 차감COMMIT→ Lock 해제B이제 조회→ A가 반영한 최신 재고 확인→ 차감 1. 왜 이름이 "비관적" 락일까?처음부터 "여러 사용자가 같은 데이터를 동시에 수정하면 충돌할 가능성이 높다"고 생각하기 때문.그래서 충돌이 실제로 일어난 뒤 처리하는 것이 아니라, "아예 먼저 잠가놓고 다른 트랜잭션이 기다리게 하자"는 접근 2. 문제 상황DB stock = 100Transaction ASELECT ..
→
💙
비관적 락 / SELECT ... FOR UPDATE / PESSIMISTIC_WRITE
2026.08.31
2026.08.31
비관적 락은 “이 데이터는 충돌할 가능성이 높다”고 보고, 한 트랜잭션이 수정하려는 데이터를 잡고 있는 동안 다른 트랜잭션이 기다리게 만드는 방식Transaction ASELECT ... FOR UPDATE→ Product 행 Lock 획득Transaction B같은 Product 조회 시도→ 기다림A재고 차감COMMIT→ Lock 해제B이제 조회→ A가 반영한 최신 재고 확인→ 차감 1. 왜 이름이 "비관적" 락일까?처음부터 "여러 사용자가 같은 데이터를 동시에 수정하면 충돌할 가능성이 높다"고 생각하기 때문.그래서 충돌이 실제로 일어난 뒤 처리하는 것이 아니라, "아예 먼저 잠가놓고 다른 트랜잭션이 기다리게 하자"는 접근 2. 문제 상황DB stock = 100Transaction ASELECT ..
비관적 락 / SELECT ... FOR UPDATE / PESSIMISTIC_WRITE
2026.08.31
비관적 락은 “이 데이터는 충돌할 가능성이 높다”고 보고, 한 트랜잭션이 수정하려는 데이터를 잡고 있는 동안 다른 트랜잭션이 기다리게 만드는 방식Transaction ASELECT ... FOR UPDATE→ Product 행 Lock 획득Transaction B같은 Product 조회 시도→ 기다림A재고 차감COMMIT→ Lock 해제B이제 조회→ A가 반영한 최신 재고 확인→ 차감 1. 왜 이름이 "비관적" 락일까?처음부터 "여러 사용자가 같은 데이터를 동시에 수정하면 충돌할 가능성이 높다"고 생각하기 때문.그래서 충돌이 실제로 일어난 뒤 처리하는 것이 아니라, "아예 먼저 잠가놓고 다른 트랜잭션이 기다리게 하자"는 접근 2. 문제 상황DB stock = 100Transaction ASELECT ..
비관적 락 / SELECT ... FOR UPDATE / PESSIMISTIC_WRITE
2026.08.31
비관적 락은 “이 데이터는 충돌할 가능성이 높다”고 보고, 한 트랜잭션이 수정하려는 데이터를 잡고 있는 동안 다른 트랜잭션이 기다리게 만드는 방식Transaction ASELECT ... FOR UPDATE→ Product 행 Lock 획득Transaction B같은 Product 조회 시도→ 기다림A재고 차감COMMIT→ Lock 해제B이제 조회→ A가 반영한 최신 재고 확인→ 차감 1. 왜 이름이 "비관적" 락일까?처음부터 "여러 사용자가 같은 데이터를 동시에 수정하면 충돌할 가능성이 높다"고 생각하기 때문.그래서 충돌이 실제로 일어난 뒤 처리하는 것이 아니라, "아예 먼저 잠가놓고 다른 트랜잭션이 기다리게 하자"는 접근 2. 문제 상황DB stock = 100Transaction ASELECT ..
비관적 락 / SELECT ... FOR UPDATE / PESSIMISTIC_WRITE
2026.08.31
비관적 락은 “이 데이터는 충돌할 가능성이 높다”고 보고, 한 트랜잭션이 수정하려는 데이터를 잡고 있는 동안 다른 트랜잭션이 기다리게 만드는 방식Transaction ASELECT ... FOR UPDATE→ Product 행 Lock 획득Transaction B같은 Product 조회 시도→ 기다림A재고 차감COMMIT→ Lock 해제B이제 조회→ A가 반영한 최신 재고 확인→ 차감 1. 왜 이름이 "비관적" 락일까?처음부터 "여러 사용자가 같은 데이터를 동시에 수정하면 충돌할 가능성이 높다"고 생각하기 때문.그래서 충돌이 실제로 일어난 뒤 처리하는 것이 아니라, "아예 먼저 잠가놓고 다른 트랜잭션이 기다리게 하자"는 접근 2. 문제 상황DB stock = 100Transaction ASELECT ..
비관적 락 / SELECT ... FOR UPDATE / PESSIMISTIC_WRITE
2026.08.31
비관적 락은 “이 데이터는 충돌할 가능성이 높다”고 보고, 한 트랜잭션이 수정하려는 데이터를 잡고 있는 동안 다른 트랜잭션이 기다리게 만드는 방식Transaction ASELECT ... FOR UPDATE→ Product 행 Lock 획득Transaction B같은 Product 조회 시도→ 기다림A재고 차감COMMIT→ Lock 해제B이제 조회→ A가 반영한 최신 재고 확인→ 차감 1. 왜 이름이 "비관적" 락일까?처음부터 "여러 사용자가 같은 데이터를 동시에 수정하면 충돌할 가능성이 높다"고 생각하기 때문.그래서 충돌이 실제로 일어난 뒤 처리하는 것이 아니라, "아예 먼저 잠가놓고 다른 트랜잭션이 기다리게 하자"는 접근 2. 문제 상황DB stock = 100Transaction ASELECT ..
Spring
ExecutorService / CountDownLatch / 동시성 테스트
2026.08.29
Spring
ExecutorService / CountDownLatch / 동시성 테스트
2026.08.29
목표초기 재고를 100이라 한다. `stock = 100`100번 차감하면 정상적인 결과는 `100 - 100 = 0`이다.그런데 여러 스레드가 동시에 `stockService.decrease(productId);`를 호출하게 한 뒤 최종 재고를 확인한다.기대값 = 0실제값 = ?예: 73 81 64 ... 일반 테스트로는 순차 실행되기 때문에 동시성 문제를 재현하기 어렵다.Thread A ──────────┐Thread B ──────────┤Thread C ──────────┤ 동시에 같은 재고 접근Thread D ──────────┤... │Thread N ──────────┘위와 같은 상황을 만들어야하기 때문에, `ExecutorService`, `Cou..
ExecutorService / CountDownLatch / 동시성 테스트
2026.08.29
목표초기 재고를 100이라 한다. `stock = 100`100번 차감하면 정상적인 결과는 `100 - 100 = 0`이다.그런데 여러 스레드가 동시에 `stockService.decrease(productId);`를 호출하게 한 뒤 최종 재고를 확인한다.기대값 = 0실제값 = ?예: 73 81 64 ... 일반 테스트로는 순차 실행되기 때문에 동시성 문제를 재현하기 어렵다.Thread A ──────────┐Thread B ──────────┤Thread C ──────────┤ 동시에 같은 재고 접근Thread D ──────────┤... │Thread N ──────────┘위와 같은 상황을 만들어야하기 때문에, `ExecutorService`, `Cou..
→
💙
ExecutorService / CountDownLatch / 동시성 테스트
2026.08.29
2026.08.29
목표초기 재고를 100이라 한다. `stock = 100`100번 차감하면 정상적인 결과는 `100 - 100 = 0`이다.그런데 여러 스레드가 동시에 `stockService.decrease(productId);`를 호출하게 한 뒤 최종 재고를 확인한다.기대값 = 0실제값 = ?예: 73 81 64 ... 일반 테스트로는 순차 실행되기 때문에 동시성 문제를 재현하기 어렵다.Thread A ──────────┐Thread B ──────────┤Thread C ──────────┤ 동시에 같은 재고 접근Thread D ──────────┤... │Thread N ──────────┘위와 같은 상황을 만들어야하기 때문에, `ExecutorService`, `Cou..
ExecutorService / CountDownLatch / 동시성 테스트
2026.08.29
목표초기 재고를 100이라 한다. `stock = 100`100번 차감하면 정상적인 결과는 `100 - 100 = 0`이다.그런데 여러 스레드가 동시에 `stockService.decrease(productId);`를 호출하게 한 뒤 최종 재고를 확인한다.기대값 = 0실제값 = ?예: 73 81 64 ... 일반 테스트로는 순차 실행되기 때문에 동시성 문제를 재현하기 어렵다.Thread A ──────────┐Thread B ──────────┤Thread C ──────────┤ 동시에 같은 재고 접근Thread D ──────────┤... │Thread N ──────────┘위와 같은 상황을 만들어야하기 때문에, `ExecutorService`, `Cou..
ExecutorService / CountDownLatch / 동시성 테스트
2026.08.29
목표초기 재고를 100이라 한다. `stock = 100`100번 차감하면 정상적인 결과는 `100 - 100 = 0`이다.그런데 여러 스레드가 동시에 `stockService.decrease(productId);`를 호출하게 한 뒤 최종 재고를 확인한다.기대값 = 0실제값 = ?예: 73 81 64 ... 일반 테스트로는 순차 실행되기 때문에 동시성 문제를 재현하기 어렵다.Thread A ──────────┐Thread B ──────────┤Thread C ──────────┤ 동시에 같은 재고 접근Thread D ──────────┤... │Thread N ──────────┘위와 같은 상황을 만들어야하기 때문에, `ExecutorService`, `Cou..
ExecutorService / CountDownLatch / 동시성 테스트
2026.08.29
목표초기 재고를 100이라 한다. `stock = 100`100번 차감하면 정상적인 결과는 `100 - 100 = 0`이다.그런데 여러 스레드가 동시에 `stockService.decrease(productId);`를 호출하게 한 뒤 최종 재고를 확인한다.기대값 = 0실제값 = ?예: 73 81 64 ... 일반 테스트로는 순차 실행되기 때문에 동시성 문제를 재현하기 어렵다.Thread A ──────────┐Thread B ──────────┤Thread C ──────────┤ 동시에 같은 재고 접근Thread D ──────────┤... │Thread N ──────────┘위와 같은 상황을 만들어야하기 때문에, `ExecutorService`, `Cou..
ExecutorService / CountDownLatch / 동시성 테스트
2026.08.29
목표초기 재고를 100이라 한다. `stock = 100`100번 차감하면 정상적인 결과는 `100 - 100 = 0`이다.그런데 여러 스레드가 동시에 `stockService.decrease(productId);`를 호출하게 한 뒤 최종 재고를 확인한다.기대값 = 0실제값 = ?예: 73 81 64 ... 일반 테스트로는 순차 실행되기 때문에 동시성 문제를 재현하기 어렵다.Thread A ──────────┐Thread B ──────────┤Thread C ──────────┤ 동시에 같은 재고 접근Thread D ──────────┤... │Thread N ──────────┘위와 같은 상황을 만들어야하기 때문에, `ExecutorService`, `Cou..
Spring
JPA 영속성 컨텍스트 / Dirty Checking / Flush
2026.08.26
Spring
JPA 영속성 컨텍스트 / Dirty Checking / Flush
2026.08.26
@Transactional 시작 ↓ Entity 조회 ↓ Entity가 영속 상태가 됨 ↓ Entity의 값 변경 ↓ JPA가 변경을 감지 ↓ flush ↓ UPDATE SQL 실행 ↓ commit 1. JPA에서 `findById()`를 하면 무슨 일이 일어날까?평소에는 보통 이렇게 생각한다.Product product = productRepository.findById(productId).orElseThrow();단순하게 보면 `DB에서 Product를 가져온다`고 생각할 수 있다.그런데 JPA에서는 한 가지 일이 더 있다.조회한 `Product` 객체를 영속성 컨텍스트가 관리하기 시작할 수 있다.Database │ │ SELECT ▼Pro..
JPA 영속성 컨텍스트 / Dirty Checking / Flush
2026.08.26
@Transactional 시작 ↓ Entity 조회 ↓ Entity가 영속 상태가 됨 ↓ Entity의 값 변경 ↓ JPA가 변경을 감지 ↓ flush ↓ UPDATE SQL 실행 ↓ commit 1. JPA에서 `findById()`를 하면 무슨 일이 일어날까?평소에는 보통 이렇게 생각한다.Product product = productRepository.findById(productId).orElseThrow();단순하게 보면 `DB에서 Product를 가져온다`고 생각할 수 있다.그런데 JPA에서는 한 가지 일이 더 있다.조회한 `Product` 객체를 영속성 컨텍스트가 관리하기 시작할 수 있다.Database │ │ SELECT ▼Pro..
→
💙
JPA 영속성 컨텍스트 / Dirty Checking / Flush
2026.08.26
2026.08.26
@Transactional 시작 ↓ Entity 조회 ↓ Entity가 영속 상태가 됨 ↓ Entity의 값 변경 ↓ JPA가 변경을 감지 ↓ flush ↓ UPDATE SQL 실행 ↓ commit 1. JPA에서 `findById()`를 하면 무슨 일이 일어날까?평소에는 보통 이렇게 생각한다.Product product = productRepository.findById(productId).orElseThrow();단순하게 보면 `DB에서 Product를 가져온다`고 생각할 수 있다.그런데 JPA에서는 한 가지 일이 더 있다.조회한 `Product` 객체를 영속성 컨텍스트가 관리하기 시작할 수 있다.Database │ │ SELECT ▼Pro..
JPA 영속성 컨텍스트 / Dirty Checking / Flush
2026.08.26
@Transactional 시작 ↓ Entity 조회 ↓ Entity가 영속 상태가 됨 ↓ Entity의 값 변경 ↓ JPA가 변경을 감지 ↓ flush ↓ UPDATE SQL 실행 ↓ commit 1. JPA에서 `findById()`를 하면 무슨 일이 일어날까?평소에는 보통 이렇게 생각한다.Product product = productRepository.findById(productId).orElseThrow();단순하게 보면 `DB에서 Product를 가져온다`고 생각할 수 있다.그런데 JPA에서는 한 가지 일이 더 있다.조회한 `Product` 객체를 영속성 컨텍스트가 관리하기 시작할 수 있다.Database │ │ SELECT ▼Pro..
JPA 영속성 컨텍스트 / Dirty Checking / Flush
2026.08.26
@Transactional 시작 ↓ Entity 조회 ↓ Entity가 영속 상태가 됨 ↓ Entity의 값 변경 ↓ JPA가 변경을 감지 ↓ flush ↓ UPDATE SQL 실행 ↓ commit 1. JPA에서 `findById()`를 하면 무슨 일이 일어날까?평소에는 보통 이렇게 생각한다.Product product = productRepository.findById(productId).orElseThrow();단순하게 보면 `DB에서 Product를 가져온다`고 생각할 수 있다.그런데 JPA에서는 한 가지 일이 더 있다.조회한 `Product` 객체를 영속성 컨텍스트가 관리하기 시작할 수 있다.Database │ │ SELECT ▼Pro..
JPA 영속성 컨텍스트 / Dirty Checking / Flush
2026.08.26
@Transactional 시작 ↓ Entity 조회 ↓ Entity가 영속 상태가 됨 ↓ Entity의 값 변경 ↓ JPA가 변경을 감지 ↓ flush ↓ UPDATE SQL 실행 ↓ commit 1. JPA에서 `findById()`를 하면 무슨 일이 일어날까?평소에는 보통 이렇게 생각한다.Product product = productRepository.findById(productId).orElseThrow();단순하게 보면 `DB에서 Product를 가져온다`고 생각할 수 있다.그런데 JPA에서는 한 가지 일이 더 있다.조회한 `Product` 객체를 영속성 컨텍스트가 관리하기 시작할 수 있다.Database │ │ SELECT ▼Pro..
JPA 영속성 컨텍스트 / Dirty Checking / Flush
2026.08.26
@Transactional 시작 ↓ Entity 조회 ↓ Entity가 영속 상태가 됨 ↓ Entity의 값 변경 ↓ JPA가 변경을 감지 ↓ flush ↓ UPDATE SQL 실행 ↓ commit 1. JPA에서 `findById()`를 하면 무슨 일이 일어날까?평소에는 보통 이렇게 생각한다.Product product = productRepository.findById(productId).orElseThrow();단순하게 보면 `DB에서 Product를 가져온다`고 생각할 수 있다.그런데 JPA에서는 한 가지 일이 더 있다.조회한 `Product` 객체를 영속성 컨텍스트가 관리하기 시작할 수 있다.Database │ │ SELECT ▼Pro..
Spring
[TDD] 자연어 요구사항을 테스트 케이스로 바꾸기
2026.08.21
Spring
[TDD] 자연어 요구사항을 테스트 케이스로 바꾸기
2026.08.21
이미 사용된 쿠폰은 사용할 수 없다. 이런 요구사항이 있다고 예를 들자.if (coupon.isUsed()) { ...} 바로 위와 같은 코드를 생각하는 것이 아니라,먼저 이렇게 생각해야 한다.누가 사용하는가?어떤 상태여야 사용할 수 있는가?사용하면 상태가 어떻게 바뀌는가?어떤 경우에 실패해야 하는가?실패하면 기존 상태는 어떻게 되어야 하는가? 왜 요구사항을 바로 코드로 옮기면 안될까?자연어 요구사항은 생각보다 모호하다.`쿠폰을 사용할 수 있다.` 이 문장만 보고 구현하면 여러 질문이 빠진다.누가 사용할 수 있지?본인 쿠폰만 가능한가?이미 사용한 쿠폰은?존재하지 않는 쿠폰은?유효기간은?사용한 뒤에는 어떤 상태가 되지?실패했을 때 상태는? 개발자가 이런 것을 정리하지 않고 바로 구현하면 코드 안에서..
[TDD] 자연어 요구사항을 테스트 케이스로 바꾸기
2026.08.21
이미 사용된 쿠폰은 사용할 수 없다. 이런 요구사항이 있다고 예를 들자.if (coupon.isUsed()) { ...} 바로 위와 같은 코드를 생각하는 것이 아니라,먼저 이렇게 생각해야 한다.누가 사용하는가?어떤 상태여야 사용할 수 있는가?사용하면 상태가 어떻게 바뀌는가?어떤 경우에 실패해야 하는가?실패하면 기존 상태는 어떻게 되어야 하는가? 왜 요구사항을 바로 코드로 옮기면 안될까?자연어 요구사항은 생각보다 모호하다.`쿠폰을 사용할 수 있다.` 이 문장만 보고 구현하면 여러 질문이 빠진다.누가 사용할 수 있지?본인 쿠폰만 가능한가?이미 사용한 쿠폰은?존재하지 않는 쿠폰은?유효기간은?사용한 뒤에는 어떤 상태가 되지?실패했을 때 상태는? 개발자가 이런 것을 정리하지 않고 바로 구현하면 코드 안에서..
→
💙
[TDD] 자연어 요구사항을 테스트 케이스로 바꾸기
2026.08.21
2026.08.21
이미 사용된 쿠폰은 사용할 수 없다. 이런 요구사항이 있다고 예를 들자.if (coupon.isUsed()) { ...} 바로 위와 같은 코드를 생각하는 것이 아니라,먼저 이렇게 생각해야 한다.누가 사용하는가?어떤 상태여야 사용할 수 있는가?사용하면 상태가 어떻게 바뀌는가?어떤 경우에 실패해야 하는가?실패하면 기존 상태는 어떻게 되어야 하는가? 왜 요구사항을 바로 코드로 옮기면 안될까?자연어 요구사항은 생각보다 모호하다.`쿠폰을 사용할 수 있다.` 이 문장만 보고 구현하면 여러 질문이 빠진다.누가 사용할 수 있지?본인 쿠폰만 가능한가?이미 사용한 쿠폰은?존재하지 않는 쿠폰은?유효기간은?사용한 뒤에는 어떤 상태가 되지?실패했을 때 상태는? 개발자가 이런 것을 정리하지 않고 바로 구현하면 코드 안에서..
[TDD] 자연어 요구사항을 테스트 케이스로 바꾸기
2026.08.21
이미 사용된 쿠폰은 사용할 수 없다. 이런 요구사항이 있다고 예를 들자.if (coupon.isUsed()) { ...} 바로 위와 같은 코드를 생각하는 것이 아니라,먼저 이렇게 생각해야 한다.누가 사용하는가?어떤 상태여야 사용할 수 있는가?사용하면 상태가 어떻게 바뀌는가?어떤 경우에 실패해야 하는가?실패하면 기존 상태는 어떻게 되어야 하는가? 왜 요구사항을 바로 코드로 옮기면 안될까?자연어 요구사항은 생각보다 모호하다.`쿠폰을 사용할 수 있다.` 이 문장만 보고 구현하면 여러 질문이 빠진다.누가 사용할 수 있지?본인 쿠폰만 가능한가?이미 사용한 쿠폰은?존재하지 않는 쿠폰은?유효기간은?사용한 뒤에는 어떤 상태가 되지?실패했을 때 상태는? 개발자가 이런 것을 정리하지 않고 바로 구현하면 코드 안에서..
[TDD] 자연어 요구사항을 테스트 케이스로 바꾸기
2026.08.21
이미 사용된 쿠폰은 사용할 수 없다. 이런 요구사항이 있다고 예를 들자.if (coupon.isUsed()) { ...} 바로 위와 같은 코드를 생각하는 것이 아니라,먼저 이렇게 생각해야 한다.누가 사용하는가?어떤 상태여야 사용할 수 있는가?사용하면 상태가 어떻게 바뀌는가?어떤 경우에 실패해야 하는가?실패하면 기존 상태는 어떻게 되어야 하는가? 왜 요구사항을 바로 코드로 옮기면 안될까?자연어 요구사항은 생각보다 모호하다.`쿠폰을 사용할 수 있다.` 이 문장만 보고 구현하면 여러 질문이 빠진다.누가 사용할 수 있지?본인 쿠폰만 가능한가?이미 사용한 쿠폰은?존재하지 않는 쿠폰은?유효기간은?사용한 뒤에는 어떤 상태가 되지?실패했을 때 상태는? 개발자가 이런 것을 정리하지 않고 바로 구현하면 코드 안에서..
[TDD] 자연어 요구사항을 테스트 케이스로 바꾸기
2026.08.21
이미 사용된 쿠폰은 사용할 수 없다. 이런 요구사항이 있다고 예를 들자.if (coupon.isUsed()) { ...} 바로 위와 같은 코드를 생각하는 것이 아니라,먼저 이렇게 생각해야 한다.누가 사용하는가?어떤 상태여야 사용할 수 있는가?사용하면 상태가 어떻게 바뀌는가?어떤 경우에 실패해야 하는가?실패하면 기존 상태는 어떻게 되어야 하는가? 왜 요구사항을 바로 코드로 옮기면 안될까?자연어 요구사항은 생각보다 모호하다.`쿠폰을 사용할 수 있다.` 이 문장만 보고 구현하면 여러 질문이 빠진다.누가 사용할 수 있지?본인 쿠폰만 가능한가?이미 사용한 쿠폰은?존재하지 않는 쿠폰은?유효기간은?사용한 뒤에는 어떤 상태가 되지?실패했을 때 상태는? 개발자가 이런 것을 정리하지 않고 바로 구현하면 코드 안에서..
[TDD] 자연어 요구사항을 테스트 케이스로 바꾸기
2026.08.21
이미 사용된 쿠폰은 사용할 수 없다. 이런 요구사항이 있다고 예를 들자.if (coupon.isUsed()) { ...} 바로 위와 같은 코드를 생각하는 것이 아니라,먼저 이렇게 생각해야 한다.누가 사용하는가?어떤 상태여야 사용할 수 있는가?사용하면 상태가 어떻게 바뀌는가?어떤 경우에 실패해야 하는가?실패하면 기존 상태는 어떻게 되어야 하는가? 왜 요구사항을 바로 코드로 옮기면 안될까?자연어 요구사항은 생각보다 모호하다.`쿠폰을 사용할 수 있다.` 이 문장만 보고 구현하면 여러 질문이 빠진다.누가 사용할 수 있지?본인 쿠폰만 가능한가?이미 사용한 쿠폰은?존재하지 않는 쿠폰은?유효기간은?사용한 뒤에는 어떤 상태가 되지?실패했을 때 상태는? 개발자가 이런 것을 정리하지 않고 바로 구현하면 코드 안에서..
Spring
[TDD] TDD 맛보기
2026.08.20
Spring
[TDD] TDD 맛보기
2026.08.20
TDD: Red → Green → Refactor 목표요구사항 ↓실패하는 테스트 작성 ↓RED ↓최소 구현 ↓GREEN ↓코드 정리 ↓REFACTOR ↓테스트가 계속 통과하는지 확인 RED : 내 테스트가 실제로 아직 구현되지 않은 요구사항 때문에 실패하고 있다는 뜻 1. TDD에서 왜 일부러 실패하는 테스트부터 만드나?보통 개발을 하면 이런 순서를 떠올리기 쉽다.Product 클래스 작성↓decreaseStock() 구현↓잘 되는지 테스트 작성 TDD에서는 순서를 뒤집는다."재고를 하나 차감하면 9가 되어야 해"↓그 요구사항을 테스트로 먼저 작성↓당연히 아직 구현이 없으므로 실패↓그 테스트를 통과할 만큼만 구현 2. RED 테스트 작성test 폴더에 `ProductTest.java`를 ..
[TDD] TDD 맛보기
2026.08.20
TDD: Red → Green → Refactor 목표요구사항 ↓실패하는 테스트 작성 ↓RED ↓최소 구현 ↓GREEN ↓코드 정리 ↓REFACTOR ↓테스트가 계속 통과하는지 확인 RED : 내 테스트가 실제로 아직 구현되지 않은 요구사항 때문에 실패하고 있다는 뜻 1. TDD에서 왜 일부러 실패하는 테스트부터 만드나?보통 개발을 하면 이런 순서를 떠올리기 쉽다.Product 클래스 작성↓decreaseStock() 구현↓잘 되는지 테스트 작성 TDD에서는 순서를 뒤집는다."재고를 하나 차감하면 9가 되어야 해"↓그 요구사항을 테스트로 먼저 작성↓당연히 아직 구현이 없으므로 실패↓그 테스트를 통과할 만큼만 구현 2. RED 테스트 작성test 폴더에 `ProductTest.java`를 ..
→
💙
[TDD] TDD 맛보기
2026.08.20
2026.08.20
TDD: Red → Green → Refactor 목표요구사항 ↓실패하는 테스트 작성 ↓RED ↓최소 구현 ↓GREEN ↓코드 정리 ↓REFACTOR ↓테스트가 계속 통과하는지 확인 RED : 내 테스트가 실제로 아직 구현되지 않은 요구사항 때문에 실패하고 있다는 뜻 1. TDD에서 왜 일부러 실패하는 테스트부터 만드나?보통 개발을 하면 이런 순서를 떠올리기 쉽다.Product 클래스 작성↓decreaseStock() 구현↓잘 되는지 테스트 작성 TDD에서는 순서를 뒤집는다."재고를 하나 차감하면 9가 되어야 해"↓그 요구사항을 테스트로 먼저 작성↓당연히 아직 구현이 없으므로 실패↓그 테스트를 통과할 만큼만 구현 2. RED 테스트 작성test 폴더에 `ProductTest.java`를 ..
[TDD] TDD 맛보기
2026.08.20
TDD: Red → Green → Refactor 목표요구사항 ↓실패하는 테스트 작성 ↓RED ↓최소 구현 ↓GREEN ↓코드 정리 ↓REFACTOR ↓테스트가 계속 통과하는지 확인 RED : 내 테스트가 실제로 아직 구현되지 않은 요구사항 때문에 실패하고 있다는 뜻 1. TDD에서 왜 일부러 실패하는 테스트부터 만드나?보통 개발을 하면 이런 순서를 떠올리기 쉽다.Product 클래스 작성↓decreaseStock() 구현↓잘 되는지 테스트 작성 TDD에서는 순서를 뒤집는다."재고를 하나 차감하면 9가 되어야 해"↓그 요구사항을 테스트로 먼저 작성↓당연히 아직 구현이 없으므로 실패↓그 테스트를 통과할 만큼만 구현 2. RED 테스트 작성test 폴더에 `ProductTest.java`를 ..
[TDD] TDD 맛보기
2026.08.20
TDD: Red → Green → Refactor 목표요구사항 ↓실패하는 테스트 작성 ↓RED ↓최소 구현 ↓GREEN ↓코드 정리 ↓REFACTOR ↓테스트가 계속 통과하는지 확인 RED : 내 테스트가 실제로 아직 구현되지 않은 요구사항 때문에 실패하고 있다는 뜻 1. TDD에서 왜 일부러 실패하는 테스트부터 만드나?보통 개발을 하면 이런 순서를 떠올리기 쉽다.Product 클래스 작성↓decreaseStock() 구현↓잘 되는지 테스트 작성 TDD에서는 순서를 뒤집는다."재고를 하나 차감하면 9가 되어야 해"↓그 요구사항을 테스트로 먼저 작성↓당연히 아직 구현이 없으므로 실패↓그 테스트를 통과할 만큼만 구현 2. RED 테스트 작성test 폴더에 `ProductTest.java`를 ..
[TDD] TDD 맛보기
2026.08.20
TDD: Red → Green → Refactor 목표요구사항 ↓실패하는 테스트 작성 ↓RED ↓최소 구현 ↓GREEN ↓코드 정리 ↓REFACTOR ↓테스트가 계속 통과하는지 확인 RED : 내 테스트가 실제로 아직 구현되지 않은 요구사항 때문에 실패하고 있다는 뜻 1. TDD에서 왜 일부러 실패하는 테스트부터 만드나?보통 개발을 하면 이런 순서를 떠올리기 쉽다.Product 클래스 작성↓decreaseStock() 구현↓잘 되는지 테스트 작성 TDD에서는 순서를 뒤집는다."재고를 하나 차감하면 9가 되어야 해"↓그 요구사항을 테스트로 먼저 작성↓당연히 아직 구현이 없으므로 실패↓그 테스트를 통과할 만큼만 구현 2. RED 테스트 작성test 폴더에 `ProductTest.java`를 ..
[TDD] TDD 맛보기
2026.08.20
TDD: Red → Green → Refactor 목표요구사항 ↓실패하는 테스트 작성 ↓RED ↓최소 구현 ↓GREEN ↓코드 정리 ↓REFACTOR ↓테스트가 계속 통과하는지 확인 RED : 내 테스트가 실제로 아직 구현되지 않은 요구사항 때문에 실패하고 있다는 뜻 1. TDD에서 왜 일부러 실패하는 테스트부터 만드나?보통 개발을 하면 이런 순서를 떠올리기 쉽다.Product 클래스 작성↓decreaseStock() 구현↓잘 되는지 테스트 작성 TDD에서는 순서를 뒤집는다."재고를 하나 차감하면 9가 되어야 해"↓그 요구사항을 테스트로 먼저 작성↓당연히 아직 구현이 없으므로 실패↓그 테스트를 통과할 만큼만 구현 2. RED 테스트 작성test 폴더에 `ProductTest.java`를 ..
🎵 Playlist
loading...
00:00 / 00:00