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
110
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
64
Testes - A que será que se destina?
ronanrodrigo
1
150
Métodos, Técnicas e Ferramentas de Desenvolvimento de Software
ronanrodrigo
1
61
Uma decisão pode custar caro
ronanrodrigo
1
150
Crie aplicativos adiando decisões
ronanrodrigo
0
44
Por que eu criei uma biblioteca Open Source?
ronanrodrigo
0
160
Com quantas views se faz uma APP?
ronanrodrigo
0
74
VIPER - Arquitetura limpa em nossos APPs
ronanrodrigo
1
690
Other Decks in Programming
See All in Programming
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
240
CSC307 Lecture 01
javiergs
PRO
0
670
AIエージェント、”どう作るか”で差は出るか? / AI Agents: Does the "How" Make a Difference?
rkaga
3
1.6k
インターン生でもAuth0で認証基盤刷新が出来るのか
taku271
0
170
.NET Conf 2025 の興味のあるセッ ションを復習した / dotnet conf 2025 quick recap for backend engineer
tomohisa
0
110
LLM Observabilityによる 対話型音声AIアプリケーションの安定運用
gekko0114
2
350
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
480
gunshi
kazupon
1
140
Findy AI+の開発、運用におけるMCP活用事例
starfish719
0
2.2k
Data-Centric Kaggle
isax1015
2
530
AtCoder Conference 2025「LLM時代のAHC」
imjk
2
660
CSC307 Lecture 02
javiergs
PRO
1
760
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.5k
Chasing Engaging Ingredients in Design
codingconduct
0
97
Design in an AI World
tapps
0
120
AI: The stuff that nobody shows you
jnunemaker
PRO
2
170
Designing for Performance
lara
610
70k
So, you think you're a good person
axbom
PRO
2
1.9k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
1.5k
We Are The Robots
honzajavorek
0
130
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.9k
The Invisible Side of Design
smashingmag
302
51k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
880
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.7k
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