테스트 코드를 작성할 때 AAA패턴(Arrange/Act/Assert)을 따르면 가독성이 향상되며, 다른 사람이 테스트 코드를 이해하는데 도움이 됩니다.
AAA패턴이란, 테스트 코드를 아래 3단계 순서로 구분하는 것을 말합니다.
- Arrange(준비) : 테스트를 실행하기 전에 필요한 것들을 준비합니다. 예를 들어, 객체를 생성하거나, Mock 객체를 만들거나, 테스트 전에 호출되어야 할 API들을 호출하는 것들을 의미합니다.
- Act(실행) : 테스트 코드를 실행합니다.
- Assert(단언) : 실행한 코드가 예상한대로 동작했는지 확인합니다.
assertTrue()
,assertThat()
등의 코드들이 여기에 해당합니다.
예제
AAA패턴으로 작성한 테스트 코드입니다.
@Test
public void testAAAPattern() {
// Arrange
List<String> list = new ArrayList<>();
// Act
list.add("123");
list.add("abc");
list.remove("abc");
// Assert
assertThat(list, hasItem("123"));
assertThat(list, not(hasItem("abc")));
}
- Arrange : 테스트에 필요한 리스트 객체를 생성하였습니다.
- Act : 테스트하려는 코드를 실행하였습니다. 여기서는 예로, 리스트에서 문자열 추가와 삭제를 수행하였습니다.
- Assert : 예상하는 결과를 확인하였습니다.
위의 예제 처럼, 각 단계마다 빈줄로 구분하면 테스트 코드의 가독성이 더욱 좋아집니다. (주석으로 Arrange, Act, Assert를 입력해줄 필요는 없습니다.)
대부분의 개발자들은 AAA패턴을 알고 있기 때문에, 이런 흐름을 예상하면서 코드를 읽을 수 있습니다.
예제 2
위의 예제도 매우 간단하지만, Act 부분이 좀 정신없고, 서로 다른 내용을 체크하는 assert들이 호출되고 있습니다. 테스트 이름도 무엇을 테스트하려고 하는지 의도를 분명히 드러내고 있지 않습니다.
위의 테스트를 아래와 같이 두개의 테스트로 분리하였습니다. 각각의 테스트는 한가지 동작만 확인합니다.
@Test
public void testDoingSomething_hasItem() {
// Arrange
List<String> list = new ArrayList<>();
// Act
addAndRemoveThings(list);
// Assert
assertThat(list, hasItem("123"));
}
@Test
public void testDoingSomething_hasNotItem() {
// Arrange
List<String> list = new ArrayList<>();
// Act
addAndRemoveThings(list);
// Assert
assertThat(list, not(hasItem("abc")));
}
private void addAndRemoveThings(List<String> list) {
list.add("123");
list.add("abc");
list.remove("abc");
}
먼저, Act에서 수행하는 3줄의 코드를 addAndRemoveThings()
라는 메소드 1개로 변경하였습니다.
또한, 적절한 메소드 이름을 지어, 테스트를 읽는 사람이 메소드 안에서 무엇을 하는지 확인할 필요가 없도록 했습니다.
마지막으로 각 테스트에는 1개의 assert만 추가하였습니다. 서로 다른 결과를 확인하는 assert들이 많으면 이 테스트가 어떤 행위를 테스트하는지 논점이 흐려질 수 있습니다.
(remove와 add를 하나의 테스트에서 체크해도 문제는 없어보입니다. 극단적으로 예를 들었으니 이런 부분들은 감안해주세요.)
테스트를 1개로 유지하면, Arrange나 Act에서 걸리는 시간을 절약할 수 있습니다. 하지만, 테스트 코드를 이해하는데 어려울 수 있고, 테스트가 실패했을 때, 그 뒤에 있는 assert 코드들은 확인되지 않고 테스트가 종료된다는 단점이 있습니다.
따라서, 여러 테스트로 분리해도 수행 시간이 오래 걸리지 않도록 가볍게 유지하면서, 1개의 테스트에 적은 수의 assert가 추가되도록 만드는 것이 좋습니다. 물론, 가이드일 뿐, 경우에 따라 많은 assert를 추가하는 것에서 이득이 있다면 그렇게 하시는 것이 좋습니다.
Related Posts
- Java - Unsupported class file major version 61 에러
- Java - String.matches()로 문자열 패턴 확인 및 다양한 예제 소개
- Java - 문자열 공백제거 (trim, replace)
- Java - replace()와 replaceAll()의 차이점
- Java - ArrayList 초기화, 4가지 방법
- Java - 배열 정렬(Sorting) (오름차순, 내림차순)
- Java - 문자열(String)을 비교하는 방법 (==, equals, compare)
- Java - StringBuilder 사용 방법, 예제
- Java - 로그 출력, 파일 저장 방법 (Logger 라이브러리)
- Java IllegalArgumentException 의미, 발생 이유
- Java - NullPointerException 원인, 해결 방법
- Seleninum의 ConnectionFailedException: Unable to establish websocket connection 해결
- Java - compareTo(), 객체 크기 비교
- Java - BufferedWriter로 파일 쓰기
- Java - BufferedReader로 파일 읽기
- Java charAt() 함수 알아보기
- Java - BigInteger 범위, 비교, 연산, 형변환
- Java contains()로 문자(대소문자 X) 포함 확인
- Java - Set(HashSet)를 배열로 변환
- Java - 문자열 첫번째 문자, 마지막 문자 확인
- Java - 문자열 한글자씩 자르기
- Java - 문자열 단어 개수 가져오기
- Java - 1초마다 반복 실행
- Java - 배열을 Set(HashSet)로 변환
- Java - 여러 Set(HashSet) 합치기
- Java - 명령행 인자 입력 받기
- Java - 리스트 역순으로 순회, 3가지 방법
- Java - 특정 조건으로 리스트 필터링, 3가지 방법
- Java - HashMap 모든 요소들의 합계, 평균 계산
- Java - 특정 조건으로 HashMap 필터링
- Java - 싱글톤(Singleton) 패턴 구현
- Java - 숫자 왼쪽에 0으로 채우기
- Java - String 배열 초기화 방법
- Java - 정렬된 순서로 Map(HashMap) 순회
- Java - HashMap에서 key, value 가져오기