TDD, 단위 테스트, XCTest로 iOS 앱 테스트하기

Bibi·2022년 3월 3일
0

TDD, 단위 테스트

  • 테스트 메서드가 private이면 무조건 성공으로 나오니 조심하자..

https://velog.io/@minni/TDD%EC%99%80-Swift-XCTest-%ED%99%9C%EC%9A%A9%ED%95%98%EA%B8%B0

  • TDD : Test Driven Development
    • 기존의 설계 -> 개발 -> 테스트 가 아닌, 설계 -> 테스트 -> 개발 의 순서로 작업
    • 설계 문제로 인한 오류를 빠르게 잡아낼 수 있다.
    • TDD의 장점
      • 디버깅 시간을 단축할 수 있다.
      • 객체지향적 설계가 가능하다. 유지보수가 가능하다.
      • 테스트를 자동화하고 테스트 문서로 삼을 수 있다.
  • Red, Green, Blue / Triple A (Arrange, Act, Assert)
    • 매 구현 단계마다 Red - Green - Blue 를 반복하며 개발한다.
    • Red : 실패. 실패하는 테스트 케이스 작성하기
    • Green : 성공. 실패하는 테스트 케이스를 성공시키기 위한 최소한의 코드 작성하기
    • Blue : 리팩토링. 성공한 테스트 케이스를 리팩토링하기.
  • 단위테스트 : Unit Test
    • 기능 단위의 테스트 코드를 작성하는 것.
    • 즉 모든 기능(메서드)에 대한 테스트케이스를 작성하는 절차를 말함.
    • 단위테스트의 장점
      • 코드 변경으로 인한 디버깅을 빠르게 해 준다.
      • 단위테스트를 믿고 리팩토링을 편하게 할 수 있고, 리팩토링 후 단위테스트로 재검증이 가능하다.
    • FIRST : 좋은 단위테스트 작성 원칙
      • Fast : 빠른. 테스트는 빠르게 실행되어야 함
      • Isolated : 독립된. 테스트는 따로 설정이나 분리를 해서는 안 됨
      • Repeatable : 반복 가능한. 테스트를 반복 수행해도 같은 결과여야 한다.
      • Self-validating : 자체 검증. 테스트는 완전히 자동화되어야 한다. 테스트 결과를 또 해석할 필요 없이, pass 또는 fail을 출력하게 한다.
      • Timely : 적시에. 테스트 코드는 개발 전에 작성해야 한다.

XCTest 로 iOS 앱 테스트하기 - Test Navigator

https://www.raywenderlich.com/21020457-ios-unit-testing-and-ui-testing-tutorial

  • 테스트는 무엇을 테스트해야 하는가?
    • 핵심 기능 - 모델 클래스들과 메서드들, 컨트롤러와의 상호작용
    • UI 작업 흐름
    • 경계 조건
    • 버그 해결

유닛 테스트 만들기

  1. XCode 프로젝트에서 command + 6을 입력해 테스트 네비게이터를 연다.
  2. New Unit Test Target 선택
    1. 프로젝트명 + Tests 이름의 클래스가 XCTest를 import 하고, XCTestCase를 상속받은 채로 생성됨
    2. setUpWithError(), tearDownWithError() 라는 오버라이딩 메서드 자동 생성
    3. 예시 테스트 메서드인 testExample(), testPerformanceExample() 자동 생성
  3. 테스트 실행하기 : Command + U (전체 실행), 다이아몬드 버튼 누르기(개별 실행)
  4. Performance Result 확인하기 : 회색 다이아몬드 버튼 누르기

모델 테스트를 위해 XCTAssert 사용하기

import XCTest

@testable import PokerGameApp // 기능을 테스트할 모델 가져오기 - 모델의 내부 타입과 메서드에 접근 가능하게 함

class PokerGameAppTests: XCTestCase {
    
    var systemUnderTest: PokerGame! // System Under Test

    override func setUpWithError() throws {
        // Put setup code here. This method is called before the invocation of each test method in the class.
        try super.setUpWithError()
        systemUnderTest = PokerGame(playerNames: ["A", "B"]) // 테스트할 객체 생성
        // SUT는 setUpWithError()에서 만들고, tearDownWithError()에서 해제하는 것이 좋다.
    }

    override func tearDownWithError() throws {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        systemUnderTest = nil // 테스트한 객체 릴리즈
        try super.tearDownWithError()
    }
  
}
  1. import XCTest 아래에 기능을 테스트할 모델을 가져온다. @testable import 모델명

  2. PokerGameAppTests의 프로퍼티로 var systemUnderTest: 테스트할 객체를 선언한다.

    1. SUT(System Under Unit) : 테스트 케이스 클래스가 테스트할 객체를 말함
  3. SUT는 setUpWithError()에서 만들고, tearDownWithError()에서 해제하는 것이 좋다.

    1. setUpWithError() 에 아래 코드를 추가한다.

      1. try super.setUpWithError()
        systemUnderTest = PokerGame()
      2. 테스트할 객체를 클래스 수준에서 생성해, 테스트 클래스의 모든 테스트가 SUT 객체의 프로퍼티와 메서드에 접근할 수 있도록 한다.

      3. set up = 설립하다

    2. tearDownWithError()에 아래 코드를 추가한다.

      1. systemUnderTest = nil
        try super.tearDownWithError()
      2. SUT 객체를 릴리즈하는 작업이다.

      3. tear down = 해체하다

테스트 케이스 작성하기 - Given, When, Then

  • 테스트 메서드 이름 : 항상 test로 시작하고, 무엇을 테스트하는지에 대해 설명해야 한다.
  • 테스트 메서드는 given, when, then 부분으로 나누어 작성하는 것이 좋다.
    • Given : 테스트에 필요한 값을 설정하는 부분.
    • When : 테스트할 코드를 실행하는 부분. 예를 들어 메서드를 실행함
    • Then : 테스트에 기대되는 결괏값을 단정하는 부분 - 실패 시 메시지를 출력함.
  • 테스트 디버깅 : 실패하는 테스트 디버깅하기
    • 실패하는 테스트를 만들어 둔다.
    • Test Failure Breakpoint를 만들어 어디에서 실패했는지 디버깅할 수 있다.
      • 테스트 메서드에서 실패 Assertion이 발생했을 때 테스트 실행을 멈춘다.
    • 이후 Xcode 디버거로 평소처럼 디버깅을 하면 된다.

0개의 댓글