안녕하세요🐶
빈지식 채우기의 비니🙋🏻♂️입니다.
.
어떠한 A 라는 기능을 개발하였고,
해당 기능을 테스트 하기 위해서 프로젝트 Run 을 하는 경우가 많습니다.
이 방법으로도 충분히 테스트가 가능하지만!
시간도 오래 걸릴 뿐더러 생산성을 저하시킬 수 있기 때문에
우리는 유닛 테스트 ( Unit Test ) 라는 것을 사용할 수 있습니다.
1. FIRST 원칙
유닛 테스트는 아래와 같이 FIRST 원칙을 지켜야 합니다.
속도 ( Fast )
느린 테스트는 개발자가 코드를 수정하고 결과를 확인하기까지 시간이 걸려 생산성을 저하시킨다.
따라서 유닛 테스트에서는 빠른 속도로 테스트를 수행할 수 있도록 설계해야한다.
독립적 ( Independent / Isolated )
유닛 테스트는 각각의 테스트가 독립적으로 실행될 수 있어야 합니다.
이러한 방식으로 작성된 유닛 테스트는 코드 변경에 대해 신속하게 대응을 할 수 있습니다.
반복적 ( Repeatable )
유닛 테스트는 반복적으로 실행될 수 있어야 합니다.
동일한 입력값에 대해서는 항상 동일한 결과를 보여야 합니다.
이러한 특징은 테스트의 신뢰성을 높일 수 있습니다.
자동화 ( Self-Automation )
수동으로 테스트 하는 것보다 자동화된 테스트를 수행하면 시간과 비용을 절약할 수 있습니다.
또한 자동화 테스트는 개발자가 코드를 변경하거나 기능을 추가할 때마다 쉽게 실행할 수 있어서 버그를 손쉽게 찾을 수 있습니다.
시점 ( Timely )
코드가 수정되어도 다른 부분에 영향을 미치지 않는지 확인할 수 있는 시점에 테스트를 실행해야 합니다.
코드 수정 후 변경 사항을 더욱 빠르게 확인할 수 있습니다.
2. 생성 방법
유닛 테스트 생성 방법은 크게 두가지가 있습니다.
2-1. 프로젝트 생성 시
- Include Tests 를 체크 후 프로젝트 생성
2-2. 프로젝트 생성 이후
- 좌측 네비게이션에서 상위 프로젝트 클릭 > Editor > Add Target
- Unit Test 검색 후 생성
- 생성된 Test 폴더 확인
기본 테스트 코드 생성 확인 완료
3. 간단 설명
XCTest 란 실제 유닛 테스트를 할 수 있게 도와주는 프레임워크 입니다.
또한 각각의 테스트가 서로 영향을 미치지 않도록 ( 독립성 ) 메서드를 통해 테스트를 도와줍니다.
위 XCTest 프로세스를 기반으로,
아래 작업 간단한 예시를 작성을 해보았습니다.
import XCTest
final class RxSwift_Study_1Test2: XCTestCase {
// 타입 메서드로 시작 전 딱 한 번만 호출됩니다.
// 모든 테스트 메서드에서 실행 전 정의하거나 초기화할 작업에 대해 구현합니다.
override class func setUp() {
super.setUp()
print("전체 테스트 시작!")
}
// 각 테스트 메서드가 실행되기 전에 실행됩니다.
// 각각 테스트 메서드에서 사용될 것들에 대해 초기화 하는 작업에 대해 구현합니다.
override func setUpWithError() throws {
try super.setUpWithError()
print("테스트1 시작!(setUpWithError)")
}
// setUpWithError 와 동일하지만 다른 점은 실행 도중 발생한 에러에 대해 처리할 수 있는 점입니다.
override func setUp() {
super.setUp()
print("테스트1 시작!(setUp)")
}
// 실제 테스트에서 사용될 메서드 블럭입니다.
func testMethod() throws {
print("testMethod() 호출")
// testMethod()가 종료될 때 실행되는 코드 블럭입니다.
// 먼저 선언된 블럭이 나중에 실행되는 LIFO 구조입니다.
addTeardownBlock {
print("addTearDownBlock 호출")
}
}
// 각각의 테스트가 종요되고 나서 호출됩니다.
// 메서드 수행 후 정리하는 작업을 오버라이드하여 구현합니다.
override func tearDown() {
super.tearDown()
print("테스트1 종료(tearDown)")
}
// tearDown() 메서드와 마찬가지로 각각의 테스트 종료 후에 호출 됩니다.
// 다른 점은 해당 메서드는 실행 도중 발생한 에러에 대해 처리가 가능합니다.
override func tearDownWithError() throws {
try super.tearDownWithError()
print("테스트1 종료(tearDownWithError)")
}
// 타입 메서드로 모든 테스트가 종료되고 딱 한번만 호출됩니다.
// 모든 테스트를 마치고 정리해야 할 작업에 대해 구현합니다.
override class func tearDown() {
super.tearDown()
print("전체 테스트 종료!")
}
}
테스트를 사용할 때 사용하는 메서드는 다음과 같습니다.
- class func setUp()
- 타입 메서드로 테스트 시작 전 한번만 호출됩니다.
- 모든 테스트 메서드에서 실행 전 정의해야할 것이나 초기화할 작업에 대해 구현합니다.
- func setUpWithError()
- 각 테스트 메서드가 실행되기 전 실행됩니다.
- 각각의 테스트에서 사용되는 값에 대한 초기화가 구현됩니다.
- func setUp() 과 동일한 기능을 가지지만, 다른 점은 해당 메서드는 실행 중간에 발생하는 에러를 처리할 수 있습니다.
- func setUp()
- setUpWithError() 와 동일한 기능을 가집니다.
- func testMethod() & addTearDownBlock(_:)
- 실질적은 테스트를 수행하는 메서드입니다.
- 테스트 메서드 이름은 자유롭게 지을 수 있습니다.
- addTearDownBlock(_:) 의 경우 testMethod() 가 종료될 때 실행됩니다.
- addTearDownBlock(_:) 의 경우 먼저 선언된 것이 나중에 실행되는 LIFO 구조로 호출됩니다.
- func tearDown()
- 각각의 메서드가 종료되고 나서 실행됩니다.
- 각각의 테스트가 진행되고 정리하는 작업에 대해 구현합니다.
- func tearDownWithError()
- tearDown() 과 동일한 기능을 가졌습니다.
- 다른 점은 해당 메서드의 경우 실행 도중에 발생하는 에러에 대해 처리가 가능합니다.
- class func tearDown()
- 타입 메서드로 모든 테스트가 종료되고 딱 한 번만 호출됩니다.
- 모든 테스트를 마치고 정리해야할 작업을 구현합니다.
이상으로 간단하게 유닛 테스트 ( Unit Test ) 의 기본에 대해 알아보았습니다.합니다.ㅇ
참고
'iOS 🖥️ > 유틸' 카테고리의 다른 글
[Test] 유닛 테스트 ( Unit Test ) 간단 예제 (0) | 2024.02.07 |
---|