Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testes_-_A_que_será_que_se_destina__-_V2.pdf

 Testes_-_A_que_será_que_se_destina__-_V2.pdf

Ronan Rodrigo Nunes

November 29, 2021
Tweet

More Decks by Ronan Rodrigo Nunes

Other Decks in Programming

Transcript

  1. Testes: A que será
    que se destina?
    Breve história sobre testes, boas e más práticas no ecossistema Apple
    Ronan Rodrigo Nunes

    View Slide

  2. Arqueologia

    View Slide

  3. View Slide

  4. View Slide

  5. 2005
    Xcode 2.1
    OCUnit
    2013
    Xcode 5.0
    XCTest
    2015
    Xcode 7.0
    XCUITest

    View Slide

  6. Cultura

    View Slide

  7. View Slide

  8. Não vejo benefício

    View Slide

  9. Meu código funciona
    perfeitamente, por que
    eu testaria?

    View Slide

  10. Até APP com testes tem
    bugs

    View Slide

  11. Até APP com testes tem
    bugs

    View Slide

  12. Não sei como,
    nem o que testar

    View Slide

  13. Não sei como,
    nem o que testar

    classona
    classinha
    extrair
    injetar
    testar

    View Slide

  14. Não temos tempo

    View Slide

  15. É difícil e complicado

    View Slide

  16. Meu time não tem a
    cultura de testar

    mobster.cc

    View Slide

  17. O que ganho com isso?

    View Slide

  18. 👃 Cheiro de que?

    View Slide

  19. 🏰 Arquitete-se

    View Slide

  20. 🧘 Equilibrio

    View Slide

  21. ⛹ Domínio

    View Slide

  22. ✍ Documentação

    View Slide

  23. Boas práticas &
    Smells &
    Armadilhas

    View Slide

  24. func test_primaryButtonTapped_doesRouteToFullSheet() {


    // given


    XCTAssertTrue(router.routeToFullSheetCallCount == 0)


    // when


    interactor.primaryButtonTapped()


    // then


    XCTAssertTrue(router.routeToFullSheetCallCount == 1)


    }

    View Slide

  25. func test_primaryButtonTapped_doesRouteToFullSheet() {


    XCTAssertTrue(router.routeToFullSheetCallCount == 0)


    interactor.primaryButtonTapped()


    XCTAssertTrue(router.routeToFullSheetCallCount == 1)


    }

    View Slide

  26. func test_primaryButtonTapped_doesRouteToFullSheet() {


    interactor.primaryButtonTapped()


    XCTAssertTrue(router.routeToFullSheetCallCount == 1)


    }

    View Slide

  27. func test_primaryButtonTapped_doesRouteToFullSheet() {


    interactor.primaryButtonTapped()


    XCTAssertEqual(router.routeToFullSheetCallCount, 1)


    }
    ✔︎

    View Slide

  28. func test_startReport_doesRouteToReportFlow() {


    interactor.startReport()


    XCTAssertEqual(router.routeToReportFlowCallCount, 1)


    }
    ✔︎

    View Slide

  29. func test_allByMonth_existingMonth_callCompletionWithItems() {


    var expectedGroupedFoods: [GroupedFoods]?


    // ...


    guard let expectedGroupedFoods = expectedGroupedFoods,


    firstGroup = expectedGroupedFoods.first else {


    XCTFail("empty expectedGroupedFoods")


    }


    XCTAssertFalse(firstGroup.foods.isEmpty)


    }

    View Slide

  30. func test_allByMonth_existingMonth_callCompletionWithItems() {


    var expectedGroupedFoods: [GroupedFoods]?


    // ...


    XCTAssertFalse(expectedGroupedFoods!.first!.foods.isEmpty)


    }

    View Slide

  31. func test_allByMonth_existingMonth_callCompletionWithItems() {


    var expectedGroupedFoods: [GroupedFoods]?


    // ...


    if let expectedGroupedFoods = expectedGroupedFoods {


    if let firstGroup = expectedGroupedFoods.first {


    XCTAssertFalse(firstGroup.foods.isEmpty)


    }


    }


    }

    View Slide

  32. func test_allByMonth_existingMonth_callCompletionWithItems() {


    var expectedGroupedFoods: [GroupedFoods]?


    // ...


    XCTAssertEqual(expectedGroupedFoods?.first?.foods.isEmpty,
    false)


    XCTAssertEqual(expectedGroupedFoods?.first?.foods.count, 4)


    }
    ✔︎

    View Slide

  33. func test_allByMonth_existingMonth_callCompletionWithItems() {


    var expectedGroupedFoods: [GroupedFoods]?


    let month = MonthGatewayFactory.make().month(number: 1)


    gateway.all(byMonth: month) { expectedGroupedFoods = $0.data }


    XCTAssertEqual(expectedGroupedFoods?.isEmpty, false)


    }

    View Slide

  34. func test_allByMonth_existingMonth_callCompletionWithItems() {


    var expectedGroupedFoods: [GroupedFoods]?


    let month = MonthGatewayFactory.make().month(number: 1)


    gateway.all(byMonth: month) {


    expectedGroupedFoods = $0.data


    }


    XCTAssertEqual(expectedGroupedFoods?.isEmpty, false)


    }
    ✔︎

    View Slide

  35. func test_finishReport_completeFlow() {


    var completed = false


    interactor.myEventStream().subscribe { _ in


    completed = true


    }


    .disposed(by: disposeBag)


    interactor.finish()


    XCTAssertTrue(completed)


    }

    View Slide

  36. func test_finishReport_completeFlow() {


    var completed = false


    onCompleteFlow(completed = true)


    interactor.finish()


    XCTAssertTrue(completed)


    }


    func onCompleteFlow(_ fn: @escaping @autoclosure () -> ()) {


    interactor.myEventStream()


    .subscribe { _ in fn() }


    .disposeOnTearDown(testCase: self)


    }
    ✔︎

    View Slide

  37. class ReportTripInteractorTests: XCTestCase


    class ReportTripInteractor_StartTripTests:
    ReportTripInteractorTests


    class ReportTripInteractor_FinishingTripTests:
    ReportTripInteractorTests


    class ReportTripInteractor_SearchingTripTests:
    ReportTripInteractorTests


    class ReportTripInteractor_WaintingTripTests:
    ReportTripInteractorTests
    ✔︎

    View Slide

  38. func test_start_validInteractor_createEventAtStream() {


    let expectedResponse = Response(uuid: "id")


    shareService.fetchHandler = { _ in .just(expectedResponse) }


    worker.start(interactor)


    someStream.dataSubject


    .subscribe(onNext: { eventResponse in


    XCTAssertEqual(expectedResponse, eventResponse)


    })


    .disposed(by: disposeBag)


    }

    View Slide

  39. class Worker {


    func start(_ interactor: AnyInteractor) {


    someObservable


    .subscribe(someStream.dataSubject)


    .disposeOnStop(self)


    }


    }
    .subscribe(someStream.dataSubject)

    View Slide

  40. class Worker {


    func start(_ interactor: AnyInteractor) {


    someObservable


    .disposeOnStop(self)


    }


    }

    View Slide

  41. func test_start_validInteractor_createEventAtStream() {


    let expectedResponse = Response(uuid: "id")


    shareService.fetchHandler = { _ in .just(expectedResponse) }


    var eventResponse: Response?


    someStream.dataSubject


    .subscribe(onNext: { eventResponse = $0 })


    .disposed(by: disposeBag)


    worker.start(interactor)


    XCTAssertEqual(expectedResponse, eventResponse)


    }
    ✔︎

    View Slide

  42. func test_schedule_createEvent() {


    // ...


    }

    View Slide

  43. func test_givenMonthExist_whenContainsMeeting_thenCreateEvent() {


    // ...


    }


    func test_monthExist_containsMeeting_createEvent() {


    // ...


    }


    func testScheduleEvent_monthExist_containsMeeting_createEvent() {


    // ...


    }


    func test_itMonthExist_andContainsMeeting_shouldCreateEvent() {


    // ...


    }
    ✔︎

    View Slide

  44. Obrigado

    View Slide

  45. Obrigado
    ronanrodrigo.dev

    View Slide

  46. Obrigado
    ronanrodrigo.dev
    ronanrodrigo.dev/slides

    View Slide