띠오니 개발자 성장일지
article thumbnail
반응형

테스트가 중요한 이유에 중점을 두고 단위 테스트에 대해 자세히 알아보자.

1. 테스트가 중요한 이유

2. 단위 테스트의 모양

3. 단위 테스트를 작성하고 실행하는 방법

테스트의 철학에 대해 살펴본 후, Android 프로젝트에서 자동 생성된 테스트를 자세히 알아보고 마지막으로 주사위 프로젝트의 앱 테스트를 진행해보자.


테스트가 중요한 이유

처음 앱의 규모가 작고 기능이 제한 되어있을 때는 쉽게 수동으로 모든 기능이 정상작동 하는지 테스트 할 수 있다. 

하지만 규모가 커지면서 수동 테스트는 자동 테스트를 작성하는 것 보다 더 많은 노력이 필요하다.

전문가 수준의 앱 작업을 시작하면, 테스트는 사용자층이 넓을 때 중요해진다.

다양한 버전과 여러 디바이스를 고려해야 한다. 그러다 보니 수동 테스트보다 자동 테스트가 훨씬 빠르게 대다수의 사용 시나리오를 고려할 수 있게 된다. 또 더 정확하고 팀의 생산성을 고려하면 자동 테스트를 사용하는 것이 좋다고 한다.

 

단위 테스트

Android 앱을 만들 때 자동으로 테스트가 생성된다. 단위 테스트는 항상 test 디렉토리에 있다.

1. app/build.gradle 파일을 열고 dependencies에서 의존성 추가된 부분을 확인해보자. 일부 종속성이 testImplementation 및 androidTestImplementation 으로 표시되어 있다. testImplementation은 단위 테스트, androidTestImplementation은 계측 테스트에 해당한다.

계측 테스트 : 계측 단위 테스트는 실제 기기 및 에뮬레이터에서 실행되는 테스트

단위 테스트 : 테스트를 더 빠르게 실행해야 하고 실제 기기에서 테스트를 실행함으로써 얻는 충실도와 신뢰도가 필요하지 않은 경우 로컬 단위 테스트를 사용하여 앱 로직을 평가할 수 있다.

단위 테스트는 안드로이드 공식 문서로 찾아보니 로컬 단위 테스트 라는 용어로 번역되어 사용되는 것 같다.

아무튼, 그 다음으로 Junit 라이브러리가 종속 추가된 것을 확인한다. Junit 라이브러리는 단위 테스트를 구동하고, 앱 코드를 테스트 할 수 있는 방식으로 컴파일하고 실행할 수 있도록 코드를 테스트로 표시하도록 허용한다.

testImplementation 'junit:junit:4.13.2'

 

2. test 디렉토리에서 ExampleUnitTest.kt 파일을 열어보자

열어보면 테스트 코드를 작성한 적 없는데 뭔가 적혀져있다. 이는 Android 스튜디오에서 자동으로 생성하는 코드이다.

테스트함수는 org.junit.test 라이브러리에서 가져온 @Test 어노테이션을 달아야한다. 어노테이션은 코드가 컴파일 되는 방법을 변경할 ㅅ수 있는 코드의 메타 데이터 태그로 생각하면 된다. 즉 @Test 어노테이션을 사용하면 이 코드가 테스트 코드로서 컴파일 된다.

 

그럼 테스트코드로 작성된 addition_isCorrect() 메소드를 확인해보자. 메소드 내의 assertEquals() 함수는 예상한 값이 비즈니스 로직을 통해 도출된 결과값과 같아야 한다는 함수이다. 이 assert 함수는 단위 테스트의 최종 목표이다. 즉 단위 테스트에서 assert 함수를 통해 기대값과 실제값이 같은지 검증해야 한다. 일치하면 통과, 다르면 테스트 실패다. 

메소드 이름 옆의 화살표를 누르면 아래와 같이 뜨는데, Run 'ExampleUnitTest.addition_isCorrect'를 선택한다.

테스트 결과를 보면 Tests passed : 1로 되어있고, 빌드도 성공했다는 메시지를 볼 수 있다. 테스트에 통과한 테스트의 수다.

포지티브 테스트는 assert 테스트가 긍정적인 결과를 나타냈을 때를 뜻한다.

반대로 네거티브 테스트는 assert 여부가 부정상태로 만드는 것을 뜻한다. 테스트가 틀렸을 경우 빨간색으로 틀렸다고 티를 내준다.

왼쪽 Test Results의 하위메뉴 항목을 클릭하면 테스트 실패한 이유를 나타내는 오류 메시지를 보여준다.

 

 

주사위 앱의 단위 테스트 해보기

주사위 앱의 단위 테스트를 해보자. 주사위의 기능은 랜덤한 숫자를 보여주는 것인데, 무작위로 생성된 값이니만큼 테스트 하기에는 어렵다. 

그래서 이 테스트에서는 dice클래스의 roll() 메소드를 호출할 때 적절한 숫자가 반환되는지 확인해보자.

테스트 결과로 나온 수가 지정한 범위 내의 숫자인지만 확인한다.

@Test
fun generates_number() {
    val dice = Dice(6)
    val rollResult = dice.roll()
}

우선 주사위 객체와 면의 개수를 지정해주고, roll() 메소드를 호출해 결과를 얻어온다.

이 결과가 면의 개수 내에 있는 값을 반환했다고 assert 해야한다. 면의 개수를 6으로 지정했기 때문에 값이 0보다 크고 7보다 작아야 한다.

이렇게 하려면 assertTrue() 메소드를 사용한다. 

org.junit.Assert 패키지를 import해야 사용할 수 있다. 즉 import org.junit.Assert.assertTrue

괄호 사이에 커서를 두고 command + p 를 누르면 메소드의 매개변수를 보여주는 도움말이 뜬다.

assertTrue()는 String, Boolean 타입의 매개변수를 사용하는데,

String은 assert에 실패하면 콘솔에 표시되는 메시지이고, Boolean은 조건문을 입력한다.

@Test
fun generates_number() {
   val dice = Dice(6)
   val rollResult = dice.roll()
   assertTrue("The value of rollResult was not between 1 and 6", rollResult in 1..6)
}

테스트를 실행해보자. Tests passed 로 표시되면 성공 ! 

 

참고: JUnit 라이브러리에는 어설션이 많이 있습니다. 발생할 수 있는 일반적인 어설션은 다음과 같습니다.
assertEquals()
assertNotEquals()
assertThat()
assertTrue()
assertFalse()
assertNull()
assertNotNull()
For more information, see Assert.

 

 

참고

Android에서 앱 테스트

반응형
profile

띠오니 개발자 성장일지

@띠오니

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!