SlideShare a Scribd company logo
Testing in Android
Mission impossible?
http://joaoptrindade.com
Why automated tests
We all write crappy code and then refactor
We will break the app app
Humans suck at repetitive tasks
We won’t be able to always test everything
Users will be our ultimate testers
Ratings: ...that one star on the store....
What to test
Unit 2
OS interaction 5
Integration (network) 2
Acceptance 1
Performance 4
What to test
Unit 3
OS interaction 5
Integration (network) 2
Acceptance 1
Performance 4
How many of you do some type of automated tests on your android app?
Quick survey
Why is it so painful on Android
Speed
The way Android SDK is structured
You need to test on the device
Fragmentation
Compromises
Move tests to the JVM
Only test the bacon on Android
Monkeys are great testers
Help the QA guy! (probably your boss)
Move logic to the JVM
dependencies {
...
compile project (':domain')
compile project (':network')
}
.
├── build.gradle
├── app
│ ├── build.gradle
│ └── src
├── domain
│ ├── build.gradle
│ └── src
└── network
├── build.gradle
├── remote.iml
└── src
apply plugin: 'java'
apply plugin: 'java'
dependencies {
compile "com.squareup. retrofit:..."
compile "com.squareup. okhttp:..."
compile project( ':domain')
}
Move logic to the JVM
Business logic in a jar
Include your POJOS here
Put everything that is not Android specific
Implement use cases via interactors
class UseCase implements Interactor {
UseCase(Rulebook rules ) {
this.rules = rules;
}
public String getTitle(String userName, int age) {
if(rules.is_old_enough (age))
return "Mr " + username
}
}
public class User {
private final int userId;
public User(int userId) {
this.userId = userId;
}
public int getUserId() {
return userId;
}
@Override public String toString() {
...
return stringBuilder .toString();
}
}
Move logic to the JVM
Now you can unit test like you are used to.
import org.junit.Test;
public class MyTests {
@Test
public void multiplicationOfZeroIntegersShouldReturnZero () {
MyClass tester = new MyClass();
assertEquals ("10 x 0 must be 0" , 0, tester.multiply(10, 0));
}
}
Move logic to the JVM (network)
public interface RestInterface {
@POST("/user/create/" )
public void userRegister (
@Body UserRest user ,
Callback <UserRest> callback);
Use retrofit to do the network communication
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint( https://api.github.com/")
. setClient(new OkHttpClient())
.build() ;
Move logic to the JVM (network)
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint( https://api.github.com/")
. setClient(new OkHttpClient())
.build() ;
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint( https://api.github.com/")
. setClient(new MockClient())
.build() ;
public interface RestInterface {
@POST("/user/create/" )
public void userRegister (
@Body UserRest user ,
Callback <UserRest> callback);
Use retrofit to do the network communication
Move logic to the JVM (network)
public class NewUserMockClient implements Client{
static String VALID_RESPONSE = "{ status: 'OK', id: %s }"
String json;
int code;
NewUserMockClient(String json, int code) {
this.json = json;
this.code = code;
}
static NewUserMockClient getOkMock(int id, String email) {
String response = String.format(VALID_RESP, userId)
return new NewUserMockClient(response, HTTP_OK_STATUS);
}
@Override
public Response execute(Request request)throws IOException {
return
new Response(request.url, code, ...,
new TypedByteArray(MIME_TYPE, json.getBytes()));
}
}
Move logic to the JVM (network)
@Before
public void setUp() {
String email = getUUID() + "@somehost.com" ;
String pass = "pass";
user = new User(email, pass);
}
@Test
public void registerUserWithFamilyName() {
client = NewUserMockClient .getOkMock(userId, email);
RestAdapter restAdapter = new RestAdapter .Builder()
.setEndpoint (https://api.github.com/")
.setClient(newUserMockClient )
.build();
rest.userRegister (user);
assertThat (observable, something_you_expect );
}
Move logic to the JVM (network)
@Before
public void setUp() {
String email = getUUID() + "@somehost.com" ;
String pass = "pass";
user = new User(email, pass);
}
@Test
public void registerUserWithFamilyName() {
client = NewUserMockClient .getOkMock(userId, email);
RestAdapter restAdapter = new RestAdapter .Builder()
.setEndpoint (https://api.github.com/")
.setClient(newUserMockClient )
.build();
rest.userRegister (user);
assertThat (observable, something_you_expect );
} http://riggaroo.co.za/mocking-api-responses-using-a-retrofit-client-in-android/
Focus on the bacon
Espresso @RunWith(AndroidJUnit4.class)
public class MainActivityEspressoTest {
@Test
public void ensureTextChangesWork () {
// Type text and then press the button.
onView (withId(R.id.inputField))
.perform(typeText("HELLO"), closeSoftKeyboard ());
onView (withId(R.id.changeText)).perform(click());
// Check that the text was changed.
onView (withId(R.id.inputField))
. check(matches(withText("Changed")));
}
}
Monkeys are great testers
$ adb shell monkey -p your.package.name -v 500
Help the QA guy
Help the QA guy
https://github.com/orhanobut/bee
Help the QA guy
https://github.com/orhanobut/bee
@Override protected void onCreate(Bundle savedInstanceState) {
...
Bee.init(this)
.setBeeSize(100) //optional bee button size
.setBeePosition (Gravity.CENTER) //optional bee button position
.setBeeMargin (0, 0, 0, 400) //optional margin for the bee
button
.inject(SampleBeeConfig .class); //required
}
Help the QA guy
https://github.com/orhanobut/bee
@Title("Select user")
@Spinner({"John Doe", "Foo Bar"})
public void onUserSelected(String selectedValue) {
doSomeInternalLogic(selectedValue);
}
Help the QA guy
https://github.com/orhanobut/bee
But this is
not
automated
What to test
Unit 2 JVM
OS interaction 5 (Monkey...kind of)
Integration (network) 2 Retrofit + MockClient
Acceptance 1 Bee, Espresso
Performance 4
Debug only:
Android settings,
various other tools
That’s all folks

More Related Content

PPTX
Legacy Code Kata v3.0
PPTX
Legacy Dependency Kata v2.0
PDF
Spock Framework
PDF
We Are All Testers Now: The Testing Pyramid and Front-End Development
PPTX
Unit testing patterns for concurrent code
PPTX
Building unit tests correctly
PDF
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
PPTX
Full Stack Unit Testing
Legacy Code Kata v3.0
Legacy Dependency Kata v2.0
Spock Framework
We Are All Testers Now: The Testing Pyramid and Front-End Development
Unit testing patterns for concurrent code
Building unit tests correctly
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Full Stack Unit Testing

What's hot (20)

PPTX
Java concurrency in practice
ODP
Testing RESTful Webservices using the REST-assured framework
PDF
Mobile Day - React Native
PDF
PPTX
Reactive Java (33rd Degree)
PDF
Introduction to Retrofit and RxJava
PPTX
Open sourcing the store
PDF
Martin Anderson - threads v actors
PDF
Introduction+To+Java+Concurrency
PDF
Testing Android apps based on Dagger and RxJava
PDF
Java9 Beyond Modularity - Java 9 más allá de la modularidad
PDF
Concurrency Utilities in Java 8
PDF
Unit Testing Express Middleware
PDF
node.js practical guide to serverside javascript
PDF
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
PDF
Android architecture component - FbCircleDev Yogyakarta Indonesia
PDF
Painless JavaScript Testing with Jest
PDF
Unit Testing Express and Koa Middleware in ES2015
PDF
Reactive server with netty
ODP
To inject or not to inject: CDI is the question
Java concurrency in practice
Testing RESTful Webservices using the REST-assured framework
Mobile Day - React Native
Reactive Java (33rd Degree)
Introduction to Retrofit and RxJava
Open sourcing the store
Martin Anderson - threads v actors
Introduction+To+Java+Concurrency
Testing Android apps based on Dagger and RxJava
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Concurrency Utilities in Java 8
Unit Testing Express Middleware
node.js practical guide to serverside javascript
Cool Jvm Tools to Help you Test - Aylesbury Testers Version
Android architecture component - FbCircleDev Yogyakarta Indonesia
Painless JavaScript Testing with Jest
Unit Testing Express and Koa Middleware in ES2015
Reactive server with netty
To inject or not to inject: CDI is the question
Ad

Similar to Testing in android (20)

PDF
Testing Java Code Effectively
PDF
Guide to the jungle of testing frameworks
PDF
Infinum Android Talks #17 - Testing your Android applications by Ivan Kust
PDF
World-Class Testing Development Pipeline for Android
PPTX
The real beginner's guide to android testing
PDF
Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust
PDF
Android testing
PPTX
Mobile developer is Software developer
PDF
Make it test-driven with CDI!
PDF
Android Building, Testing and reversing
PDF
Cool JVM Tools to Help You Test
PDF
Agile mobile
PDF
Testing and Building Android
PDF
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
PPTX
Unit Testing Android Applications
PDF
Oh so you test? - A guide to testing on Android from Unit to Mutation
PPTX
Different Android Test Automation Frameworks - What Works You the Best?
PDF
Testing Android
PPTX
Robospock droidcon '14
PDF
Guide to the jungle of testing frameworks
Testing Java Code Effectively
Guide to the jungle of testing frameworks
Infinum Android Talks #17 - Testing your Android applications by Ivan Kust
World-Class Testing Development Pipeline for Android
The real beginner's guide to android testing
Android Meetup Slovenija #3 - Testing with Robolectric by Ivan Kust
Android testing
Mobile developer is Software developer
Make it test-driven with CDI!
Android Building, Testing and reversing
Cool JVM Tools to Help You Test
Agile mobile
Testing and Building Android
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit Testing Android Applications
Oh so you test? - A guide to testing on Android from Unit to Mutation
Different Android Test Automation Frameworks - What Works You the Best?
Testing Android
Robospock droidcon '14
Guide to the jungle of testing frameworks
Ad

Recently uploaded (6)

PDF
Lesson 13- HEREDITY _ pedSAWEREGFVCXZDSASEWFigree.pdf
DOC
Camb毕业证学历认证,格罗斯泰斯特主教大学毕业证仿冒文凭毕业证
DOC
证书学历UoA毕业证,澳大利亚中汇学院毕业证国外大学毕业证
PDF
heheheueueyeyeyegehehehhehshMedia-Literacy.pdf
PPTX
ASMS Telecommunication company Profile
PDF
6-UseCfgfhgfhgfhgfhgfhfhhaseActivity.pdf
Lesson 13- HEREDITY _ pedSAWEREGFVCXZDSASEWFigree.pdf
Camb毕业证学历认证,格罗斯泰斯特主教大学毕业证仿冒文凭毕业证
证书学历UoA毕业证,澳大利亚中汇学院毕业证国外大学毕业证
heheheueueyeyeyegehehehhehshMedia-Literacy.pdf
ASMS Telecommunication company Profile
6-UseCfgfhgfhgfhgfhgfhfhhaseActivity.pdf

Testing in android

  • 1. Testing in Android Mission impossible? http://joaoptrindade.com
  • 2. Why automated tests We all write crappy code and then refactor We will break the app app Humans suck at repetitive tasks We won’t be able to always test everything Users will be our ultimate testers Ratings: ...that one star on the store....
  • 3. What to test Unit 2 OS interaction 5 Integration (network) 2 Acceptance 1 Performance 4
  • 4. What to test Unit 3 OS interaction 5 Integration (network) 2 Acceptance 1 Performance 4
  • 5. How many of you do some type of automated tests on your android app? Quick survey
  • 6. Why is it so painful on Android Speed The way Android SDK is structured You need to test on the device Fragmentation
  • 7. Compromises Move tests to the JVM Only test the bacon on Android Monkeys are great testers Help the QA guy! (probably your boss)
  • 8. Move logic to the JVM dependencies { ... compile project (':domain') compile project (':network') } . ├── build.gradle ├── app │ ├── build.gradle │ └── src ├── domain │ ├── build.gradle │ └── src └── network ├── build.gradle ├── remote.iml └── src apply plugin: 'java' apply plugin: 'java' dependencies { compile "com.squareup. retrofit:..." compile "com.squareup. okhttp:..." compile project( ':domain') }
  • 9. Move logic to the JVM Business logic in a jar Include your POJOS here Put everything that is not Android specific Implement use cases via interactors class UseCase implements Interactor { UseCase(Rulebook rules ) { this.rules = rules; } public String getTitle(String userName, int age) { if(rules.is_old_enough (age)) return "Mr " + username } } public class User { private final int userId; public User(int userId) { this.userId = userId; } public int getUserId() { return userId; } @Override public String toString() { ... return stringBuilder .toString(); } }
  • 10. Move logic to the JVM Now you can unit test like you are used to. import org.junit.Test; public class MyTests { @Test public void multiplicationOfZeroIntegersShouldReturnZero () { MyClass tester = new MyClass(); assertEquals ("10 x 0 must be 0" , 0, tester.multiply(10, 0)); } }
  • 11. Move logic to the JVM (network) public interface RestInterface { @POST("/user/create/" ) public void userRegister ( @Body UserRest user , Callback <UserRest> callback); Use retrofit to do the network communication RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint( https://api.github.com/") . setClient(new OkHttpClient()) .build() ;
  • 12. Move logic to the JVM (network) RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint( https://api.github.com/") . setClient(new OkHttpClient()) .build() ; RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint( https://api.github.com/") . setClient(new MockClient()) .build() ; public interface RestInterface { @POST("/user/create/" ) public void userRegister ( @Body UserRest user , Callback <UserRest> callback); Use retrofit to do the network communication
  • 13. Move logic to the JVM (network) public class NewUserMockClient implements Client{ static String VALID_RESPONSE = "{ status: 'OK', id: %s }" String json; int code; NewUserMockClient(String json, int code) { this.json = json; this.code = code; } static NewUserMockClient getOkMock(int id, String email) { String response = String.format(VALID_RESP, userId) return new NewUserMockClient(response, HTTP_OK_STATUS); } @Override public Response execute(Request request)throws IOException { return new Response(request.url, code, ..., new TypedByteArray(MIME_TYPE, json.getBytes())); } }
  • 14. Move logic to the JVM (network) @Before public void setUp() { String email = getUUID() + "@somehost.com" ; String pass = "pass"; user = new User(email, pass); } @Test public void registerUserWithFamilyName() { client = NewUserMockClient .getOkMock(userId, email); RestAdapter restAdapter = new RestAdapter .Builder() .setEndpoint (https://api.github.com/") .setClient(newUserMockClient ) .build(); rest.userRegister (user); assertThat (observable, something_you_expect ); }
  • 15. Move logic to the JVM (network) @Before public void setUp() { String email = getUUID() + "@somehost.com" ; String pass = "pass"; user = new User(email, pass); } @Test public void registerUserWithFamilyName() { client = NewUserMockClient .getOkMock(userId, email); RestAdapter restAdapter = new RestAdapter .Builder() .setEndpoint (https://api.github.com/") .setClient(newUserMockClient ) .build(); rest.userRegister (user); assertThat (observable, something_you_expect ); } http://riggaroo.co.za/mocking-api-responses-using-a-retrofit-client-in-android/
  • 16. Focus on the bacon Espresso @RunWith(AndroidJUnit4.class) public class MainActivityEspressoTest { @Test public void ensureTextChangesWork () { // Type text and then press the button. onView (withId(R.id.inputField)) .perform(typeText("HELLO"), closeSoftKeyboard ()); onView (withId(R.id.changeText)).perform(click()); // Check that the text was changed. onView (withId(R.id.inputField)) . check(matches(withText("Changed"))); } }
  • 17. Monkeys are great testers $ adb shell monkey -p your.package.name -v 500
  • 18. Help the QA guy
  • 19. Help the QA guy https://github.com/orhanobut/bee
  • 20. Help the QA guy https://github.com/orhanobut/bee @Override protected void onCreate(Bundle savedInstanceState) { ... Bee.init(this) .setBeeSize(100) //optional bee button size .setBeePosition (Gravity.CENTER) //optional bee button position .setBeeMargin (0, 0, 0, 400) //optional margin for the bee button .inject(SampleBeeConfig .class); //required }
  • 21. Help the QA guy https://github.com/orhanobut/bee @Title("Select user") @Spinner({"John Doe", "Foo Bar"}) public void onUserSelected(String selectedValue) { doSomeInternalLogic(selectedValue); }
  • 22. Help the QA guy https://github.com/orhanobut/bee But this is not automated
  • 23. What to test Unit 2 JVM OS interaction 5 (Monkey...kind of) Integration (network) 2 Retrofit + MockClient Acceptance 1 Bee, Espresso Performance 4 Debug only: Android settings, various other tools