이번 시간은 테스트기법 중 하나인 단위테스트에 대한 이야기다.
교육에서 보여주는 예제는 자바로 재해석했다.
원본이 궁금하면 이규원님의 TDD 수강하는걸 추천드립니다.
단위 테스트란?
테스트 주도 개발에 이용되는 가장 중요한 도구이며, 전체시스템 중에 일부분을 테스트 자동화한다.
단위 테스트 작성 실습
아래 예제는 운영중인 프로그램으로
문자열을 입력받아서 공백 문자가 연속되면 하나로 합치는 기능을 제공한다.
public class BlankReplace {
public String refineTest(String s) {
return s.replace(" ", " ").replace(" ", " ");
}
}
테스트 코드를 작성해보자
class BlankReplaceTest {
private BlankReplace blankReplace = new BlankReplace();
@Test
@DisplayName("연속된 2개 공백 -> 하나의 공백")
public void blackReplace() throws Exception {
//given
String s = "hello world";
//when
boolean result = blankReplace.refineTest(s).equals("hello world");
//then
assertEquals(result, true);
}
}
hello world 가운데는 공백이 2번 들어있다.
함수를 실행하면 반환되는 결과가 hello world 와 같은지 테스트 결과를 확인해보자.
하지만 다른 상황에도 잘 작동이 될까? 공백문자 4개로 해보자
@Test
@DisplayName("연속된 공백 4개 -> 하나의 공백")
public void fourblackReplace() throws Exception {
// 이번엔 공백 4개
String s = "hello world";
...(이하 동일)
}
이번에도 통과가 되었다.
공백 3개일 경우도 추가해보자
@Test
@DisplayName("연속된 공백 3개 -> 하나의 공백")
public void threeBlackReplace() throws Exception {
// 이번엔 공백 3개
String s = "hello world";
...(이하 동일)
}
3개의 테스트 중 2개가 통과 되었고 1개가 실패되었다.
공백이 하나인 hello world 가 아니라 공백이 2개인 hello world 로 반환되었기 때문에 실패했다.
이미 작성된 운영코드를 테스트를 진행하니 2가지 케이스(공백 2,4개)에 대해선 테스트가 성공했지만
공백이 3개인 경우 실패한다는 결과를 받았다.
테스트 코드를 다시 보자.
3가지 테스트 코드는 입력된 hello world 의 공백 개수만 다르고 나머지는 동일하다.
반복되는 것을 줄여보자.
@Test
@DisplayName("배열로 테스트")
public void blankArrayTest() throws Exception {
String[] s = {"hello world", "hello world", "hello world"};
for (int i = 0; i < s.length; i++) {
boolean result = blankReplace.refineTest(s[i]).equals("hello world");
assertEquals(result, true);
}
}
세개의 테스트가 하나의 테스트로 합쳐졌다. 결과를 보자.
반복문으로 중복 코드를 제거했지만 아래의 문제가 발생했다.
- 이전에는 3가지 유형으로 각각의 테스트 결과로 무엇이 실패한지 알 수 있는데, 이번에는 하나의 테스트로 배열에 들어간 값 중 무엇이 실패했는지 알 수가 없다.
- 이전의 3가지 유형으로 공백 3개인 배열의 2번째에서 실패한걸 유추할 수 있지만, 그 뒤의 값은 실행도 안되고 테스트가 끝났다. 공백 4개가 성공했는지 실패했는지 알 수가 없다.
반복문으로 테스트 작성코드 비용은 감소했지만, 이전 3가지 유형보다 피드백 품질이 감소되었다.
테스트 코드가 작다고 좋은건 아니다.
xUnit 은 다행히 ParameterizedTest 을 제공한다.
이 기법을 사용하면 위의 3가지 유형의 코드 중복을 제거하면서, 반복문으로 작성했던 테스트의 피드백 품질도 개선할 수 있다.
@ParameterizedTest
@CsvSource(value = {"hello world", "hello world", "hello world"})
@DisplayName("배열로 테스트")
public void blankArrayTest(String s) throws Exception {
boolean result = blankReplace.refineTest(s).equals("hello world");
assertEquals(result, true);
}
반복코드를 줄여서 작성했지만 하나의 결과가 아닌 3개의 결과로 보여주고 있다.
기존의 중복 코드를 줄이면서 양질의 피드백을 받을 수 있게 되었다.
이번 시간은 여기까지
다음은 테스트 우선 개발에 대해 알아보도록 하자.
'교육 및 인강 > 이규원의 현실 세상의 TDD' 카테고리의 다른 글
이규원님의 현실 세상의 TDD 기초, 6편 : 정리된 코드(리팩토링) (0) | 2021.04.14 |
---|---|
이규원님의 현실 세상의 TDD 기초, 5편 : 테스트 우선 개발 (0) | 2021.04.13 |
이규원님의 현실 세상의 TDD 기초, 3편 : 코드 분해 (0) | 2021.03.10 |
이규원님의 현실 세상의 TDD 기초, 2편 : 테스트 기법 (0) | 2021.03.10 |
이규원님의 현실 세상의 TDD 기초, 1편 : 코드 기능 명세 (2) | 2021.03.10 |