단위테스트

Little_Machine_Human_·2025년 1월 15일
post-thumbnail

단위 테스트(Unit Testing)는 소프트웨어 개발에서 가장 기본적이고 중요한 테스트 방법 중 하나

  • 코드의 가장 작은 단위(보통 함수나 메서드 수준)를 독립적으로 테스트하는 방법
  • 특정 함수가 예상대로 동작하는지 확인하기 위해 다양한 입력값을 넣고 그 결과를 검증
  • 자동화된 방식으로 실행되어 코드 변경 시 빠르게 문제를 발견

XCTest를 이용한 단위테스트

import XCTest

class Calculator {
    func add(_ a: Int, _ b: Int) -> Int {
        return a + b
    }
}

class CalculatorTests: XCTestCase {
    var calculator: Calculator!
    
    override func setUp() {
        super.setUp()
        calculator = Calculator()
    }
    
    func testAdd() {
        // Given
        let a = 5
        let b = 3
        
        // When
        let result = calculator.add(a, b)
        
        // Then
        XCTAssertEqual(result, 8)
    }
}

ViewModel 테스트

class WeatherViewModel: ObservableObject {
    @Published var temperature: Double = 0.0
    
    func convertToFahrenheit(_ celsius: Double) -> Double {
        return (celsius * 9/5) + 32
    }
}

class WeatherViewModelTests: XCTestCase {
    var viewModel: WeatherViewModel!
    
    override func setUp() {
        super.setUp()
        viewModel = WeatherViewModel()
    }
    
    func testTemperatureConversion() {
        // Given
        let celsius = 20.0
        
        // When
        let fahrenheit = viewModel.convertToFahrenheit(celsius)
        
        // Then
        XCTAssertEqual(fahrenheit, 68.0)
    }
}

Preview Provider를 활용한 UI 테스트:

struct ContentView: View {
    @StateObject var viewModel = WeatherViewModel()
    
    var body: some View {
        Text("\(viewModel.temperature)°C")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

SwiftUI 테스트 시 주요 고려사항

비즈니스 로직 분리

  • View에서 비즈니스 로직을 분리하여 ViewModel이나 별도 타입으로 구성
  • 순수 로직은 단위 테스트가 용이하도록 설계

의존성 주입

struct ContentView: View {
    @StateObject var viewModel: WeatherViewModel // 테스트를 위해 주입 가능

    init(viewModel: WeatherViewModel = WeatherViewModel()) {
        _viewModel = StateObject(wrappedValue: viewModel)
    }
}

비동기 테스트

func testAsyncOperation() async throws {
    // Given
    let expectation = XCTestExpectation(description: "Async operation")
    
    // When
    await viewModel.fetchWeatherData()
    
    // Then
    XCTAssertNotNil(viewModel.temperature)
    expectation.fulfill()
}

환경값(Environment) 테스트

struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme
    
    var body: some View {
        Text("Hello")
            .foregroundColor(colorScheme == .dark ? .white : .black)
    }
}

// 테스트
func testColorScheme() {
    let view = ContentView()
        .environment(\.colorScheme, .dark)
    // 테스트 로직
}

테스트 작성 시 기억할 점

  • Given-When-Then 패턴 사용
  • 각 테스트는 독립적이어야 함
  • 테스트 이름은 명확하게 작성
  • 실패 케이스도 테스트

Given-When-Then 패턴

func testExample() {
    // Given (준비)
    // 테스트에 필요한 초기 조건과 데이터를 설정
    let calculator = Calculator()
    let input = 5
    
    // When (실행)
    // 테스트하려는 동작을 실행
    let result = calculator.square(input)
    
    // Then (검증)
    // 결과를 검증
    XCTAssertEqual(result, 25)
}

각 부분의 역할:

  • Given: 테스트를 위한 전제 조건을 설정 (객체 생성, 초기값 설정 등)
  • When: 테스트하려는 실제 동작을 수행
  • Then: 예상한 결과가 나왔는지 확인
profile
while(true){ 가족(); 건강(); 자기개발(); }

0개의 댓글