테스트
단위 테스트
Automated tests
Better code design
Fewer bugs and higher reliability
Increases confidence for code refactoring
DevOps and Build Pipelines
CI/CD
통합 테스트
하향식 통합 테스트
깊이 우선, 너비 우선
Stub (가짜 모듈) 사용
상향식 통합 테스트
클러스터 : 하위 모듈 그룹
드라이버 : 더미 모듈
순서
낮은 수준 모듈들을 클러스터로 결합
드라이버 작성
클러스터 검사/테스트
드라이버 제거하고 클러스터를 상위로 결합
유닛테스트 프레임워크
JUnit
Mockito
Unit Test
Process
- Set Up
- Execute
- Assert
class DemoUtilsTest
{
@Test
void testEqualsAndNotEquals()
{
// set up
DemoUtils demoUtils = new DemoUtils();
int expected= 6;
// execute
int actual= demoUtils.add(2,4);
// assert
Assertions.assertEquals(expected, actual, "2+4 는 6이다.");
}
}
Execution Sequence
@BeforeAll (static method)
@BeforeEach
@Test Method One
@AfterEach
@BeforeEach
@Test Method Two
@AfterEach
@AfterAll (static method)
Custom Display Names
현재 테스트를 할 때 그 결과는 단순히 클래스명과 테스트한 메소드 명을 보여주고 있다.
그래서 애노테이션을 추가하여
커스텀된 테스트 결과 리스트를 보여주려고 함.
@DisplayName("..")
각 메소드마다 애노테이션을 추가하여 테스트에 대한 설명을 적을 수 있음.
사용해본 결과 : 번거로운 점이 있음
@Test
@DisplayName("Equals and Not Equals")
void testEqualsAndNotEquals(){
DemoUtils demoUtils = new DemoUtils();
assertEquals(6,demoUtils.add(2,4), " 2 +4 = 6");
assertNotEquals(6,demoUtils.add(2,7), " 2 +4 = 6");
}
@Test
@DisplayName("Null and Not Null")
void testNullAndNotNull(){
DemoUtils demoUtils = new DemoUtils();
String str1= null;
String str2 = "javapp";
assertNull(demoUtils.checkNull(str1), "Object should be null");
assertNotNull(demoUtils.checkNull(str2), "Object should be null");
}
제너레이터를 둔다.
DisplayNameGenerator.ReplaceUnderscores.class --> 밑줄을 공백으로 대체해줌.
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
public class DemoUtilsTest {
@Test
void test_Equals_And_Not_Equals(){
DemoUtils demoUtils = new DemoUtils();
assertEquals(6,demoUtils.add(2,4), " 2 +4 = 6");
assertNotEquals(6,demoUtils.add(2,7), " 2 +4 = 6");
}
@Test
void test_Null_And_Not_Null(){
DemoUtils demoUtils = new DemoUtils();
String str1= null;
String str2 = "javapp";
assertNull(demoUtils.checkNull(str1), "Object should be null");
assertNotNull(demoUtils.checkNull(str2), "Object should be null");
}
}
단 한번 애노테이션을 써서 사용할 수 있으며
메소드 명을 통해 테스트를 설명할 수 있음.
사용해본 결과 : 스네이크 표기법을 쓰면서 "_" 사용에 부자연스러움
DisplayName 보다는 효율적임
Simple 일 경우 단순히 메소드 마지막 소괄호 제거
@DisplayNameGeneration(DisplayNameGenerator.Simple.class)
IndicativeSentences
어떤 클래스에서 어떤 메소드를 사용했는지 제공해줌.
@DisplayNameGeneration(DisplayNameGenerator.IndicativeSentences.class)
Assertions
assertEquals , assertNotEquals
assertNull , assertNotNull
assertSame
assertNotSame
assertTrue
assertFalse
assertArrayEquals
assertIterableEquals
assertLinesMatch
assertThrows
assertDoesNotThrow
assertTimeoutPreemptively
JUnit 메이븐 의존성 추가
단위 테스트
assertEquals , assertNotEquals(기대값, 테스트값, message);
assertEquals 성공
assertNotEquals 실패
assertNull , assertNotNull(테스트값, message);
public Object checkNull(Object obj) {
return null;
}
public Object checkNull(Object obj) {
if (obj != null) {
return obj;
}
return null;
}
null 일때 파라미터 타입으로 반환
assertSame
assertNotSame
assertTrue
assertFalse
@Test
@DisplayName("Same and Not Same")
void testSameAndNotSame()
{
String str= "code";
assertSame(demoUtils.getAcademy(), demoUtils.getAcademyDuplicate(),"같은 값을 가진다.");
assertNotSame(str,demoUtils.getAcademy());
}
@Test
@DisplayName("True and False")
void testTrueFalse()
{
int gradeOne= 10;
int gradeTwo = 5;
assertTrue(demoUtils.isGreater(gradeOne, gradeTwo), "this should return true");
assertFalse(demoUtils.isGreater(gradeTwo, gradeOne), "this should return false");
}
assertArrayEquals
assertIterableEquals
- 예상 반복 가능 항목과 실제 반복 가능 항목이 동일한지 확인
- LinkedList 및 ArrayList 의 값 비교 가능
@DisplayName("Array Equals")
@Test
void testArrayEquals(){
String [] stringArray={"A","B","C"};
assertArrayEquals(stringArray, demoUtils.getFirstThreeLettersOfAlphabet(),"배열의 값이 같다.");
}
@DisplayName("Iterable equals")
@Test
void testIterableEquals(){
List<String> theList = List.of("academy","In","List");
assertIterableEquals(theList,demoUtils.getAcademyInList(),"리스트의 요소들이 같다.");
}
assertLinesMatch
- 예상 목록이 실제 목록과 일치하는지 확인
@DisplayName("Iterable equals")
@Test
void testLinesMatch(){
List<String> theList = List.of("academy","In","List");
assertLinesMatch(theList,demoUtils.getAcademyInList(),"리스트의 요소들이 같다.");
}
Throws Test
예외 처리 테스트
assertThrows
assertDoesNotThrow
public class DemoUtils {
public String throwException(int a) throws Exception {
if (a < 0) {
throw new Exception("0 보다 같거나 커야 됩니다.");
}
return "값이 0보다 크거나 같습니다.";
}
...
}
@DisplayName("예외 테스트")
@Test
void testThrowsAndDoesNotThrow(){
assertThrows(Exception.class, ()->{demoUtils.throwException(-1);}, "예외 발생");
assertDoesNotThrow(()->demoUtils.throwException(-1), "예외가 발생하면 안됨.");
}
assertDoesNotThrow 의 에러 메시지와
메소드에 의한 에러 메시지 출력
타임아웃 테스트
assertTimeoutPreemptively
@DisplayName("타임 아웃 테스트")
@Test
void test3secTimeout(){
assertTimeoutPreemptively(Duration.ofSeconds(3), ()->{
demoUtils.checkTimeout(); // 2초간의 작업
}, "메소드는 3초안에 처리되어야 한다.");
}
테스트 순서
@TestMethodOrder(MethodOrderer.MethodName.class) // 메소드명 순서
@TestMethodOrder(MethodOrderer.DisPlayName.class) // 디스플레이 명 순서
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) + @Order(n) // 음수 가능
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class DemoUtilsTest
{
@Order(1)
@Test
@DisplayName("...")
method()
}
파라미터를 이용한 테스트 반복
@ParameterizedTest // 파라미터를 이용하여 테스트를 할 수 있음.
어떤 데이터 자원 포맷을 사용할 것인지 애노테이션을 작성
@ValueSource(strings = {""," "})
@NullSource // primitive 타입은 불가
@EmptySource
@NullAndEmptySource
@EnumSource(Month.class)
@MethodSource // 복잡한 인수 전달
사용예시)
@ParameterizedTest // 파라미터를 이용하여 테스트를 할 수 있음.
@ValueSource(strings = {""," "})
실습) CSV 에서 (값 , 예상값) 을 파라미터로 가져와서 반복 단위 테스트
FizzBuzzTest.java
// csv 파일을 활용한 반복 테스트
@DisplayName("csv 파일을 활용한 반복 테스트")
@ParameterizedTest(name="value={0}, expected={1}")
@CsvFileSource(resources="/small-test-data.csv")
@Order(5)
void testCsvDataFile(int value, String expected){
assertEquals(expected, FizzBuzz.compute(value), "1 리턴");
}
JUnit 은 실제로 해당 테스트를 호출합니다. 백그라운드에서
CSV 파일을 통해 데이터를 여러번 생성하며 모든 반복 작업을 처리합니다.
https://www.jetbrains.com/help/idea/junit.html
https://junit.org/junit5/docs/current/user-guide/#writing-tests
'Back-end > 테스트' 카테고리의 다른 글
Spring Boot MVC 데이터베이스 통합 테스트 @Sql (0) | 2022.10.29 |
---|---|
Spring Boot Unit Testing - Mocking with Mockito - @MockBean, ReflectionTestUtils (0) | 2022.10.21 |
Spring Boot Unit Testing Support - 1 (0) | 2022.10.10 |
TDD 테스트 주도 개발 연습 (0) | 2022.10.05 |
JUnit - 코드 커버리지 테스트 (0) | 2022.09.25 |
댓글