Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Testes_-_A_que_será_que_se_destina__-_V2.pdf
Search
Ronan Rodrigo Nunes
November 29, 2021
Programming
0
98
Testes_-_A_que_será_que_se_destina__-_V2.pdf
Ronan Rodrigo Nunes
November 29, 2021
Tweet
Share
More Decks by Ronan Rodrigo Nunes
See All by Ronan Rodrigo Nunes
Audio Capture
ronanrodrigo
0
53
Testes - A que será que se destina?
ronanrodrigo
1
140
Métodos, Técnicas e Ferramentas de Desenvolvimento de Software
ronanrodrigo
1
55
Uma decisão pode custar caro
ronanrodrigo
1
150
Crie aplicativos adiando decisões
ronanrodrigo
0
38
Por que eu criei uma biblioteca Open Source?
ronanrodrigo
0
150
Com quantas views se faz uma APP?
ronanrodrigo
0
64
VIPER - Arquitetura limpa em nossos APPs
ronanrodrigo
1
660
Other Decks in Programming
See All in Programming
Claude Codeで実装以外の開発フロー、どこまで自動化できるか?失敗と成功
ndadayo
2
760
LLMOpsのパフォーマンスを支える技術と現場で実践した改善
po3rin
8
970
オホーツクでコミュニティを立ち上げた理由―地方出身プログラマの挑戦 / TechRAMEN 2025 Conference
lemonade_37
2
490
フロントエンドのmonorepo化と責務分離のリアーキテクト
kajitack
2
130
バイブコーディングの正体——AIエージェントはソフトウェア開発を変えるか?
stakaya
5
1k
兎に角、コードレビュー
mitohato14
0
150
コンテキストエンジニアリング Cursor編
kinopeee
1
680
Portapad紹介プレゼンテーション
gotoumakakeru
1
130
CEDEC 2025 『ゲームにおけるリアルタイム通信への QUIC導入事例の紹介』
segadevtech
3
950
『リコリス・リコイル』に学ぶ!! 〜キャリア戦略における計画的偶発性理論と変わる勇気の重要性〜
wanko_it
1
590
管你要 trace 什麼、bpftrace 用下去就對了 — COSCUP 2025
shunghsiyu
0
450
20250808_AIAgent勉強会_ClaudeCodeデータ分析の実運用〜競馬を題材に回収率100%の先を目指すメソッドとは〜
kkakeru
0
200
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1370
200k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Speed Design
sergeychernyshev
32
1.1k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
820
GitHub's CSS Performance
jonrohan
1031
460k
Testing 201, or: Great Expectations
jmmastey
45
7.6k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
What’s in a name? Adding method to the madness
productmarketing
PRO
23
3.6k
A Modern Web Designer's Workflow
chriscoyier
695
190k
Agile that works and the tools we love
rasmusluckow
329
21k
Transcript
Testes: A que será que se destina? Breve história sobre
testes, boas e más práticas no ecossistema Apple Ronan Rodrigo Nunes
Arqueologia
None
None
2005 Xcode 2.1 OCUnit 2013 Xcode 5.0 XCTest 2015 Xcode
7.0 XCUITest
Cultura
None
Não vejo benefício “
Meu código funciona perfeitamente, por que eu testaria? “
Até APP com testes tem bugs “
Até APP com testes tem bugs “
Não sei como, nem o que testar “
Não sei como, nem o que testar “ classona classinha
extrair injetar testar ✔
Não temos tempo “
É difícil e complicado “
Meu time não tem a cultura de testar “ mobster.cc
O que ganho com isso?
👃 Cheiro de que?
🏰 Arquitete-se
🧘 Equilibrio
⛹ Domínio
✍ Documentação
Boas práticas & Smells & Armadilhas
func test_primaryButtonTapped_doesRouteToFullSheet() { // given XCTAssertTrue(router.routeToFullSheetCallCount == 0) // when
interactor.primaryButtonTapped() // then XCTAssertTrue(router.routeToFullSheetCallCount == 1) } ✘
func test_primaryButtonTapped_doesRouteToFullSheet() { XCTAssertTrue(router.routeToFullSheetCallCount == 0) interactor.primaryButtonTapped() XCTAssertTrue(router.routeToFullSheetCallCount == 1)
} ✘
func test_primaryButtonTapped_doesRouteToFullSheet() { interactor.primaryButtonTapped() XCTAssertTrue(router.routeToFullSheetCallCount == 1) } ✘
func test_primaryButtonTapped_doesRouteToFullSheet() { interactor.primaryButtonTapped() XCTAssertEqual(router.routeToFullSheetCallCount, 1) } ✔︎
func test_startReport_doesRouteToReportFlow() { interactor.startReport() XCTAssertEqual(router.routeToReportFlowCallCount, 1) } ✔︎
func test_allByMonth_existingMonth_callCompletionWithItems() { var expectedGroupedFoods: [GroupedFoods]? // ... guard let
expectedGroupedFoods = expectedGroupedFoods, firstGroup = expectedGroupedFoods.first else { XCTFail("empty expectedGroupedFoods") } XCTAssertFalse(firstGroup.foods.isEmpty) } ✘
func test_allByMonth_existingMonth_callCompletionWithItems() { var expectedGroupedFoods: [GroupedFoods]? // ... XCTAssertFalse(expectedGroupedFoods!.first!.foods.isEmpty) }
✘
func test_allByMonth_existingMonth_callCompletionWithItems() { var expectedGroupedFoods: [GroupedFoods]? // ... if let
expectedGroupedFoods = expectedGroupedFoods { if let firstGroup = expectedGroupedFoods.first { XCTAssertFalse(firstGroup.foods.isEmpty) } } } ✘
func test_allByMonth_existingMonth_callCompletionWithItems() { var expectedGroupedFoods: [GroupedFoods]? // ... XCTAssertEqual(expectedGroupedFoods?.first?.foods.isEmpty, false)
XCTAssertEqual(expectedGroupedFoods?.first?.foods.count, 4) } ✔︎
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) } ✘
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) } ✔︎
func test_finishReport_completeFlow() { var completed = false interactor.myEventStream().subscribe { _
in completed = true } .disposed(by: disposeBag) interactor.finish() XCTAssertTrue(completed) } ✘
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) } ✔︎
class ReportTripInteractorTests: XCTestCase class ReportTripInteractor_StartTripTests: ReportTripInteractorTests class ReportTripInteractor_FinishingTripTests: ReportTripInteractorTests class
ReportTripInteractor_SearchingTripTests: ReportTripInteractorTests class ReportTripInteractor_WaintingTripTests: ReportTripInteractorTests ✔︎
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) } ✘
class Worker { func start(_ interactor: AnyInteractor) { someObservable .subscribe(someStream.dataSubject)
.disposeOnStop(self) } } .subscribe(someStream.dataSubject)
class Worker { func start(_ interactor: AnyInteractor) { someObservable .disposeOnStop(self)
} }
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) } ✔︎
func test_schedule_createEvent() { // ... } ✘
func test_givenMonthExist_whenContainsMeeting_thenCreateEvent() { // ... } func test_monthExist_containsMeeting_createEvent() { //
... } func testScheduleEvent_monthExist_containsMeeting_createEvent() { // ... } func test_itMonthExist_andContainsMeeting_shouldCreateEvent() { // ... } ✔︎
Obrigado
Obrigado ronanrodrigo.dev
Obrigado ronanrodrigo.dev ronanrodrigo.dev/slides