How to build rock solid apps and keep 100m+ users happy
-
Upload
iordanis-giannakakis -
Category
Engineering
-
view
977 -
download
5
description
Transcript of How to build rock solid apps and keep 100m+ users happy
![Page 1: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/1.jpg)
How to build rock-solid apps and keep 100m+ users happy
Iordanis Giannakakis
![Page 2: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/2.jpg)
About me
• Iordanis “Jordan” Giannakakis
• Android Team Lead at Shazam
• @iordanis_g
@iordanis_g
![Page 3: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/3.jpg)
How Shazam works
@iordanis_g
![Page 4: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/4.jpg)
100+ million users
@iordanis_g
![Page 5: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/5.jpg)
Happy users
@iordanis_g
Even developers?
![Page 6: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/6.jpg)
Android testing
@iordanis_g
![Page 7: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/7.jpg)
Faster release cycles
@iordanis_g
![Page 8: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/8.jpg)
Better code
@iordanis_g
![Page 10: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/10.jpg)
Easy
@iordanis_g
![Page 11: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/11.jpg)
A user walks into a bar...
@iordanis_g
![Page 12: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/12.jpg)
Doing it the test-driven way
@iordanis_g
Write UI test
Implement
Refactor
Write unit test
BDD
TDD
![Page 13: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/13.jpg)
“To TDD or not to TDD?
@iordanis_g
...That is not the question” Seb Rose
http://claysnow.co.uk/to-tdd-or-not-to-tdd/
![Page 14: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/14.jpg)
Test-first
@iordanis_g
• Generally easier
• Eliminates external dependencies
• Easily repeatable
![Page 15: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/15.jpg)
The Acceptance tests cycle
@iordanis_g
Write UI test
Implement
Refactor
Write unit test
BDD
TDD
![Page 16: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/16.jpg)
Acceptance criteria
@iordanis_g
Given: arrange
When: act
Then: assert
![Page 17: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/17.jpg)
Example
@iordanis_g
Given a user is near a music venue
And the server always returns a known result
When the user Shazams
Then the user can check-in their discovery
![Page 18: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/18.jpg)
gwen
@iordanis_g
given(user).isNear(lexington())
given(server).returns(lustForLife())
when(user).shazams()
then(user).canCheckIn(lustForLife(), lexington())
https://github.com/shazam/gwen
![Page 19: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/19.jpg)
Acceptance tests technologies
@iordanis_g
• Instrumentation
• JUnit 3
• Robotium & Espresso
• gwen
• HamMock Server
![Page 20: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/20.jpg)
The Unit tests cycle
@iordanis_g
Write UI test
Implement
Refactor
Write unit test
BDD
TDD
![Page 21: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/21.jpg)
What we don’t test
@iordanis_g
Activities & Fragments
https://github.com/xxv/android-lifecycle/
![Page 22: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/22.jpg)
What we don’t test
@iordanis_g
![Page 23: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/23.jpg)
What we do unit test
@iordanis_g
• Presentation logic
• Business logic
• That’s all!
![Page 24: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/24.jpg)
The MVP pattern
@iordanis_g
Presenter
Model View
![Page 25: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/25.jpg)
The MVP pattern, for Android
@iordanis_g
Presenter
Model
View
start
stop
Android
![Page 26: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/26.jpg)
The MVP pattern
@iordanis_g
• Makes presentation logic testable
• No need to test the “slave” view
• Avoid Android dependencies
![Page 27: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/27.jpg)
Dependency Injection, Yourself (DIY)
@iordanis_g
• Break hardcoded dependencies
• Behaviour vs implementation
• Swappable dependencies for test and production runtimes
![Page 28: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/28.jpg)
Hard-coded dependencies
@iordanis_g
Client
Feature X Feature X
![Page 29: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/29.jpg)
Dependency Injection
@iordanis_g
Client
Injector
Feature X Interface
![Page 30: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/30.jpg)
Model
@iordanis_g
public interface VenueRetriever {
void findClosestVenue(VenueFoundCallback callback);
}
public class NetworkVenueRetriever implements VenueRetriever {
public void findClosestVenue(VenueFoundCallback callback) {
// Some slow networking
}
}
public class LocalVenueRetriever implements VenueRetriever {
public void findClosestVenue(VenueFoundCallback callback) {
// DB look-up / caching layer, perhaps?
}
}
![Page 31: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/31.jpg)
Activity
@iordanis_g
public class ResultActivity extends Activity implements ResultView {
private final VenueRetriever venueRetriever;
private ResultPresenter resultPresenter;
public ResultActivity() {
venueRetriever = venueRetriever();
}
public void onCreate(Bundle savedInstanceState) {
// TODO: Setup layouts & views
Result result = resultToDisplay();
resultPresenter = new ResultPresenter(this, venueRetriever, result);
}
public void onStart() {
resultPresenter.startPresenting();
}
}
![Page 32: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/32.jpg)
Presenter
@iordanis_g
public class ResultPresenter {
public ResultPresenter(ResultView resultView, VenueRetriever
venueRetriever, Result result) {
this.resultView = resultView;
this.venueRetriever = venueRetriever;
this.result = result;
}
public void startPresenting() {
resultView.showResult(result);
venueRetriever.findClosestVenue(new VenueFoundCallback() {
public void venueFound(Venue venue) {
resultView.showCheckInPrompt(venue);
}
});
}
}
![Page 33: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/33.jpg)
View
@iordanis_g
public interface ResultView {
void showResult(Result track);
void showCheckInPrompt(Venue venue);
}
![Page 34: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/34.jpg)
Activity
@iordanis_g
public class ResultActivity extends Activity implements ResultView {
public void showResult(Result result) {
//TODO show the result screen & bind result data
}
public void showCheckInPrompt(Venue venue) {
//TODO bind the venue with check-in prompt view
}
}
![Page 35: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/35.jpg)
Unit tests technologies
@iordanis_g
• JUnit 4
• Robolectric java.lang.RuntimeException: Stub!
• Hamcrest
• JMock
![Page 36: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/36.jpg)
Test execution
@iordanis_g
![Page 37: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/37.jpg)
Continuous Integration
@iordanis_g
![Page 38: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/38.jpg)
Speed (Hint: slow)
@iordanis_g
![Page 39: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/39.jpg)
Usual execution
@iordanis_g
Test Suite
![Page 41: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/41.jpg)
Fork
@iordanis_g
Test Suite
![Page 42: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/42.jpg)
Fork
@iordanis_g
• Inspired by Spoon, but faster
• Infinitely scalable
• Current setup 1 test / 2 secs
• Pooled execution
![Page 43: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/43.jpg)
Flakiness monitor
@iordanis_g
![Page 44: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/44.jpg)
ADB Remote
@iordanis_g
https://github.com/sleekweasel/CgiAdbRemote
![Page 45: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/45.jpg)
If all else fails...
@iordanis_g
![Page 46: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/46.jpg)
If all else fails...
@iordanis_g
![Page 47: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/47.jpg)
If all else fails...
@iordanis_g
![Page 48: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/48.jpg)
Summary
@iordanis_g
• Testing is easier than you may think
• Practice, practice, practice
• Toolset is limited
• Ship it!
![Page 49: How to build rock solid apps and keep 100m+ users happy](https://reader034.fdocuments.us/reader034/viewer/2022042513/53f4a1548d7f72c80e8b4ad2/html5/thumbnails/49.jpg)
@iordanis_g
Questions?
Hiring...