으아아아ㅏㅏ 한장 한장 내용이 너무많아......
테스트란?
테스트란 결국 내가 예상하고 의도했던 대로 코드가 정확히 동작하는지를 확인해서, 만든 코드를 확신할 수 있게 해주는 작업이다. 또한 테스트의 결과가 원하는 대로 나오지 않는 경우에는 코드나 설계에 결함이 있음을 알 수 있다. 이를 통해 코드의 결함을 제거해가는 작업, 일명 디버깅을 거치게 되고, 결국 최종적으로 테스트가 성공하면 모든 결함이 제거됐다는 확인을 얻을 수 있다.
- 코드의 정확성을 보장하여 신뢰도를 높인다.
- 설계 및 코드의 결함을 조기에 발견하여 유지보수 비용을 절감할 수 있다.
- 코드 변경(리팩토링) 시 기존 기능이 정상적으로 동작하는지 검증할 수 있다.
테스트 실패시
- 코드 자체의 버그
- 잘못된 요구 사항 정의
- 예상과 다른 실행 결과
작은 단위의 테스트(단위 테스트)
단위 테스트(Unit Test)는 프로그램의 가장 작은 단위(클래스, 메서드, 함수)를 독립적으로 검증하는 테스트다.
단위 테스트의 특징
- 독립적이어야 한다.
- 특정 테스트가 다른 테스트의 영향을 받아서는 안 된다.
- 한 개의 테스트가 실패해도 다른 테스트가 정상적으로 실행되어야 한다.
- 작은 단위로 나누어야 한다.
- 한 번에 여러 기능을 테스트하지 말고, 하나의 기능(로직)만 테스트해야 한다.
- 예: 메서드 A가 B와 C를 호출한다고 할 때, A만 단독으로 테스트해야 한다.
- 빠르게 실행될 수 있어야 한다.
- 실행 시간이 짧아야 개발 과정에서 반복 실행하는 데 부담이 없다.
단위 테스트의 장점
- 코드 변경 시 기존 기능이 깨지지 않는지 빠르게 확인할 수 있다.
- 버그를 조기에 발견할 수 있어 유지보수 비용이 절감된다.
- 코드 품질이 향상되며, 리팩토링이 쉬워진다.
JUnit 테스트
Junit은 자바에서 가장 널리 사용되는 단위 테스트 프레임워크다.
테스트 수행 방식
JUnit에서는 Given-When-Then 패턴을 사용하여 테스트를 구조화 한다.
- Given (준비)
- 테스트를 실행하기 위한 초기 상태를 설정
- 필요한 객체 생성 및 초기화
- When (실행)
- 테스트하려는 실제 동작을 수행
- Then (검증)
- 기대한 결과와 실제 결과를 비교하여 테스트 성공 여부 확인
테스트 주도 개발 (TDD: Test-Driven Development)
TDD는 코드를 작성하기 전에 테스트 코드를 먼저 장성하는 개발 방식이다.
- 테스트 작성 (Red 단계)
- 아직 구현되지 않은 기능에 대해 테스트를 작성한다.
- 이때 테스트는 실패하는 것이 정상이다.
- 코드 작성 (Green 단계)
- 테스트를 통과할 수 있도록 최소한의 코드만 작성한다.
- 빠르게 테스트를 통과하는 것이 목표다.
- 리팩토링(Refactor 단계)
- 중복 코드 제거, 성능 개선 등을 진행하여 코드를 정리한다.
- 리팩토링 후에도 테스트는 계속 통과해야 한다.
TDD의 장점
- 요구사항을 명확하게 이해하고 개발할 수 있다.
- 테스트를 먼저 작성하여 코드 품질을 자연스럽게 향상시킨다.
- 코드 변경 시, 기존 테스트가 보장되므로 안정적인 유지보수가 가능한다.
픽스처 (Fixture)
테스트를 수행하는 데 필요한 정보나 오브젝트를 픽스처(fixture)라고 한다.
- 객체의 초기화
- 테스트를 수행하기 위해 필요한 객체를 미리 생성하여 사용
- 테스트 데이터 준비
- 데이터베이스나 파일에서 필요한 데이터를 미리 로드하여 테스트 진행
의존성 주입(DI)이 필요한 이유
소프트웨어 개발에서 "절대로 바뀌지 않는 것은 없다."
즉, 클래스의 구현 방식이 현재는 고정되어 있어도 미래에 변경이 필요할 수 있기 때문에 인터페이스를 활용하고 DI를 적용하는 것이 유리하다.
- 유지보수성 향상
- 코드 변경 시, 의존성이 적어 수정이 용이함
- 객체 간의 강한 결합을 줄이고 유연성을 높임.
- 테스트 용이성
- 테스트를 위한 Mock 객체 주입이 가능하며, 간위 테스트가 쉬워짐.
- Spring 없이도 독립적으로 객체 테스트가 가능.
- 확장성 증가
- 새로운 기능 추가 시 기존 코드를 수정하지 않고도 확장 가능.
@DirtiesContext
스프링의 테스트 컨텍스트 프레임워크에게 해당 클래스의 테스트에서 애플리케이션 컨텍스트의 상태를 변경한다는 것을 알려준다.
- 테스트에서 컨텍스트를 변경(빈 추가/수정 등)하면, 이후 테스트에서 새로운 컨텍스트를 사용하도록 강제할 수 있다.
- 클래스 또는 메서드 레벨에서 사용 가능하다.
- 매 테스트 실행마다 새로운 컨텍스트를 로딩할 수도 있다.
@SpringBootTest
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
void testCreateUser() {
userService.createUser("Kim");
assertNotNull(userService.findUser("Kim"));
}
@Test
void testDeleteUser() {
userService.createUser("Lima");
userService.deleteUser("Lima");
assertNull(userService.findUser("Lima"));
}
}
침투적 기술과 비침투적 기술
침투적(invasive) 기술
기술을 적용했을 때 애플리케이션 코드에 기술 관련 API가 등장하거나, 특정 인터페이스나 클래스를 사용하도록 강제하는 기술을 말한다. 침투적 기술을 사용하면 애플리케이션 코드가 해당 기술에 종속되는 결과를 가져온다.
- 기술이 애플리케이션 코드에 직접 개입하는 방식
- 특정 프레임워크나 API를 사용하도록 강제함
- 기술 변경 시 에플리케이션 코드에도 영향을 줌
비침투적(noninvasive)기술
애플리케이션 로직을 담은 코드에 아무런 영향을 주지 않고 적용이 가능하다. 따라서 기술에 종속적이지 않은 순수한 코드를 유지할 수 있게 해준다.
스프링은 이런 비침투적인 기술의 대표적인 예다. 그래서 스프링 컨테이너 없는 DI 테스트도 가능한 것이다.
- 애플리케이션 로직을 변경하지 않고 적용할 수 있는 기술
- 기술 종속성을 줄여 코드의 독립성과 유지보수성을 높임
- 스프링이 대표적인 비침투적 기술
학습테스트(learning test)
자신이 사용할 API나 프레임워크의 기능을 테스트로 보면서 사용 방법을 익히려는 것이다. 오히려 자신이 테스트를 만들려고 하는 기술이나 기능에 대해 얼마나 제대로 이해하고 있는지, 그 사용 방법을 바로 알고 있는지를 검증하려는 게 목적이다.
- 다양한 조건에 따른 기능을 손쉽게 확인해볼 수 있다.
- 학습 테스트 코드를 개발 중에 참고할 수 있다.
- 프레임워크나 제품을 업그레이드할 때 호환성 검증을 도와준다.
- 테스트 작성에 대한 좋은 훈련이 된다.
- API의 사용 방법을 빠르게 익힐 수 있다.
버그 테스트(bug test)
코드에 오류가 있을 때 그 오류를 가장 잘 드러내줄 수 있는 테스트를 말한다.
- 테스트의 완성도를 높여준다. -> 기존에 고려하지 못했던 예외 상황까지 검증 가능
- 버그의 내용을 명확하게 분석하게 해준다.
- 기술적인 문제를 해결하는 데 도움이 된다. -> 동일한 버그가 발생하지 않도록 예방
동등분할(equivalence partitioning)
같은 결과를 내는 값의 범위를 구분해서 각 대표 값으로 테스트를 하는 방법을 말한다. 어떤 작업의 결과의 종류가 true, false 또는 예외발생 세가지라면 각 결과를 내는 입력 값이나 상황의 조합을 만들어 모든 경우에 대한 테스트를 해보는 것이 좋다.
- 동일한 결과를 내는 입력값을 그룹화하여 대표값을 선정해 테스트하는 기법.
- 입력값을 몇 개만 테스트해도 전체적인 동작을 확인할 수 있음.
경계값 분석(boundary value analysis)
에러는 동등분할 범위의 경계에서 주로 많이 발생한다는 특징을 이용해서 경계의 근처에 있는 값을 이용해 테스트 하는 방법이다. 보통 숫자의 입력 값인 경우 0이나 그 주변 값 또는 정수의 최대값, 최소값 등으로 테스트해보면 도움이 될 때가 많다.
- 입력값의 최소값, 최대값 근처에서 발생할 수 있는 문제를 집중적으로 테스트하는 방법.
- 보통 경계 지점에서 오류가 발생하는 경우가 많음.
화... 화이팅!
** 그냥 하루하루 개인 공부한 것을 끄적 거리는 공간입니다.
이곳 저곳에서 구글링한 것과 강의 들은 내용이 정리가 되었습니다.
그림들은 그림밑에 출처표시를 해놓았습니다.
문제가 될시 말씀해주시면 해당 부분은 삭제 하도록하겠습니다. **
'public void static main > Book' 카테고리의 다른 글
[Elasticsearch Bible] 1장 소개 ~ 2장 동작과 구조 (1) | 2025.01.29 |
---|---|
[토비의스프링] 1장-오브젝트와 의존관계 (1) | 2025.01.28 |
[대규모 시스템 설계 기초] 3장, 4장 (1) | 2025.01.08 |
[대규모 시스템 설계 기초] 1장, 2장 (1) | 2025.01.06 |
[JVM 밑바닥] 7장 클래스 로딩 메커니즘 (1) | 2024.11.17 |
댓글