SlideShare a Scribd company logo
Device Fragmentation

Clean Code
Iordanis “Jordan” Giannakakis
@iordanis_g
#fragVsCode
Introduction
•
•
•
•

Iordanis “Jordan” Giannakakis
Android Team Lead – Shazam
@iordanis_g
#fragVsCode

@iordanis_g #fragVsCode
How Shazam works

@iordanis_g #fragVsCode
Bad vs. good code

@iordanis_g #fragVsCode
How is fragmentation related to
clean code?

@iordanis_g #fragVsCode
Is fragmentation really a problem?

android.support
@iordanis_g #fragVsCode
Is fragmentation really a problem?

@iordanis_g #fragVsCode
Is clean code really a concern?

@iordanis_g #fragVsCode
Is clean code really a concern?

A couple of months later...
@iordanis_g #fragVsCode
SharedPreferences.Editor

• commit() – slow
• apply() – fast

@iordanis_g #fragVsCode
API example – MainActivity
protected void onResume() {
super.onResume();
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
prefEditor.putBoolean("has_launched_before", true);
// Will only be available for versions after Froyo
if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
editor.apply();
} else {
editor.commit();
}
}

@iordanis_g #fragVsCode
Fixed it!

@iordanis_g #fragVsCode
What are the issues?
protected void onResume() {
super.onResume();
SharedPreferences sharedPreferences =
Glue
PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPreferences.edit();
Business
prefEditor.putBoolean("has_launched_before", true);

Logic

// Will only be available for versions after Froyo
if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
editor.apply();
} else {
editor.commit();
}

Glue

}

@iordanis_g #fragVsCode
How to unit test?

Good luck!

@iordanis_g #fragVsCode
Dependency Injection

@iordanis_g #fragVsCode
Dependency Injection Framework

@iordanis_g #fragVsCode
New MainActivity

@Override
public void onResume() {
super.onResume();

editor.putBoolean("has_launched_before", true);
preferencesSaver.save(editor);
}

@iordanis_g #fragVsCode
Before & After
protected void onResume() {
super.onResume();
SharedPreferences sharedPreferences =
PreferenceManager
.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor =
sharedPreferences.edit();
prefEditor.putBoolean(
"has_launched_before", true);
// Will only be available for versions
after Froyo
if(VERSION.SDK_INT >=
VERSION_CODES.GINGERBREAD) {
editor.apply();
} else {
editor.commit();
}
}

public void onResume() {
super.onResume();
editor.putBoolean(
"has_launched_before", true);
preferencesSaver.save(editor);
}

@iordanis_g #fragVsCode
New MainActivity – Constructors

// Constructor the system will call to instantiate this activity
public MainActivity() {
this(sharedPreferencesEditor(), preferencesSaver());
}

// Constructor that can be used in production and test code
public MainActivity(Editor editor, PreferencesSaver preferencesSaver) {
this.editor = editor;
this.preferencesSaver = preferencesSaver;
}

@iordanis_g #fragVsCode
Module classes
public class SharedPreferencesEditorModule {
public static SharedPreferences.Editor sharedPreferencesEditor() {
Context context = getApplication().getApplicationContext();
SharedPreferences preferences = getDefaultSharedPreferences(context);
Editor editor = preferences.edit();
return editor;
}
}
public class PreferencesSaverModule {
public static PreferencesSaver preferencesSaver() {
if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {

return new ApplyPreferencesSaver();
}
return new CommitPreferencesSaver();
}
}

@iordanis_g #fragVsCode
Application
public class MyCoolApplication extends Application {
private static MyCoolApplication application;
@Override
public void onCreate() {
application = this;
}
public static MyCoolApplication getApplication() {
return application;
}

}

@iordanis_g #fragVsCode
How to unit test?
@Mock Editor editor;
@Mock PreferencesSaver saver;
@Test
public void canSaveLaunchFlag() {
mockery.checking(new Expectations() {{
atLeast(1).of(editor).putBoolean("has_launched_before", true);
oneOf(saver).save(editor);
}});
MainActivity activity = new MainActivity(editor, saver);
activity.onResume();
}

