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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Ronan Rodrigo Nunes
November 29, 2021
Programming
0
120
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
70
Testes - A que será que se destina?
ronanrodrigo
1
150
Métodos, Técnicas e Ferramentas de Desenvolvimento de Software
ronanrodrigo
1
62
Uma decisão pode custar caro
ronanrodrigo
1
150
Crie aplicativos adiando decisões
ronanrodrigo
0
46
Por que eu criei uma biblioteca Open Source?
ronanrodrigo
0
160
Com quantas views se faz uma APP?
ronanrodrigo
0
75
VIPER - Arquitetura limpa em nossos APPs
ronanrodrigo
1
700
Other Decks in Programming
See All in Programming
Honoを使ったリモートMCPサーバでAIツールとの連携を加速させる!
tosuri13
1
180
ノイジーネイバー問題を解決する 公平なキューイング
occhi
0
110
生成AIを活用したソフトウェア開発ライフサイクル変革の現在値
hiroyukimori
PRO
0
100
AI時代の認知負荷との向き合い方
optfit
0
160
FOSDEM 2026: STUNMESH-go: Building P2P WireGuard Mesh Without Self-Hosted Infrastructure
tjjh89017
0
170
Claude Codeと2つの巻き戻し戦略 / Two Rewind Strategies with Claude Code
fruitriin
0
140
AIフル活用時代だからこそ学んでおきたい働き方の心得
shinoyu
0
140
余白を設計しフロントエンド開発を 加速させる
tsukuha
7
2.1k
360° Signals in Angular: Signal Forms with SignalStore & Resources @ngLondon 01/2026
manfredsteyer
PRO
0
130
今こそ知るべき耐量子計算機暗号(PQC)入門 / PQC: What You Need to Know Now
mackey0225
3
380
AI Schema Enrichment for your Oracle AI Database
thatjeffsmith
0
320
なぜSQLはAIぽく見えるのか/why does SQL look AI like
florets1
0
480
Featured
See All Featured
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.6k
Done Done
chrislema
186
16k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
1
1.4k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
0
210
From Legacy to Launchpad: Building Startup-Ready Communities
dugsong
0
140
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
0
140
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
170
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.3k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
150
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
940
Documentation Writing (for coders)
carmenintech
77
5.3k
Six Lessons from altMBA
skipperchong
29
4.2k
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