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
S3 Filesで挑む! 八戸せんべい汁の食べ頃問題
usanchuu
0
110
専門領域のAIをどう評価するか
bengo4com
2
270
AIカンパニーへの転換を支えた、エンジニアの仕事の再定義
kworkdev
PRO
2
1.3k
Browser Spec: Testing Hotwire with Ruby
takahashim
1
130
夫婦で子育てするための育児標準化
codmoninc
PRO
0
430
事業成長とデータ活用を止めないためのマネジメントへ挑戦
hiracky16
0
400
PHPカンファレンス関西の招待状 / Invitation to PHP Conference Kansai
ykanoh
0
200
10年後、Engineering 行為を剥奪されるとして、わたしたちは、どう、何を創ればいいだろうか。 / If Engineering Is Taken Away in 10 Years, How and What Should We Create?
bitkey
PRO
1
200
AI駆動で「他アプリの音を加工できる」アプリを作った
satomasahiro2005
0
170
hackers_champloo_2026_tidb
makocchi
0
170
Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
1
720
Conditional PED-ANOVA: Hyperparameter Importance in Hierarchical & Dynamic Search Spaces
pfn
PRO
0
140
Featured
See All Featured
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
Color Theory Basics | Prateek | Gurzu
gurzu
1
490
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
500
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
440
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
1
280
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
930
Optimising Largest Contentful Paint
csswizardry
37
4k
Mind Mapping
helmedeiros
1
400
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
360
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
Un-Boring Meetings
codingconduct
0
460
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