@iordanis_g #fragVsCode
Capabilities example – Google+

@iordanis_g #fragVsCode
Capabilities example
public void onCreate(Bundle savedInstanceState) {
// Set layout
View googlePlus = findViewById(R.id.google_plus);
try {
getPackageManager().getApplicationInfo("com.android.vending", 0);
googlePlus.setVisibility(VISIBLE);
} catch (PackageManager.NameNotFoundException e) {
googlePlus.setVisibility(GONE);
}
}

@iordanis_g #fragVsCode
MVP pattern

@iordanis_g #fragVsCode
The Model
public class GooglePlayAvailability {
private PackageManager packageManager;
public GooglePlayAvailability(PackageManager packageManager) {
this.packageManager = packageManager;
}
public boolean googlePlayIsAvailable() {
try {
packageManager.getApplicationInfo("com.android.vending", 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}
}

@iordanis_g #fragVsCode
The View

public interface GooglePlusView {
public void showGooglePlus();

public void hideGooglePlus();
}

@iordanis_g #fragVsCode
Activity as View
public class MainActivity extends Activity implements GooglePlusView {
public void onCreate(Bundle savedInstanceState) {
//Set layout...
googlePlus = findViewById(R.id.google_plus);
//Injected googlePlusPresenter
googlePlusPresenter.setView(this);
googlePlusPresenter.present();

}
public void showGooglePlus() {
googlePlus.setVisibility(VISIBLE);
}
public void hideGooglePlus() {
googlePlus.setVisibility(GONE);
}
}

@iordanis_g #fragVsCode
The Presenter
public class GooglePlusPresenter {
private GooglePlayAvailability googlePlayAvailability;
private GooglePlusView googlePlusView;
public GooglePlusPresenter(GooglePlayAvailability availability) {
googlePlayAvailability = availability;
}

public void present() {
if (googlePlayAvailability.googlePlayIsAvailable()) {
googlePlusView.showGooglePlus();
} else {
googlePlusView.hideGooglePlus();
}
}
}

@iordanis_g #fragVsCode
How to unit test?
@Mock GooglePlayAvailability googlePlayAvailability;
@Mock GooglePlusView googlePlus;
private GooglePlusPresenter presenter;
@Test
public void hidesGooglePlusIfNotAvailable() {
mockery.checking(new Expectations() {{
allowing(googlePlayAvailability).googlePlayIsAvailable();
will(returnValue(false));
oneOf(googlePlus).hideGooglePlus();
}});

presenter.present();
}

@iordanis_g #fragVsCode
Device size diversity

@iordanis_g #fragVsCode
Device size diversity

@iordanis_g #fragVsCode
How about Acceptance Tests?

@iordanis_g #fragVsCode
How about Acceptance Tests?

public class ShazamTest extends
ActivityInstrumentationTestCase2<ActivityUnderTest> {
private static final int TIMEOUT = 5000;
private Solo solo;
protected void setUp() {
solo = new Solo(getInstrumentation());
}
}

@iordanis_g #fragVsCode
How about Acceptance Tests?
public void testCanShazamOnPhone() {
// Action
// User hits the big Shazam button
View shazamButton = solo.getView(R.id.big_button);
solo.clickOnView(shazamButton);
// Assertions
// Track details are showing on full screen
assertThat(solo.waitForCondition(titleShowsOnFullScreen(),
TIMEOUT), is(true));
}

@iordanis_g #fragVsCode
How about Acceptance Tests?
public void testShazamingOnTablet() {
// Action
// Hit small Shazam button and wait for animation to finish
final View shazamButton = solo.getView(R.id.small_button);
solo.clickOnView(shazamButton);
waitForAnimationToFinish();
// Assertions
// Track details are showing on side-panel
assertThat(solo.waitForCondition(titleShowsOnSidePanel(),
TIMEOUT), is(true));

}

@iordanis_g #fragVsCode
Fixed it!

@iordanis_g #fragVsCode
Test frameworks

GWEN

https://github.com/shazam/gwen

@iordanis_g #fragVsCode
New Acceptance Test
protected void setUp() {
solo = new Solo(getInstrumentation());
user = new User(solo);
}
public void testCanShowTrackAfterShazaming() {
when(user).shazams();
then(user).seesDetailsForTrack();
}

@iordanis_g #fragVsCode
User class
public class User implements Actor, Asserter {
private final Solo solo;
public void shazams() {
Action<Solo, Void> action;
if (isTablet()) {
action = new ShazamTabletButtonAction();
} else {
action = new ShazamPhoneButtonAction();
}
action.actOn(solo);
}
public void seesDetailsForTrack() {
Assertion<Solo> assertion;
if (isTablet()) {
assertion = new TabletDetailsAssertion();
} else {
assertion = new PhoneDetailsAssertion();
}
assertion.assertWith(solo);
}
}

@iordanis_g #fragVsCode
Actions
public class ShazamPhoneButtonAction implements Action<Solo, Void> {
public void actOn(Solo solo) {
View bigButton = solo.getView(R.id.big_button);
solo.clickOnView(bigButton);
}
}
public class ShazamTabletButtonAction implements Action<Solo, Void> {
public void actOn(Solo solo) {
View smallButton = solo.getView(R.id.small_button);
solo.clickOnView(smallButton);
}
}

@iordanis_g #fragVsCode
Assertions
public class PhoneDetailsAssertion implements Assertion<Solo>{
public void assertWith(Solo solo) {
assertThat(solo.waitForCondition(titleShowsOnFullScreen(),
TIMEOUT), is(true));
}
}

public class TabletDetailsAssertion implements Assertion<Solo> {
public void assertWith(Solo solo) {
waitForAnimationToFinish();
assertThat(solo.waitForCondition(titleShowsOnSidePanel(),
TIMEOUT), is(true));
}
}

@iordanis_g #fragVsCode
Fixed it!

@iordanis_g #fragVsCode
Hiring...

Questions?
@iordanis_g
#fragVsCode
github.com/iordanis/androidCleanCode

More Related Content

PDF
Android Test Automation Workshop
PPTX
ProTips DroidCon Paris 2013
PDF
Robotium Tutorial
PDF
Automated Historical Performance Analysis with kmemtracer
PDF
Utilizando Espresso e UIAutomator no Teste de Apps Android
PDF
Android testing part i
PDF
Dagger for android
PPTX
Testing android apps with espresso
Android Test Automation Workshop
ProTips DroidCon Paris 2013
Robotium Tutorial
Automated Historical Performance Analysis with kmemtracer
Utilizando Espresso e UIAutomator no Teste de Apps Android
Android testing part i
Dagger for android
Testing android apps with espresso

What's hot (7)

PDF
Testing on Android
PDF
Testable Android Apps using data binding and MVVM
PDF
Android UI Testing with Espresso
PPTX
Android testing
PPTX
Clean Test
PDF
A guide to Android automated testing
PPTX
Android testing
Testing on Android
Testable Android Apps using data binding and MVVM
Android UI Testing with Espresso
Android testing
Clean Test
A guide to Android automated testing
Android testing
Ad

Similar to Device fragmentation vs clean code (20)

PDF
Keeping 100m+ users happy: How we test Shazam on Android
PDF
How to build rock solid apps and keep 100m+ users happy
PPT
Android the Agile way
PDF
Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...
PDF
How to code to code less
PPT
Ruby conf2012
PPTX
Code to DI For - Dependency Injection for Modern Applications
KEY
Design Patterns for Tablets and Smartphones
PDF
From Idea to App (or “How we roll at Small Town Heroes”)
DOCX
STYLISH FLOOR
PDF
Hacking the Codename One Source Code - Part IV - Transcript.pdf
PDF
Mini curso Android
PPTX
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
PDF
Building a Native Camera Access Library - Part II - Transcript.pdf
PPTX
Building native Android applications with Mirah and Pindah
PDF
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
PDF
Alexey Buzdin "Maslow's Pyramid of Android Testing"
PDF
Customizing Xamarin.Forms UI
PDF
Refactoring Wunderlist. UA Mobile 2016.
PPTX
Встреча Google Post IO ( Владимир Иванов, Катерина Заворотченко и Сергей Комлач)
Keeping 100m+ users happy: How we test Shazam on Android
How to build rock solid apps and keep 100m+ users happy
Android the Agile way
Android Wear 2.0 - New Level of Freedom for Your Action - GDG CEE Leads Summi...
How to code to code less
Ruby conf2012
Code to DI For - Dependency Injection for Modern Applications
Design Patterns for Tablets and Smartphones
From Idea to App (or “How we roll at Small Town Heroes”)
STYLISH FLOOR
Hacking the Codename One Source Code - Part IV - Transcript.pdf
Mini curso Android
Architecture components, Константин Марс, TeamLead, Senior Developer, DataArt
Building a Native Camera Access Library - Part II - Transcript.pdf
Building native Android applications with Mirah and Pindah
GDG Mediterranean Dev Fest Code lab #DevFestMed15 da android ad android wear ...
Alexey Buzdin "Maslow's Pyramid of Android Testing"
Customizing Xamarin.Forms UI
Refactoring Wunderlist. UA Mobile 2016.
Встреча Google Post IO ( Владимир Иванов, Катерина Заворотченко и Сергей Комлач)
Ad

Recently uploaded (20)

PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Hybrid model detection and classification of lung cancer
PDF
Univ-Connecticut-ChatGPT-Presentaion.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Web App vs Mobile App What Should You Build First.pdf
PDF
project resource management chapter-09.pdf
PDF
Hindi spoken digit analysis for native and non-native speakers
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Heart disease approach using modified random forest and particle swarm optimi...
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
August Patch Tuesday
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
PDF
1 - Historical Antecedents, Social Consideration.pdf
PDF
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
PPTX
1. Introduction to Computer Programming.pptx
PDF
Mushroom cultivation and it's methods.pdf
PDF
A novel scalable deep ensemble learning framework for big data classification...
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Hybrid model detection and classification of lung cancer
Univ-Connecticut-ChatGPT-Presentaion.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Programs and apps: productivity, graphics, security and other tools
Web App vs Mobile App What Should You Build First.pdf
project resource management chapter-09.pdf
Hindi spoken digit analysis for native and non-native speakers
MIND Revenue Release Quarter 2 2025 Press Release
Heart disease approach using modified random forest and particle swarm optimi...
A comparative analysis of optical character recognition models for extracting...
August Patch Tuesday
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
TechTalks-8-2019-Service-Management-ITIL-Refresh-ITIL-4-Framework-Supports-Ou...
1 - Historical Antecedents, Social Consideration.pdf
From MVP to Full-Scale Product A Startup’s Software Journey.pdf
1. Introduction to Computer Programming.pptx
Mushroom cultivation and it's methods.pdf
A novel scalable deep ensemble learning framework for big data classification...

Device fragmentation vs clean code

  • 1. Device Fragmentation Clean Code Iordanis “Jordan” Giannakakis @iordanis_g #fragVsCode
  • 2. Introduction • • • • Iordanis “Jordan” Giannakakis Android Team Lead – Shazam @iordanis_g #fragVsCode @iordanis_g #fragVsCode
  • 4. Bad vs. good code @iordanis_g #fragVsCode
  • 5. How is fragmentation related to clean code? @iordanis_g #fragVsCode
  • 6. Is fragmentation really a problem? android.support @iordanis_g #fragVsCode
  • 7. Is fragmentation really a problem? @iordanis_g #fragVsCode
  • 8. Is clean code really a concern? @iordanis_g #fragVsCode
  • 9. Is clean code really a concern? A couple of months later... @iordanis_g #fragVsCode
  • 10. SharedPreferences.Editor • commit() – slow • apply() – fast @iordanis_g #fragVsCode
  • 11. API example – MainActivity protected void onResume() { super.onResume(); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor editor = sharedPreferences.edit(); prefEditor.putBoolean("has_launched_before", true); // Will only be available for versions after Froyo if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { editor.apply(); } else { editor.commit(); } } @iordanis_g #fragVsCode
  • 13. What are the issues? protected void onResume() { super.onResume(); SharedPreferences sharedPreferences = Glue PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor editor = sharedPreferences.edit(); Business prefEditor.putBoolean("has_launched_before", true); Logic // Will only be available for versions after Froyo if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { editor.apply(); } else { editor.commit(); } Glue } @iordanis_g #fragVsCode
  • 14. How to unit test? Good luck! @iordanis_g #fragVsCode
  • 17. New MainActivity @Override public void onResume() { super.onResume(); editor.putBoolean("has_launched_before", true); preferencesSaver.save(editor); } @iordanis_g #fragVsCode
  • 18. Before & After protected void onResume() { super.onResume(); SharedPreferences sharedPreferences = PreferenceManager .getDefaultSharedPreferences(this); SharedPreferences.Editor editor = sharedPreferences.edit(); prefEditor.putBoolean( "has_launched_before", true); // Will only be available for versions after Froyo if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { editor.apply(); } else { editor.commit(); } } public void onResume() { super.onResume(); editor.putBoolean( "has_launched_before", true); preferencesSaver.save(editor); } @iordanis_g #fragVsCode
  • 19. New MainActivity – Constructors // Constructor the system will call to instantiate this activity public MainActivity() { this(sharedPreferencesEditor(), preferencesSaver()); } // Constructor that can be used in production and test code public MainActivity(Editor editor, PreferencesSaver preferencesSaver) { this.editor = editor; this.preferencesSaver = preferencesSaver; } @iordanis_g #fragVsCode
  • 20. Module classes public class SharedPreferencesEditorModule { public static SharedPreferences.Editor sharedPreferencesEditor() { Context context = getApplication().getApplicationContext(); SharedPreferences preferences = getDefaultSharedPreferences(context); Editor editor = preferences.edit(); return editor; } } public class PreferencesSaverModule { public static PreferencesSaver preferencesSaver() { if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { return new ApplyPreferencesSaver(); } return new CommitPreferencesSaver(); } } @iordanis_g #fragVsCode
  • 21. Application public class MyCoolApplication extends Application { private static MyCoolApplication application; @Override public void onCreate() { application = this; } public static MyCoolApplication getApplication() { return application; } } @iordanis_g #fragVsCode
  • 22. How to unit test? @Mock Editor editor; @Mock PreferencesSaver saver; @Test public void canSaveLaunchFlag() { mockery.checking(new Expectations() {{ atLeast(1).of(editor).putBoolean("has_launched_before", true); oneOf(saver).save(editor); }}); MainActivity activity = new MainActivity(editor, saver); activity.onResume(); } @iordanis_g #fragVsCode
  • 23. Capabilities example – Google+ @iordanis_g #fragVsCode
  • 24. Capabilities example public void onCreate(Bundle savedInstanceState) { // Set layout View googlePlus = findViewById(R.id.google_plus); try { getPackageManager().getApplicationInfo("com.android.vending", 0); googlePlus.setVisibility(VISIBLE); } catch (PackageManager.NameNotFoundException e) { googlePlus.setVisibility(GONE); } } @iordanis_g #fragVsCode
  • 26. The Model public class GooglePlayAvailability { private PackageManager packageManager; public GooglePlayAvailability(PackageManager packageManager) { this.packageManager = packageManager; } public boolean googlePlayIsAvailable() { try { packageManager.getApplicationInfo("com.android.vending", 0); return true; } catch (PackageManager.NameNotFoundException e) { return false; } } } @iordanis_g #fragVsCode
  • 27. The View public interface GooglePlusView { public void showGooglePlus(); public void hideGooglePlus(); } @iordanis_g #fragVsCode
  • 28. Activity as View public class MainActivity extends Activity implements GooglePlusView { public void onCreate(Bundle savedInstanceState) { //Set layout... googlePlus = findViewById(R.id.google_plus); //Injected googlePlusPresenter googlePlusPresenter.setView(this); googlePlusPresenter.present(); } public void showGooglePlus() { googlePlus.setVisibility(VISIBLE); } public void hideGooglePlus() { googlePlus.setVisibility(GONE); } } @iordanis_g #fragVsCode
  • 29. The Presenter public class GooglePlusPresenter { private GooglePlayAvailability googlePlayAvailability; private GooglePlusView googlePlusView; public GooglePlusPresenter(GooglePlayAvailability availability) { googlePlayAvailability = availability; } public void present() { if (googlePlayAvailability.googlePlayIsAvailable()) { googlePlusView.showGooglePlus(); } else { googlePlusView.hideGooglePlus(); } } } @iordanis_g #fragVsCode
  • 30. How to unit test? @Mock GooglePlayAvailability googlePlayAvailability; @Mock GooglePlusView googlePlus; private GooglePlusPresenter presenter; @Test public void hidesGooglePlusIfNotAvailable() { mockery.checking(new Expectations() {{ allowing(googlePlayAvailability).googlePlayIsAvailable(); will(returnValue(false)); oneOf(googlePlus).hideGooglePlus(); }}); presenter.present(); } @iordanis_g #fragVsCode
  • 33. How about Acceptance Tests? @iordanis_g #fragVsCode
  • 34. How about Acceptance Tests? public class ShazamTest extends ActivityInstrumentationTestCase2<ActivityUnderTest> { private static final int TIMEOUT = 5000; private Solo solo; protected void setUp() { solo = new Solo(getInstrumentation()); } } @iordanis_g #fragVsCode
  • 35. How about Acceptance Tests? public void testCanShazamOnPhone() { // Action // User hits the big Shazam button View shazamButton = solo.getView(R.id.big_button); solo.clickOnView(shazamButton); // Assertions // Track details are showing on full screen assertThat(solo.waitForCondition(titleShowsOnFullScreen(), TIMEOUT), is(true)); } @iordanis_g #fragVsCode
  • 36. How about Acceptance Tests? public void testShazamingOnTablet() { // Action // Hit small Shazam button and wait for animation to finish final View shazamButton = solo.getView(R.id.small_button); solo.clickOnView(shazamButton); waitForAnimationToFinish(); // Assertions // Track details are showing on side-panel assertThat(solo.waitForCondition(titleShowsOnSidePanel(), TIMEOUT), is(true)); } @iordanis_g #fragVsCode
  • 39. New Acceptance Test protected void setUp() { solo = new Solo(getInstrumentation()); user = new User(solo); } public void testCanShowTrackAfterShazaming() { when(user).shazams(); then(user).seesDetailsForTrack(); } @iordanis_g #fragVsCode
  • 40. User class public class User implements Actor, Asserter { private final Solo solo; public void shazams() { Action<Solo, Void> action; if (isTablet()) { action = new ShazamTabletButtonAction(); } else { action = new ShazamPhoneButtonAction(); } action.actOn(solo); } public void seesDetailsForTrack() { Assertion<Solo> assertion; if (isTablet()) { assertion = new TabletDetailsAssertion(); } else { assertion = new PhoneDetailsAssertion(); } assertion.assertWith(solo); } } @iordanis_g #fragVsCode
  • 41. Actions public class ShazamPhoneButtonAction implements Action<Solo, Void> { public void actOn(Solo solo) { View bigButton = solo.getView(R.id.big_button); solo.clickOnView(bigButton); } } public class ShazamTabletButtonAction implements Action<Solo, Void> { public void actOn(Solo solo) { View smallButton = solo.getView(R.id.small_button); solo.clickOnView(smallButton); } } @iordanis_g #fragVsCode
  • 42. Assertions public class PhoneDetailsAssertion implements Assertion<Solo>{ public void assertWith(Solo solo) { assertThat(solo.waitForCondition(titleShowsOnFullScreen(), TIMEOUT), is(true)); } } public class TabletDetailsAssertion implements Assertion<Solo> { public void assertWith(Solo solo) { waitForAnimationToFinish(); assertThat(solo.waitForCondition(titleShowsOnSidePanel(), TIMEOUT), is(true)); } } @iordanis_g #fragVsCode