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
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
夫婦で子育てするための育児標準化
codmoninc
PRO
0
420
実体験から学ぶ分析エージェントの開発と運⽤
recruitengineers
PRO
8
2.4k
Optunaの最新リリースv5.0について
pfn
PRO
0
120
Post AI時代のリファクタリング実践記 / Refactoring in the post AI era
kaminashi
1
270
スプシの手作業からの解脱 ~更新はClaude Codeに、見せ方と使い方はGASアプリに任せる~
kentarofujii
0
160
Local CI × GitHub Actions
gogutan
2
220
AI駆動で「他アプリの音を加工できる」アプリを作った
satomasahiro2005
0
170
アウトプット初心者、半年間のふりかえり
4o1sobblue
0
440
Claude の新機能を、 出た日に触って社内に届けるまで
rfdnxbro
1
190
ストレスなくAIと付き合いたい!こんなときどうしてる?
namiki64
3
590
V8のArray.prototype.flatを最大約20倍速くするまでと、巨大OSSへの大規模コミットの道のり
riyaamemiya
0
300
無理せず続ける、子育てエンジニアの学び
codmoninc
PRO
0
960
Featured
See All Featured
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
18k
Mind Mapping
helmedeiros
1
400
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
500
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
Designing for humans not robots
tammielis
254
26k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
550
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.5k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3.1k
ラッコキーワード サービス紹介資料
rakko
1
5.4M
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
710
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
940
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
930
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