Skip to content

Latest commit

 

History

History
195 lines (143 loc) · 6.85 KB

2.4.5.2 iOSTests.md

File metadata and controls

195 lines (143 loc) · 6.85 KB

iOS Testing

Примечание. Чтобы увидеть полный список утверждений XCTestAssertions, перейдите к утверждениям Apple, перечисленным по категориям.

Правила при написании тестов:

  1. Нейминг теста: test_whenFilterOneModelWithWrongQuarter_ItReturnNothing()
  2. sut должен называться тестируемый класс. sut (subject under test) означает «испытуемый предмет».
  3. Использовать Given-When-Then подход
  4. В тестах должна быть 1 логическая проверка. Количество XCTestAssertions может быть любым.

Пример теста:

Open

/// DealsTests
   
@testable import Deals
import XCTest
   
class Tests: XCTestCase {
 // MARK: - Properties
 private var sut, sut_withError: ViewModel!
   
 // MARK: - Test Lifecycle
 override funx setUp() {
   super.setUp()
   sut = ViewModel()
   sut_withError = ViewModel()
}
   
 override func tearDown() {
   super.tearDown()
   sut = nil
   sut_withError = nil
 }
   
 // MARK: - Tests
 func testFunction() {
   // given
   sut.property = 1
   
   // when
   sut.callFunction()
   
   // then
   XCTAssertEqual(sut.funcInvokedCount, 1)
 }
   
 func testPublisher() {
   // given
   var loadCompleted = false
   
   // when
   cancellable = sut.getResponse()
      .sink(receiveCompletion: { completion in
           if case .finished = completion {
               loadCompleted = true
           }
      }, receiveValue: { _ in })
   
   // then
   XCTAssertTrue(loadCompleted)
 }

 final class ViewModel: ViewModelProtocol {
   // MARK: - Testing
   private(set) var funcInvokedCount = 0

   // MARK: - ViewModelProtocol
  var property = 0

   func callFunction() { funcInvokedCount += 1 }

   func getResponse() -> AnyPublisher<Void, Never> {
     return Empty().eraseToAnyPublisher()
   }
 }

Тестирование асинхронного кода

Open

Для тестирования асинхронного кода можно использовать expectations:

    func testAsync() {
      //given
      let expectation = XCTestExpectation(description: "Download apple.com home page")

      //when
      sut?.reloadData()

      DispatchQueue.main.asyncAfter(dedline: .now() + 0.3) {
         expectation.fulfill()
      }

      wait(for: [expectation], timeout: 0.5)

      //then
      XCTAssertEqual(sut?.items.count, 2)
   }
   
   func testPublisher() {
      // given
      var loadCompleted = false
   
      // when
      cancellable = sut.getResponse()
         .sink(receiveCompletion: { completion in
            if case .finished = completion {
                loadCompleted = true
             }
         }, receiveValue: { _ in })
   
      // then
      XCTAssertTrue(loadCompleted)
   }

   func getResponse() -> AnyPublisher<Void, Never> {
     return Empty().eraseToAnyPublisher()
   }

expectation.fulfill() : вызовите это при закрытии условия успеха обработчика завершения асинхронного метода, чтобы отметить, что ожидание было выполнено.

wait (for: timeout :) : тест продолжается до тех пор, пока не будут выполнены все ожидания или пока timeout не закончится, в зависимости от того, что произойдет раньше.

Также можно использовать Sheduler вместо expectation:

Основная задача при тестировании Combine избавиться от использования expectation, чтобы тесты проходили намного быстрее, так как в перспективе, с увеличением количества тестов, таймауты сыграют неприятную роль в производительности тестов"

Тестирования производительности

Open

  • Testing Performance
  • Для тестирования произодительности необходимо добавить measure перед вызовом функции с метриками, которые нужно измерить:

    func testScoreIsComputedPerformance() {
      measure(
        metrics: [
          XCTClockMetric(), 
          XCTCPUMetric(),
          XCTStorageMetric(), 
          XCTMemoryMetric()
        ]
      ) {
        sut.check(guess: 100)
      }
    }
    

    Создать пустой Publisher:

    AnyPublisher<Model, Error>: Just(Model()).setFailureType(to: Error.self).eraseToAnyPublisher()

    AnyPublisher<Void, Error>: Empty().eraseToAnyPublisher()


    2.4.5.2 Driven Development Theme | Back To iOSWiki Contents | 2.5 Cybersecurity Theme Folder