Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Desenvolvimento guiado por testes no Android co...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Vinícius Soares
May 11, 2017
Technology
67
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Desenvolvimento guiado por testes no Android com MVP.
Vinícius Soares
May 11, 2017
More Decks by Vinícius Soares
See All by Vinícius Soares
Ruby on Rails 101
viniciussoares
0
92
Static Sites with GatsbyJS, React.js & Firebase
viniciussoares
0
88
Other Decks in Technology
See All in Technology
映像変換サーバーなしで端末内でHLSを生成してライブ配信
hikarusato
0
120
2026-09-11 【Snowflake World Tour Tokyo 2026】Snowflakeを起点に、AI Agentが自律稼働し続ける未来へ / Driving AI Agents with Snowflake
civitaspo
0
670
10Xに技術的負債をもたらした「2つの境界の歪み」その構造と解消への営み
10xinc
0
2k
LTのテーマ どうきめてる?〜5つの型と私のやり方〜
yama3133
1
110
range over func 2年間の軌跡 Issue #56413 はGoのエコシステムをどう変えたか
ryujicre8ive
0
190
すぐできる衛星通信対応 あとは山奥に行くだけ
tatetate55
0
130
銀行勘定系システムにおける開発プロセス刷新×AIによる環境モダナイゼーション / Development Process Transformation and AI-Driven Environment Modernization
muit
1
2.3k
データ_AIの事業の勝敗をわけるもの
nek0128
1
410
登壇の自信を奪う3匹のオバケ / 3 Ghosts That Rob You of Your Confidence in Public Speaking
pauli
9
980
Deployment の 先にある AI Agent 基盤 - kagent vNext、Agent Substrate、Hermes から読み解く Agent Runtime の現在地 / k8s-matsuri-2-ai-agent-platform-amsy810
masayaaoyama
4
630
AgentCore Runtime上にAgentic Coding基盤を構築・展開する際の設計ポイントと限界点 / Design considerations and limitations when building an agentic coding platform on AgentCore Runtime
har1101
4
220
積み重なった技術負債への挑戦 〜初手としての全社ゴト化〜
techtekt
PRO
0
1.3k
Featured
See All Featured
[SF Ruby Conf 2025] Rails X
palkan
3
1.4k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
410
For a Future-Friendly Web
brad_frost
183
10k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
810
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Documentation Writing (for coders)
carmenintech
77
5.5k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.1k
Designing for humans not robots
tammielis
254
26k
Designing Experiences People Love
moore
143
24k
The SEO identity crisis: Don't let AI make you average
varn
0
560
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
450
Facilitating Awesome Meetings
lara
57
7.1k
Transcript
Desenvolvimento guiado por testes no Android com MVP. Vinícius Soares
- @vinicius5oares
None
Por que usar TDD?
Por que usar TDD? Code design
Por que usar TDD? Manutenção
Por que usar TDD? Documentação
Por que usar TDD? É divertido
TDD - Test Driven Development
TDD - Test Driven Development Write a test that fails
TDD - Test Driven Development Write a test that fails
Make the code work
TDD - Test Driven Development Write a test that fails
Make the code work Remove redundancy
Model View Presenter
Model View Presenter
Model View Presenter
Model View Presenter
Model View Presenter
Dagger 2 - Dependency Injection medium.com/android-dev-br/introdução-ao-dagger-2-56d193118a6c
RxJava youtube.com/watch?v=0FpphC6hL5I
Mockito youtube.com/watch?v=DJDBl0vURD4
Mockito class Database { String getFirstProductName() { /* ... */
}; /* ... */ }
Mockito class Database { String getFirstProductName() { /* ... */
}; /* ... */ } Database mockDatabase = Mockito.mock(Database.class);
Mockito class Database { String getFirstProductName() { /* ... */
}; /* ... */ } Database mockDatabase = Mockito.mock(Database.class); System.out.print(mockDatabase.getFirstProductName()); // Prints: null Mockito.verify(mockDatabase).getFirstProductName();
Mockito class Database { String getFirstProductName() { /* ... */
}; /* ... */ } Database mockDatabase = Mockito.mock(Database.class);
Mockito class Database { String getFirstProductName() { /* ... */
}; /* ... */ } Database mockDatabase = Mockito.mock(Database.class); Mockito.when(mockDatabase.getFirstProductName()).thenReturn("Google Pixel"); System.out.print(mockDatabase.getFirstProductName()); // Prints: Google Pixel Mockito.verify(mockDatabase).getFirstProductName();
Mockito class Database { String getFirstProductName() { /* ... */
}; /* ... */ } Database mockDatabase = Mockito.mock(Database.class); Mockito.when(mockDatabase.getFirstProductName()).thenReturn("Google Pixel"); System.out.print(mockDatabase.getFirstProductName()); // Prints: Google Pixel Mockito.verify(mockDatabase).getFirstProductName();
Talk is cheap. Show me the code!
Planning • Mostrar a lista de artigos. • Mostrar um
Empty State se a lista estiver vazia.
Tests @Test public void loadArticlesReturnsArticles() { }
Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new
ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); }
Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new
ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); }
Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new
ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); }
Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new
ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); Mockito.verify(mockView).showArticles(articles); }
Tests @Test public void loadArticlesReturnsArticles() { List<Article> articles = new
ArrayList<>(); articles.add(/* ... */); articles.add(/* ... */); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); Mockito.verify(mockView).showArticles(articles); Mockito.verify(mockView, never()).showEmptyState(); }
Tests @Test public void loadArticlesReturnsEmptyList() { List<Article> articles = new
ArrayList<>(); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); }
Tests @Test public void loadArticlesReturnsEmptyList() { List<Article> articles = new
ArrayList<>(); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); }
Tests @Test public void loadArticlesReturnsEmptyList() { List<Article> articles = new
ArrayList<>(); Mockito.when(mockRepository.getArticles()).thenReturn(Observable.just(articles)); presenter.loadArticles(); Mockito.verify(mockView).showEmptyState(); Mockito.verify(mockView, never()).showArticles(ArgumentMatchers.anyList()); }
View interface ArticlesView { void showArticles(List<Articles> articles); void showEmptyState(); }
class ArticlesActivity extends AppCompatActivity implements ArticlesView { ArticlesPresenter presenter; protected
void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); presenter = new ArticlesPresenter(UserRepository.getInstance()); /* Use dagger */ presenter.attachView(this); } protected onDestroy() { super.onDestroy(); presenter.detachView(); } public void showArticles(List<Articles> articles) { /* ... */ } public void showEmptyState() { /* ... */ } }
Presenter class ArticlesPresenter { private ArticlesView view; public void attachView(ArticlesView
view) { this.view = view; } public void detachView() { this.view = null; } }
Presenter class ArticlesPresenter { private View view; private ArticlesRepository repository;
public ArticlesPresenter(ArticlesRepository repository) { this.repository = repository; } public void attachView(View view) { /* ... */ } public void detachView() { /* ... */ } }
Presenter public void detachView() { /* ... */ } public
void loadArticles() { repository.getArticles() /* ... */ .subscribe(articles -> { if (articles.isEmpty()) view.showArticlesEmptyState(); else view.showArticles(articles); }); } }
Model - Simple Example interface ArticlesRepository { @GET("articles") Observable<List<Article>> getArticles();
}
Model - Repository Pattern class ArticlesRepository { public Observable<List<Article>> getArticles()
{ Observable<List<Article>> memory = /* ... */; Observable<List<Article>> database = /* ... */; Observable<List<Article>> api = /* ... */; return Observable .concat(memory, database, api) .first(); } }
Links • github.com/googlesamples/android-architecture/tree/todo-mvp-rxjava • github.com/ribot/android-boilerplate • codelabs.developers.google.com/codelabs/android-testing/index.html
Próximos passos • Clean Architecture • Espresso & UiAutomator. •
Cobertura de Testes • Code Analysis tools • Continuous integration
Obrigado :) speakerdeck.com/viniciussoares @vinicius5oares @vinicius-soares