SlideShare a Scribd company logo
Android Testing
Evan Lin
at
evan.lin@getloopd.com
Tools
• Mock -> Mockito
• http://mockito.org/
• UI Testing -> Espresso
• https://developer.android.com/training/testing/ui-testing/espresso-testing.html
• Dependency Injection -> Dagger2
• http://google.github.io/dagger/
Mockito
dependencies {

...


// Mockito

debugCompile 'org.mockito:mockito-core:1.10.19'

debugCompile 'com.google.dexmaker:dexmaker:1.2'

debugCompile ‘com.google.dexmaker:dexmaker-mockito:1.2'


}
Espresso
android {



defaultConfig {


...


// Espresso2

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

}

}


dependencies {


...


// Espresso2

androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'

androidTestCompile ‘com.android.support.test:runner:0.3'


}
Dagger2
// dagger2
apply plugin: 'com.neenbedankt.android-apt'



buildscript {

repositories {

jcenter()

}

dependencies {

// dagger2

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'

}

}



dependencies {


...


// dagger2

compile 'junit:junit:4.12'

compile 'com.google.dagger:dagger:2.0'

apt 'com.google.dagger:dagger-compiler:2.0'

provided 'org.glassfish:javax.annotation:10.0-b28'

}

Start
public class MainActivity extends Activity {





@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}

EditText mEmailEditText;

EditText mPasswordEditText;

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);



public void onEnterButtonClick() {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

if (checkEmailAndPassword(email, password))

goToSecondPage();

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);

}



public void onEnterButtonClick() {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

if (checkEmailAndPassword(email, password))

goToSecondPage();

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

if (checkEmailAndPassword(email, password))

goToSecondPage();

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

if (checkEmailAndPassword(email, password))

goToSecondPage();

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

if (checkEmailAndPassword(email, password))

goToSecondPage();

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}

}
Keep Signin
public class UserService {



...



public boolean isLogin() {

return loadLoginStatus();

}



public boolean login(String email, String password) {

if (checkEmailAndPassword(email, password)) {

saveLoginStatus(true);

return true;

} else {

return false;

}

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



...

}
public class UserService {



...



public boolean isLogin() {

return loadLoginStatus();

}



public boolean login(String email, String password) {

if (checkEmailAndPassword(email, password)) {

saveLoginStatus(true);

return true;

} else {

return false;

}

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



...

}
public class UserService {



...



public boolean isLogin() {

return loadLoginStatus();

}



public boolean login(String email, String password) {

if (checkEmailAndPassword(email, password)) {

saveLoginStatus(true);

return true;

} else {

return false;

}

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



...

}
public class UserService {



private PasswordValidator mPasswordValidator;

...

public boolean isLogin() {

return loadLoginStatus();

}



public boolean login(String email, String password) {

if (mPasswordValidator.checkEmailAndPassword(email, password)) {

saveLoginStatus(true);

return true;

} else {

return false;

}

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



...
}
public class PasswordValidator {



public boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



}
public class UserService {



public static final String SHARED_PREF_NAME = "MY_SHARED_PREF";

private static final String SHARED_PREF_KEY_IS_LOGIN = “SHARED_PREF_KEY_IS_LOGIN";

private PasswordValidator mPasswordValidator;

private SharedPreferences mSharedPreferences;



public UserService(Context appContext, PasswordValidator validator) {
mPasswordValidator = validator;

mSharedPreferences = appContext.getSharedPreferences(SHARED_PREF_NAME, 0);

}



...



private boolean loadLoginStatus() {

return mSharedPreferences.getBoolean(SHARED_PREF_KEY_IS_LOGIN, false);

}



private void saveLoginStatus(boolean isLogin) {

SharedPreferences.Editor editor = mSharedPreferences.edit();

editor.putBoolean(SHARED_PREF_KEY_IS_LOGIN, isLogin);

editor.commit();

}

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

if (checkEmailAndPassword(email, password))

goToSecondPage();

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;

UserService mUserService;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);
mUserService = new UserService(getApplicationContext(), new PasswordValidator());

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

if (checkEmailAndPassword(email, password))

goToSecondPage();

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);
mUserService = new UserService(getApplicationContext(), new PasswordValidator());

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

if (checkEmailAndPassword(email, password))

goToSecondPage();

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);
mUserService = new UserService(getApplicationContext(), new PasswordValidator());

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

boolean isLoginSuccess = mUserService.login(email, password);

if (isLoginSuccess)

goToSecondPage();

}



private void goToSecondPage() {

Intent intent = new Intent(this, SecondActivity.class);

startActivity(intent);

}

}
public class MainActivity extends Activity {



EditText mEmailEditText;

EditText mPasswordEditText;

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);
mUserService = new UserService(getApplicationContext(), new PasswordValidator());

if (checkAutoLogin()) {

goToSecondPage();

finish();

}

}



private boolean checkAutoLogin() {

return mUserService.isLogin();

}


public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

boolean isLoginSuccess = mUserService.login(email, password);

if (isLoginSuccess)

goToSecondPage();

}
...
First Time
Open App
Second Time
Open App
Time to Test
Unit Test
1.
2.
3.
public class UserServiceTest extends TestCase {



}
public class UserServiceTest extends TestCase {



public void testLoginSuccess() throws Exception {

// arrange



// act



// assert



}



}
public class UserServiceTest extends TestCase {



public void testLoginSuccess() throws Exception {

// arrange



// act



// assert



}



}
test method prefix
public class UserServiceTest extends TestCase {



public void testLoginSuccess() throws Exception {

// arrange



// act



// assert



}



}
public class UserServiceTest extends AndroidTestCase {



public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = new PasswordValidator();

UserService userService = new UserService(getContext(), validator);



// act



// assert



}



}
public class UserServiceTest extends AndroidTestCase {



public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = new PasswordValidator();

UserService userService = new UserService(getContext(), validator);



// act

userService.login("admin", "admin");



// assert

assertTrue(userService.isLogin());
}



}
public class UserServiceTest extends AndroidTestCase {



public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = Mockito.mock(PasswordValidator.class);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("admin", "admin");



// assert

assertTrue(userService.isLogin());
}



}
public class UserServiceTest extends AndroidTestCase {



public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = Mockito.mock(PasswordValidator.class);
Mockito.when(validator.checkEmailAndPassword(Matchers.anyString(), 

Matchers.anyString())).thenReturn(true);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("admin", "admin");



// assert

assertTrue(userService.isLogin());
}



}
public class UserServiceTest extends AndroidTestCase {



public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = Mockito.mock(PasswordValidator.class);
Mockito.when(validator.checkEmailAndPassword(Matchers.anyString(), 

Matchers.anyString())).thenReturn(true);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("whateverEmail", "whateverPassword");



// assert

assertTrue(userService.isLogin());
}



}
public class UserServiceTest extends AndroidTestCase {



public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = Mockito.mock(PasswordValidator.class);
Mockito.when(validator.checkEmailAndPassword(Matchers.anyString(), 

Matchers.anyString())).thenReturn(true);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("whateverEmail", "whateverPassword");



// assert

assertTrue(userService.isLogin());
}



}
public class UserServiceTest extends AndroidTestCase {



public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = mock(PasswordValidator.class);
when(validator.checkEmailAndPassword(anyString(), 

anyString())).thenReturn(true);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("whateverEmail", "whateverPassword");



// assert

assertTrue(userService.isLogin());
}



public void testLoginFailure() throws Exception {

// arrange

PasswordValidator validator = mock(PasswordValidator.class);
when(validator.checkEmailAndPassword(anyString(), 

anyString())).thenReturn(false);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("whateverEmail", "whateverPassword");



// assert

assertFalse(userService.isLogin());
}



}
public class UserServiceTest extends AndroidTestCase {



public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = mock(PasswordValidator.class);
when(validator.checkEmailAndPassword(anyString(), 

anyString())).thenReturn(true);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("whateverEmail", "whateverPassword");



// assert

assertTrue(userService.isLogin());
}



public void testLoginFailure() throws Exception {

// arrange

PasswordValidator validator = mock(PasswordValidator.class);
when(validator.checkEmailAndPassword(anyString(), 

anyString())).thenReturn(false);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("whateverEmail", "whateverPassword");



// assert

assertFalse(userService.isLogin());
}



}
• passed when running separately(sometimes?)
• passed when running separately(sometimes?)
• but failed running the whole tests
• passed when running separately(sometimes?)
• but failed running the whole tests
• WHY?
public boolean isLogin() {

return loadLoginStatus();

}



public boolean login(String email, String password) {

if (mPasswordValidator.checkEmailAndPassword(email, password)) {

saveLoginStatus(true);

return true;

} else {

return false;

}

}



private boolean loadLoginStatus() {

return mSharedPreferences.getBoolean(SHARED_PREF_KEY_IS_LOGIN, false);

}



private void saveLoginStatus(boolean isLogin) {

SharedPreferences.Editor editor = mSharedPreferences.edit();

editor.putBoolean(SHARED_PREF_KEY_IS_LOGIN, isLogin);

editor.commit();

}
public class UserServiceTest extends AndroidTestCase {



public void setUp() throws Exception {

super.setUp();

clearSharedPref();

}



private void clearSharedPref() {

getContext().getSharedPreferences(UserService.SHARED_PREF_NAME, 0)

.edit().clear().commit();

}

...
Works!!
Async Tasks
public class PasswordValidator {



public boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



}
public class PasswordValidator {



public boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



}
public class UserApiService {



public void login(String email, String password, Callback callback) {

// todo: send login request to server...

}



public interface Callback {

void onSuccess();

void onFailure();

}

}
public class UserApiService {



public void login(String email, String password, Callback callback) {

// todo: send login request to server...

}



public interface Callback {

void onSuccess();

void onFailure();

}

}
public class UserApiService {



public void login(String email, String password, Callback callback) {

if (checkEmailAndPassword(email, password))

wait2SecondsAndRespondSuccess(callback);

}



private boolean checkEmailAndPassword(String email, String password) {

return email.equals("admin") && password.equals("admin");

}



private void wait2SecondsAndRespondSuccess(final Callback callback) {

new Handler().postDelayed(new Runnable() {

@Override

public void run() {

callback.onSuccess();

}

}, 2000);

}



public interface Callback {

void onSuccess();

void onFailure();

}

}

public class UserService {



private PasswordValidator mPasswordValidator;

...
public UserService(Context appContext, PasswordValidator validator) {
mPasswordValidator = validator;

...

}


public boolean login(String email, String password) {

if (mPasswordValidator.checkEmailAndPassword(email, password)) {

saveLoginStatus(true);

return true;

} else {

return false;

}

}


...
}
public class UserService {



private UserApiService mUserApiService;

...
public UserService(Context appContext, UserApiService userApiService) {
mUserApiService = userApiService;

...

}


public void login(String email, String password, final Callback callback) {

mUserApiService.login(email, password, new Callback() {

@Override

public void onSuccess() {

saveLoginStatus(true);

callback.onSuccess();

}



@Override

public void onFailure() {

callback.onFailure();

}

});

}

...
public class MainActivity extends Activity {


...



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);
mUserService = new UserService(getApplicationContext(), new PasswordValidator());

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

boolean isLoginSuccess = mUserService.login(email, password);

if (isLoginSuccess)

goToSecondPage();

}



...
public class MainActivity extends Activity {


...



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mEmailEditText = (EditText) findViewById(R.id.email);

mPasswordEditText = (EditText) findViewById(R.id.password);
mUserService = new UserService(getApplicationContext(), new UserApiService());

}



public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

mUserService.login(email, password, new UserApiService.Callback() {

@Override

public void onSuccess() {

goToSecondPage();

}



@Override

public void onFailure() {



}

});

}



...


Unit Test
public void testLoginSuccess() throws Exception {

// arrange

PasswordValidator validator = mock(PasswordValidator.class);
when(validator.checkEmailAndPassword(anyString(), 

anyString())).thenReturn(true);
UserService userService = new UserService(getContext(), validator);



// act

userService.login("whateverEmail", "whateverPassword");



// assert

assertTrue(userService.isLogin());
}

public void testLoginSuccess() throws Exception {

// arrange

UserApiService userApiService = mock(UserApiService.class);

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Callback callback = (Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(userApiService).login(anyString(), anyString(), any(Callback.class));

UserService userService = new UserService(getContext(), userApiService);



// act

userService.login("whateverEmail", "whateverPassword", mock(Callback.class));



// assert

assertTrue(userService.isLogin());

}
public void testLoginSuccess() throws Exception {

// arrange

UserApiService userApiService = mock(UserApiService.class);

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Callback callback = (Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(userApiService).login(anyString(), anyString(), any(Callback.class));

UserService userService = new UserService(getContext(), userApiService);



// act

userService.login("whateverEmail", "whateverPassword", mock(Callback.class));



// assert

assertTrue(userService.isLogin());

}
public void testLoginSuccess() throws Exception {

// arrange

UserApiService userApiService = mock(UserApiService.class);

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Callback callback = (Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(userApiService).login(anyString(), anyString(), any(Callback.class));

UserService userService = new UserService(getContext(), userApiService);



// act

userService.login("whateverEmail", "whateverPassword", mock(Callback.class));



// assert

assertTrue(userService.isLogin());

}
public void testLoginSuccess() throws Exception {

// arrange

UserApiService userApiService = mock(UserApiService.class);

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Callback callback = (Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(userApiService).login(anyString(), anyString(), any(Callback.class));

UserService userService = new UserService(getContext(), userApiService);



// act

userService.login("whateverEmail", "whateverPassword", mock(Callback.class));



// assert

assertTrue(userService.isLogin());

}
public void testLoginSuccess() throws Exception {

// arrange

UserApiService userApiService = mock(UserApiService.class);

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Callback callback = (Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(userApiService).login(anyString(), anyString(), any(Callback.class));

UserService userService = new UserService(getContext(), userApiService);



// act

userService.login("whateverEmail", "whateverPassword", mock(Callback.class));



// assert

assertTrue(userService.isLogin());

}
public void testLoginSuccess() throws Exception {

// arrange

UserApiService userApiService = mock(UserApiService.class);

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Callback callback = (Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(userApiService).login(anyString(), anyString(), any(Callback.class));

UserService userService = new UserService(getContext(), userApiService);



// act

userService.login("whateverEmail", "whateverPassword", mock(Callback.class));



// assert

assertTrue(userService.isLogin());

}
public void testLoginSuccess() throws Exception {

// arrange

UserApiService userApiService = mock(UserApiService.class);

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Callback callback = (Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(userApiService).login(anyString(), anyString(), any(Callback.class));

UserService userService = new UserService(getContext(), userApiService);



// act

userService.login("whateverEmail", "whateverPassword", mock(Callback.class));



// assert

assertTrue(userService.isLogin());

}



public void testLoginFailure() throws Exception {

// arrange

UserApiService userApiService = mock(UserApiService.class);

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

Callback callback = (Callback) invocation.getArguments()[2];

callback.onFailure();

return null;

}

}).when(userApiService).login(anyString(), anyString(), any(Callback.class));

UserService userService = new UserService(getContext(), userApiService);



// act

userService.login("whateverEmail", "whateverPassword", mock(Callback.class));



// assert

assertFalse(userService.isLogin());

}
Works!!
UI Test
1.
2.
3.
public class MainActivityTest extends TestCase {



}
public class MainActivityTest extends TestCase {



}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {



public MainActivityTest() {

super(MainActivity.class);

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {



public MainActivityTest() {

super(MainActivity.class);

}


public void setUp() throws Exception {

super.setUp();

clearSharedPref();

getActivity();

}



private void clearSharedPref() {

getInstrumentation().getTargetContext().getSharedPreferences
(UserService.SHARED_PREF_NAME, 0).edit().clear().commit();

}

}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLayout() throws Exception {

// arrange



// act



// assert

Espresso.onView(ViewMatchers.withId(R.id.email))

.check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

Espresso.onView(ViewMatchers.withId(R.id.password))

.check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

Espresso.onView(ViewMatchers.withId(R.id.enter_button))

.check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLayout() throws Exception {

// arrange



// act



// assert

Espresso.onView(ViewMatchers.withId(R.id.email))

.check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

Espresso.onView(ViewMatchers.withId(R.id.password))

.check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

Espresso.onView(ViewMatchers.withId(R.id.enter_button))

.check(ViewAssertions.matches(ViewMatchers.isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLayout() throws Exception {

// arrange



// act



// assert

onView(withId(R.id.email))

.check(matches(isDisplayed()));

onView(withId(R.id.password))

.check(matches(isDisplayed()));

onView(withId(R.id.enter_button))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLayout() throws Exception {

// arrange



// act



// assert

onView(withId(R.id.email))

.check(matches(isDisplayed()));

onView(withId(R.id.password))

.check(matches(isDisplayed()));

onView(withId(R.id.enter_button))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLayout() throws Exception {

// arrange



// act



// assert

onView(withId(R.id.email))

.check(matches(isDisplayed()));

onView(withId(R.id.password))

.check(matches(isDisplayed()));

onView(withId(R.id.enter_button))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLayout() throws Exception {

// arrange



// act



// assert

onView(withId(R.id.email))

.check(matches(isDisplayed()));

onView(withId(R.id.password))

.check(matches(isDisplayed()));

onView(withId(R.id.enter_button))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLayout() throws Exception {

// arrange



// act



// assert

onView(withId(R.id.email))

.check(matches(isDisplayed()));

onView(withId(R.id.password))

.check(matches(isDisplayed()));

onView(withId(R.id.enter_button))

.check(matches(isDisplayed()));

}


} Works!!
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLoginSuccess() throws Exception {

// arrange



// act

onView(ViewMatchers.withId(R.id.email))

.perform(typeText("whateverEmail"));

onView(ViewMatchers.withId(R.id.password))

.perform(typeText("whateverPassword"));

onView(ViewMatchers.withId(R.id.enter_button))

.perform(click());



// assert

onView(withText("Second Page"))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLoginSuccess() throws Exception {

// arrange



// act

onView(withId(R.id.email))

.perform(typeText("whateverEmail"));

onView(ViewMatchers.withId(R.id.password))

.perform(typeText("whateverPassword"));

onView(ViewMatchers.withId(R.id.enter_button))

.perform(click());



// assert

onView(withText("Second Page"))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLoginSuccess() throws Exception {

// arrange



// act

onView(withId(R.id.email))

.perform(typeText("whateverEmail"));

onView(withId(R.id.password))

.perform(typeText("whateverPassword"));

onView(ViewMatchers.withId(R.id.enter_button))

.perform(click());



// assert

onView(withText("Second Page"))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLoginSuccess() throws Exception {

// arrange



// act

onView(withId(R.id.email))

.perform(typeText("whateverEmail"));

onView(withId(R.id.password))

.perform(typeText("whateverPassword"));

onView(withId(R.id.enter_button))

.perform(click());



// assert

onView(withText("Second Page"))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLoginSuccess() throws Exception {

// arrange



// act

onView(withId(R.id.email))

.perform(typeText("whateverEmail"));

onView(withId(R.id.password))

.perform(typeText("whateverPassword"));

onView(withId(R.id.enter_button))

.perform(click());



// assert

onView(withText("Second Page"))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {

...


public void testLoginSuccess() throws Exception {

// arrange



// act

onView(withId(R.id.email))

.perform(typeText("whateverEmail"));

onView(withId(R.id.password))

.perform(typeText("whateverPassword"));

onView(withId(R.id.enter_button))

.perform(click());



// assert

onView(withText("Second Page"))

.check(matches(isDisplayed()));

}


}
after doing some research…
use Dagger2 for Dependency Injection
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

mUserService.login(email, password, new UserApiService.Callback() {

@Override

public void onSuccess() {

goToSecondPage();

}



@Override

public void onFailure() {



}

});

}
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

mUserService.login(email, password, new UserApiService.Callback() {

@Override

public void onSuccess() {

goToSecondPage();

}



@Override

public void onFailure() {



}

});

}
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

mUserService.login(email, password, new UserApiService.Callback() {

@Override

public void onSuccess() {

goToSecondPage();

}



@Override

public void onFailure() {



}

});

}
@Provides

@Singleton

UserService provideUserService(UserApiService userApiService){

return new UserService(mAppContext, userApiService);

}
release
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

mUserService.login(email, password, new UserApiService.Callback() {

@Override

public void onSuccess() {

goToSecondPage();

}



@Override

public void onFailure() {



}

});

}
@Provides

@Singleton

UserService provideUserService(UserApiService userApiService){

return new UserService(mAppContext, userApiService);

}
release
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

mUserService.login(email, password, new UserApiService.Callback() {

@Override

public void onSuccess() {

goToSecondPage();

}



@Override

public void onFailure() {



}

});

}


@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
@Provides

@Singleton

UserService provideUserService(UserApiService userApiService){

return new UserService(mAppContext, userApiService);

}
debug
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

mUserService.login(email, password, new UserApiService.Callback() {

@Override

public void onSuccess() {

goToSecondPage();

}



@Override

public void onFailure() {



}

});

}


@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
@Provides

@Singleton

UserService provideUserService(UserApiService userApiService){

return new UserService(mAppContext, userApiService);

}
debug
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {

String email = mEmailEditText.getText().toString();

String password = mPasswordEditText.getText().toString();

mUserService.login(email, password, new UserApiService.Callback() {

@Override

public void onSuccess() {

goToSecondPage();

}



@Override

public void onFailure() {



}

});

}


@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
@Provides

@Singleton

UserService provideUserService(UserApiService userApiService){

return new UserService(mAppContext, userApiService);

}
debug
Keep Instance


@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}


@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
public class MainActivityTest extends MainActivityTestCase {



public void setUp() throws Exception {

super.setUp();

getActivity();

UserServiceComponent.Initializer.getInstance().inject(this);

}


@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
public class MainActivityTest extends MainActivityTestCase {



public void setUp() throws Exception {

super.setUp();

getActivity();

UserServiceComponent.Initializer.getInstance().inject(this);

}
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {



@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
Keep Instance
public class MainActivityTest extends MainActivityTestCase {



public void setUp() throws Exception {

super.setUp();

getActivity();

UserServiceComponent.Initializer.getInstance().inject(this);

}
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {



@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
Keep Instance
public class MainActivityTest extends MainActivityTestCase {



public void setUp() throws Exception {

super.setUp();

getActivity();

UserServiceComponent.Initializer.getInstance().inject(this);

}
public class MainActivity extends AppCompatActivity {

...



@Inject

UserService mUserService;



@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);

...
}
public void onEnterButtonClick(View view) {



@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
Keep Instance
public class MainActivityTest extends MainActivityTestCase {



public void setUp() throws Exception {

super.setUp();

getActivity();

UserServiceComponent.Initializer.getInstance().inject(this);

}


@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
Keep Instance
public class MainActivityTest extends MainActivityTestCase {



public void setUp() throws Exception {

super.setUp();

getActivity();

UserServiceComponent.Initializer.getInstance().inject(this);

}
public class MainActivityTestCase extends ActivityInstrumentationTestCase2<MainActivity> {



@Inject

protected UserService mMockUserService;



public MainActivityTestCase() {

super(MainActivity.class);

}

}



@Provides

@Singleton

UserService provideTestUserService(UserApiService userApiService){

return mMockUserService;

}
Keep Instance
public class MainActivityTest extends MainActivityTestCase {



public void setUp() throws Exception {

super.setUp();

getActivity();

UserServiceComponent.Initializer.getInstance().inject(this);

}
public class MainActivityTestCase extends ActivityInstrumentationTestCase2<MainActivity> {



@Inject

protected UserService mMockUserService;



public MainActivityTestCase() {

super(MainActivity.class);

}

}

public class MainActivityTest extends MainActivityTestCase {

...


public void testLoginSuccess() throws Exception {

// arrange



// act

onView(ViewMatchers.withId(R.id.email))

.perform(typeText("whateverEmail"));

onView(ViewMatchers.withId(R.id.password))

.perform(typeText("whateverPassword"));

onView(ViewMatchers.withId(R.id.enter_button))

.perform(click());



// assert

onView(withText("Second Page"))

.check(matches(isDisplayed()));

}


}
public class MainActivityTest extends MainActivityTestCase {

...


public void testLoginSuccess() throws Exception {

// arrange

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

UserApiService.Callback callback = (UserApiService.Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(mMockUserService).login(anyString(), anyString(), any(UserApiService.Callback.class));



// act

onView(withId(R.id.email))

.perform(ViewActions.typeText("whateverEmail"));

onView(withId(R.id.password))

.perform(ViewActions.typeText("whateverPassword"));

onView(withId(R.id.enter_button))

.perform(ViewActions.click());



// assert

onView(withText("Second Page"))

.check(ViewAssertions.matches(isDisplayed()));

}

...
public class MainActivityTest extends MainActivityTestCase {

...


public void testLoginSuccess() throws Exception {

// arrange

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

UserApiService.Callback callback = (UserApiService.Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(mMockUserService).login(anyString(), anyString(), any(UserApiService.Callback.class));



// act

onView(withId(R.id.email))

.perform(ViewActions.typeText("whateverEmail"));

onView(withId(R.id.password))

.perform(ViewActions.typeText("whateverPassword"));

onView(withId(R.id.enter_button))

.perform(ViewActions.click());



// assert

onView(withText("Second Page"))

.check(ViewAssertions.matches(isDisplayed()));

}

...
public class MainActivityTest extends MainActivityTestCase {

...


public void testLoginSuccess() throws Exception {

// arrange

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

UserApiService.Callback callback = (UserApiService.Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(mMockUserService).login(anyString(), anyString(), any(UserApiService.Callback.class));



// act

onView(withId(R.id.email))

.perform(ViewActions.typeText("whateverEmail"));

onView(withId(R.id.password))

.perform(ViewActions.typeText("whateverPassword"));

onView(withId(R.id.enter_button))

.perform(ViewActions.click());



// assert

onView(withText("Second Page"))

.check(ViewAssertions.matches(isDisplayed()));

}

...
public class MainActivityTest extends MainActivityTestCase {

...


public void testLoginSuccess() throws Exception {

// arrange

doAnswer(new Answer() {

@Override

public Object answer(InvocationOnMock invocation) throws Throwable {

UserApiService.Callback callback = (UserApiService.Callback) invocation.getArguments()[2];

callback.onSuccess();

return null;

}

}).when(mMockUserService).login(anyString(), anyString(), any(UserApiService.Callback.class));



// act

onView(withId(R.id.email))

.perform(ViewActions.typeText("whateverEmail"));

onView(withId(R.id.password))

.perform(ViewActions.typeText("whateverPassword"));

onView(withId(R.id.enter_button))

.perform(ViewActions.click());



// assert

onView(withText("Second Page"))

.check(ViewAssertions.matches(isDisplayed()));

}

...
Works!!
• sometimes failed
• static variable
• local storage
• not easy to test all stuff
• no a best way you can follow
frequent problems
• Pattern (MVP, DI)
• Structure
• follow up the android geeks
what I learned
• mock object called when activity onCreate
• UI testing for a fragment with interaction with
certain activity
• find out the best test sturcture
still need to figure out
• https://github.com/proevan/android-testing-sample

More Related Content

What's hot

Handling action bar in Android
Handling action bar in AndroidHandling action bar in Android
Handling action bar in Android
indiangarg
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
Fabio Collini
 
Modern Android Architecture
Modern Android ArchitectureModern Android Architecture
Modern Android Architecture
Eric Maxwell
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in Android
Robert Cooper
 
Better Bullshit Driven Development [SeleniumCamp 2017]
Better Bullshit Driven Development [SeleniumCamp 2017]Better Bullshit Driven Development [SeleniumCamp 2017]
Better Bullshit Driven Development [SeleniumCamp 2017]
automician
 
Ejercicio sql server vs visual .net
Ejercicio sql server vs visual .netEjercicio sql server vs visual .net
Ejercicio sql server vs visual .net
Ayuda Universidad
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
Yurii Kotov
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New EvolutionAllan Huang
 
Wicket KT part 2
Wicket KT part 2Wicket KT part 2
Wicket KT part 2
stuq
 
Action Bar in Android
Action Bar in AndroidAction Bar in Android
Action Bar in Android
Prof. Erwin Globio
 
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
PROIDEA
 
React.js workshop by tech47.in
React.js workshop by tech47.inReact.js workshop by tech47.in
React.js workshop by tech47.in
Jaikant Kumaran
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with React
GreeceJS
 
Android App Development - 05 Action bar
Android App Development - 05 Action barAndroid App Development - 05 Action bar
Android App Development - 05 Action bar
Diego Grancini
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門
Ryosuke Uchitate
 
Android - Saving data
Android - Saving dataAndroid - Saving data
Android - Saving data
Matteo Bonifazi
 
Google Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification GoogleGoogle Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification Google
Mathias Seguy
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
Ignacio Coloma
 

What's hot (18)

Handling action bar in Android
Handling action bar in AndroidHandling action bar in Android
Handling action bar in Android
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
Modern Android Architecture
Modern Android ArchitectureModern Android Architecture
Modern Android Architecture
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in Android
 
Better Bullshit Driven Development [SeleniumCamp 2017]
Better Bullshit Driven Development [SeleniumCamp 2017]Better Bullshit Driven Development [SeleniumCamp 2017]
Better Bullshit Driven Development [SeleniumCamp 2017]
 
Ejercicio sql server vs visual .net
Ejercicio sql server vs visual .netEjercicio sql server vs visual .net
Ejercicio sql server vs visual .net
 
Data binding в массы! (1.2)
Data binding в массы! (1.2)Data binding в массы! (1.2)
Data binding в массы! (1.2)
 
JQuery New Evolution
JQuery New EvolutionJQuery New Evolution
JQuery New Evolution
 
Wicket KT part 2
Wicket KT part 2Wicket KT part 2
Wicket KT part 2
 
Action Bar in Android
Action Bar in AndroidAction Bar in Android
Action Bar in Android
 
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
4Developers: Michał Szczepanik- Kotlin - Let’s ketchup it
 
React.js workshop by tech47.in
React.js workshop by tech47.inReact.js workshop by tech47.in
React.js workshop by tech47.in
 
Taming forms with React
Taming forms with ReactTaming forms with React
Taming forms with React
 
Android App Development - 05 Action bar
Android App Development - 05 Action barAndroid App Development - 05 Action bar
Android App Development - 05 Action bar
 
Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門Form認証で学ぶSpring Security入門
Form認証で学ぶSpring Security入門
 
Android - Saving data
Android - Saving dataAndroid - Saving data
Android - Saving data
 
Google Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification GoogleGoogle Plus SignIn : l'Authentification Google
Google Plus SignIn : l'Authentification Google
 
Codemotion appengine
Codemotion appengineCodemotion appengine
Codemotion appengine
 

Similar to Android Testing

Tutorial basicapp
Tutorial basicappTutorial basicapp
Tutorial basicapp
Herry Prasetyo
 
Wicket 6
Wicket 6Wicket 6
Wicket 6
codepitbull
 
Testing in android
Testing in androidTesting in android
Testing in android
jtrindade
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
Dhaval Dalal
 
Testando API's de forma unitária mocando as dependências
Testando API's de forma unitária mocando as dependênciasTestando API's de forma unitária mocando as dependências
Testando API's de forma unitária mocando as dependências
Marcelo Aymone
 
Creating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfCreating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdf
ShaiAlmog1
 
Neues aus dem Tindergarten: Auswertung "privater" APIs mit Apache Ignite
Neues aus dem Tindergarten: Auswertung "privater" APIs mit Apache IgniteNeues aus dem Tindergarten: Auswertung "privater" APIs mit Apache Ignite
Neues aus dem Tindergarten: Auswertung "privater" APIs mit Apache Ignite
QAware GmbH
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
javatwo2011
 
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
solit
 
Asp.net state management
Asp.net state managementAsp.net state management
Asp.net state management
priya Nithya
 
Creating an Uber Clone - Part XXXX - Transcript.pdf
Creating an Uber Clone - Part XXXX - Transcript.pdfCreating an Uber Clone - Part XXXX - Transcript.pdf
Creating an Uber Clone - Part XXXX - Transcript.pdf
ShaiAlmog1
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrity
Washington Botelho
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access RunbookTaha Shakeel
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
ShaiAlmog1
 
jQuery Bay Area Conference 2010
jQuery Bay Area Conference 2010jQuery Bay Area Conference 2010
jQuery Bay Area Conference 2010
mennovanslooten
 
Android ui layouts ,cntls,webservices examples codes
Android ui layouts ,cntls,webservices examples codesAndroid ui layouts ,cntls,webservices examples codes
Android ui layouts ,cntls,webservices examples codes
Aravindharamanan S
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
DataArt
 
Testy integracyjne
Testy integracyjneTesty integracyjne
Testy integracyjne
Łukasz Zakrzewski
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
Ryunosuke SATO
 

Similar to Android Testing (20)

Week 12 code
Week 12 codeWeek 12 code
Week 12 code
 
Tutorial basicapp
Tutorial basicappTutorial basicapp
Tutorial basicapp
 
Wicket 6
Wicket 6Wicket 6
Wicket 6
 
Testing in android
Testing in androidTesting in android
Testing in android
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 
Testando API's de forma unitária mocando as dependências
Testando API's de forma unitária mocando as dependênciasTestando API's de forma unitária mocando as dependências
Testando API's de forma unitária mocando as dependências
 
Creating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfCreating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdf
 
Neues aus dem Tindergarten: Auswertung "privater" APIs mit Apache Ignite
Neues aus dem Tindergarten: Auswertung "privater" APIs mit Apache IgniteNeues aus dem Tindergarten: Auswertung "privater" APIs mit Apache Ignite
Neues aus dem Tindergarten: Auswertung "privater" APIs mit Apache Ignite
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
Solit 2013, Автоматизация тестирования сложных систем: mixed mode automated t...
 
Asp.net state management
Asp.net state managementAsp.net state management
Asp.net state management
 
Creating an Uber Clone - Part XXXX - Transcript.pdf
Creating an Uber Clone - Part XXXX - Transcript.pdfCreating an Uber Clone - Part XXXX - Transcript.pdf
Creating an Uber Clone - Part XXXX - Transcript.pdf
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrity
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
 
jQuery Bay Area Conference 2010
jQuery Bay Area Conference 2010jQuery Bay Area Conference 2010
jQuery Bay Area Conference 2010
 
Android ui layouts ,cntls,webservices examples codes
Android ui layouts ,cntls,webservices examples codesAndroid ui layouts ,cntls,webservices examples codes
Android ui layouts ,cntls,webservices examples codes
 
Тарас Олексин - Sculpt! Your! Tests!
Тарас Олексин  - Sculpt! Your! Tests!Тарас Олексин  - Sculpt! Your! Tests!
Тарас Олексин - Sculpt! Your! Tests!
 
Testy integracyjne
Testy integracyjneTesty integracyjne
Testy integracyjne
 
Clean Javascript
Clean JavascriptClean Javascript
Clean Javascript
 

Recently uploaded

May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Enterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptxEnterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptx
QuickwayInfoSystems3
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
Google
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Globus
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
e20449
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
Ortus Solutions, Corp
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
ShamsuddeenMuhammadA
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 

Recently uploaded (20)

May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Enterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptxEnterprise Software Development with No Code Solutions.pptx
Enterprise Software Development with No Code Solutions.pptx
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing SuiteAI Pilot Review: The World’s First Virtual Assistant Marketing Suite
AI Pilot Review: The World’s First Virtual Assistant Marketing Suite
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
Innovating Inference - Remote Triggering of Large Language Models on HPC Clus...
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
Graphic Design Crash Course for beginners
Graphic Design Crash Course for beginnersGraphic Design Crash Course for beginners
Graphic Design Crash Course for beginners
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024BoxLang: Review our Visionary Licenses of 2024
BoxLang: Review our Visionary Licenses of 2024
 
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptxText-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
Text-Summarization-of-Breaking-News-Using-Fine-tuning-BART-Model.pptx
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 

Android Testing

  • 2. Tools • Mock -> Mockito • http://mockito.org/ • UI Testing -> Espresso • https://developer.android.com/training/testing/ui-testing/espresso-testing.html • Dependency Injection -> Dagger2 • http://google.github.io/dagger/
  • 3. Mockito dependencies {
 ... 
 // Mockito
 debugCompile 'org.mockito:mockito-core:1.10.19'
 debugCompile 'com.google.dexmaker:dexmaker:1.2'
 debugCompile ‘com.google.dexmaker:dexmaker-mockito:1.2' 
 }
  • 4. Espresso android {
 
 defaultConfig { 
 ... 
 // Espresso2
 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
 }
 } 
 dependencies { 
 ... 
 // Espresso2
 androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2'
 androidTestCompile ‘com.android.support.test:runner:0.3' 
 }
  • 5. Dagger2 // dagger2 apply plugin: 'com.neenbedankt.android-apt'
 
 buildscript {
 repositories {
 jcenter()
 }
 dependencies {
 // dagger2
 classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
 }
 }
 
 dependencies { 
 ... 
 // dagger2
 compile 'junit:junit:4.12'
 compile 'com.google.dagger:dagger:2.0'
 apt 'com.google.dagger:dagger-compiler:2.0'
 provided 'org.glassfish:javax.annotation:10.0-b28'
 }

  • 7.
  • 8. public class MainActivity extends Activity {
 
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 }
 }
 EditText mEmailEditText;
 EditText mPasswordEditText;
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password);
 
 public void onEnterButtonClick() {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 if (checkEmailAndPassword(email, password))
 goToSecondPage();
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
  • 9. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password);
 }
 
 public void onEnterButtonClick() {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 if (checkEmailAndPassword(email, password))
 goToSecondPage();
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
 }
  • 10. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password);
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 if (checkEmailAndPassword(email, password))
 goToSecondPage();
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
 }
  • 11. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password);
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 if (checkEmailAndPassword(email, password))
 goToSecondPage();
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
 }
  • 12. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password);
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 if (checkEmailAndPassword(email, password))
 goToSecondPage();
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
 }
  • 13.
  • 15. public class UserService {
 
 ...
 
 public boolean isLogin() {
 return loadLoginStatus();
 }
 
 public boolean login(String email, String password) {
 if (checkEmailAndPassword(email, password)) {
 saveLoginStatus(true);
 return true;
 } else {
 return false;
 }
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 ...
 }
  • 16. public class UserService {
 
 ...
 
 public boolean isLogin() {
 return loadLoginStatus();
 }
 
 public boolean login(String email, String password) {
 if (checkEmailAndPassword(email, password)) {
 saveLoginStatus(true);
 return true;
 } else {
 return false;
 }
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 ...
 }
  • 17. public class UserService {
 
 ...
 
 public boolean isLogin() {
 return loadLoginStatus();
 }
 
 public boolean login(String email, String password) {
 if (checkEmailAndPassword(email, password)) {
 saveLoginStatus(true);
 return true;
 } else {
 return false;
 }
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 ...
 }
  • 18. public class UserService {
 
 private PasswordValidator mPasswordValidator;
 ...
 public boolean isLogin() {
 return loadLoginStatus();
 }
 
 public boolean login(String email, String password) {
 if (mPasswordValidator.checkEmailAndPassword(email, password)) {
 saveLoginStatus(true);
 return true;
 } else {
 return false;
 }
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 ... }
  • 19. public class PasswordValidator {
 
 public boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 }
  • 20. public class UserService {
 
 public static final String SHARED_PREF_NAME = "MY_SHARED_PREF";
 private static final String SHARED_PREF_KEY_IS_LOGIN = “SHARED_PREF_KEY_IS_LOGIN";
 private PasswordValidator mPasswordValidator;
 private SharedPreferences mSharedPreferences;
 
 public UserService(Context appContext, PasswordValidator validator) { mPasswordValidator = validator;
 mSharedPreferences = appContext.getSharedPreferences(SHARED_PREF_NAME, 0);
 }
 
 ...
 
 private boolean loadLoginStatus() {
 return mSharedPreferences.getBoolean(SHARED_PREF_KEY_IS_LOGIN, false);
 }
 
 private void saveLoginStatus(boolean isLogin) {
 SharedPreferences.Editor editor = mSharedPreferences.edit();
 editor.putBoolean(SHARED_PREF_KEY_IS_LOGIN, isLogin);
 editor.commit();
 }
 }
  • 21. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password);
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 if (checkEmailAndPassword(email, password))
 goToSecondPage();
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
 }
  • 22. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 UserService mUserService; 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password); mUserService = new UserService(getApplicationContext(), new PasswordValidator());
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 if (checkEmailAndPassword(email, password))
 goToSecondPage();
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
 }
  • 23. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password); mUserService = new UserService(getApplicationContext(), new PasswordValidator());
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 if (checkEmailAndPassword(email, password))
 goToSecondPage();
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
 }
  • 24. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password); mUserService = new UserService(getApplicationContext(), new PasswordValidator());
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 boolean isLoginSuccess = mUserService.login(email, password);
 if (isLoginSuccess)
 goToSecondPage();
 }
 
 private void goToSecondPage() {
 Intent intent = new Intent(this, SecondActivity.class);
 startActivity(intent);
 }
 }
  • 25. public class MainActivity extends Activity {
 
 EditText mEmailEditText;
 EditText mPasswordEditText;
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password); mUserService = new UserService(getApplicationContext(), new PasswordValidator());
 if (checkAutoLogin()) {
 goToSecondPage();
 finish();
 }
 }
 
 private boolean checkAutoLogin() {
 return mUserService.isLogin();
 } 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 boolean isLoginSuccess = mUserService.login(email, password);
 if (isLoginSuccess)
 goToSecondPage();
 } ...
  • 26. First Time Open App Second Time Open App
  • 30. public class UserServiceTest extends TestCase {
 
 }
  • 31. public class UserServiceTest extends TestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 
 // assert
 
 }
 
 }
  • 32. public class UserServiceTest extends TestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 
 // assert
 
 }
 
 } test method prefix
  • 33. public class UserServiceTest extends TestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 
 // assert
 
 }
 
 }
  • 34. public class UserServiceTest extends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = new PasswordValidator();
 UserService userService = new UserService(getContext(), validator);
 
 // act
 
 // assert
 
 }
 
 }
  • 35. public class UserServiceTest extends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = new PasswordValidator();
 UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("admin", "admin");
 
 // assert
 assertTrue(userService.isLogin()); }
 
 }
  • 36. public class UserServiceTest extends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = Mockito.mock(PasswordValidator.class); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("admin", "admin");
 
 // assert
 assertTrue(userService.isLogin()); }
 
 }
  • 37. public class UserServiceTest extends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = Mockito.mock(PasswordValidator.class); Mockito.when(validator.checkEmailAndPassword(Matchers.anyString(), 
 Matchers.anyString())).thenReturn(true); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("admin", "admin");
 
 // assert
 assertTrue(userService.isLogin()); }
 
 }
  • 38. public class UserServiceTest extends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = Mockito.mock(PasswordValidator.class); Mockito.when(validator.checkEmailAndPassword(Matchers.anyString(), 
 Matchers.anyString())).thenReturn(true); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("whateverEmail", "whateverPassword");
 
 // assert
 assertTrue(userService.isLogin()); }
 
 }
  • 39. public class UserServiceTest extends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = Mockito.mock(PasswordValidator.class); Mockito.when(validator.checkEmailAndPassword(Matchers.anyString(), 
 Matchers.anyString())).thenReturn(true); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("whateverEmail", "whateverPassword");
 
 // assert
 assertTrue(userService.isLogin()); }
 
 }
  • 40. public class UserServiceTest extends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = mock(PasswordValidator.class); when(validator.checkEmailAndPassword(anyString(), 
 anyString())).thenReturn(true); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("whateverEmail", "whateverPassword");
 
 // assert
 assertTrue(userService.isLogin()); }
 
 public void testLoginFailure() throws Exception {
 // arrange
 PasswordValidator validator = mock(PasswordValidator.class); when(validator.checkEmailAndPassword(anyString(), 
 anyString())).thenReturn(false); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("whateverEmail", "whateverPassword");
 
 // assert
 assertFalse(userService.isLogin()); }
 
 }
  • 41. public class UserServiceTest extends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = mock(PasswordValidator.class); when(validator.checkEmailAndPassword(anyString(), 
 anyString())).thenReturn(true); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("whateverEmail", "whateverPassword");
 
 // assert
 assertTrue(userService.isLogin()); }
 
 public void testLoginFailure() throws Exception {
 // arrange
 PasswordValidator validator = mock(PasswordValidator.class); when(validator.checkEmailAndPassword(anyString(), 
 anyString())).thenReturn(false); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("whateverEmail", "whateverPassword");
 
 // assert
 assertFalse(userService.isLogin()); }
 
 }
  • 42. • passed when running separately(sometimes?)
  • 43. • passed when running separately(sometimes?) • but failed running the whole tests
  • 44. • passed when running separately(sometimes?) • but failed running the whole tests • WHY?
  • 45. public boolean isLogin() {
 return loadLoginStatus();
 }
 
 public boolean login(String email, String password) {
 if (mPasswordValidator.checkEmailAndPassword(email, password)) {
 saveLoginStatus(true);
 return true;
 } else {
 return false;
 }
 }
 
 private boolean loadLoginStatus() {
 return mSharedPreferences.getBoolean(SHARED_PREF_KEY_IS_LOGIN, false);
 }
 
 private void saveLoginStatus(boolean isLogin) {
 SharedPreferences.Editor editor = mSharedPreferences.edit();
 editor.putBoolean(SHARED_PREF_KEY_IS_LOGIN, isLogin);
 editor.commit();
 }
  • 46. public class UserServiceTest extends AndroidTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 clearSharedPref();
 }
 
 private void clearSharedPref() {
 getContext().getSharedPreferences(UserService.SHARED_PREF_NAME, 0)
 .edit().clear().commit();
 }
 ...
  • 49. public class PasswordValidator {
 
 public boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 }
  • 50. public class PasswordValidator {
 
 public boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 } public class UserApiService {
 
 public void login(String email, String password, Callback callback) {
 // todo: send login request to server...
 }
 
 public interface Callback {
 void onSuccess();
 void onFailure();
 }
 }
  • 51. public class UserApiService {
 
 public void login(String email, String password, Callback callback) {
 // todo: send login request to server...
 }
 
 public interface Callback {
 void onSuccess();
 void onFailure();
 }
 }
  • 52. public class UserApiService {
 
 public void login(String email, String password, Callback callback) {
 if (checkEmailAndPassword(email, password))
 wait2SecondsAndRespondSuccess(callback);
 }
 
 private boolean checkEmailAndPassword(String email, String password) {
 return email.equals("admin") && password.equals("admin");
 }
 
 private void wait2SecondsAndRespondSuccess(final Callback callback) {
 new Handler().postDelayed(new Runnable() {
 @Override
 public void run() {
 callback.onSuccess();
 }
 }, 2000);
 }
 
 public interface Callback {
 void onSuccess();
 void onFailure();
 }
 }

  • 53. public class UserService {
 
 private PasswordValidator mPasswordValidator;
 ... public UserService(Context appContext, PasswordValidator validator) { mPasswordValidator = validator;
 ...
 } 
 public boolean login(String email, String password) {
 if (mPasswordValidator.checkEmailAndPassword(email, password)) {
 saveLoginStatus(true);
 return true;
 } else {
 return false;
 }
 } 
 ... }
  • 54. public class UserService {
 
 private UserApiService mUserApiService;
 ... public UserService(Context appContext, UserApiService userApiService) { mUserApiService = userApiService;
 ...
 } 
 public void login(String email, String password, final Callback callback) {
 mUserApiService.login(email, password, new Callback() {
 @Override
 public void onSuccess() {
 saveLoginStatus(true);
 callback.onSuccess();
 }
 
 @Override
 public void onFailure() {
 callback.onFailure();
 }
 });
 }
 ...
  • 55. public class MainActivity extends Activity { 
 ...
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password); mUserService = new UserService(getApplicationContext(), new PasswordValidator());
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 boolean isLoginSuccess = mUserService.login(email, password);
 if (isLoginSuccess)
 goToSecondPage();
 }
 
 ...
  • 56. public class MainActivity extends Activity { 
 ...
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 mEmailEditText = (EditText) findViewById(R.id.email);
 mPasswordEditText = (EditText) findViewById(R.id.password); mUserService = new UserService(getApplicationContext(), new UserApiService());
 }
 
 public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 mUserService.login(email, password, new UserApiService.Callback() {
 @Override
 public void onSuccess() {
 goToSecondPage();
 }
 
 @Override
 public void onFailure() {
 
 }
 });
 }
 
 ... 

  • 58. public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = mock(PasswordValidator.class); when(validator.checkEmailAndPassword(anyString(), 
 anyString())).thenReturn(true); UserService userService = new UserService(getContext(), validator);
 
 // act
 userService.login("whateverEmail", "whateverPassword");
 
 // assert
 assertTrue(userService.isLogin()); }

  • 59. public void testLoginSuccess() throws Exception {
 // arrange
 UserApiService userApiService = mock(UserApiService.class);
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 Callback callback = (Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(userApiService).login(anyString(), anyString(), any(Callback.class));
 UserService userService = new UserService(getContext(), userApiService);
 
 // act
 userService.login("whateverEmail", "whateverPassword", mock(Callback.class));
 
 // assert
 assertTrue(userService.isLogin());
 }
  • 60. public void testLoginSuccess() throws Exception {
 // arrange
 UserApiService userApiService = mock(UserApiService.class);
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 Callback callback = (Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(userApiService).login(anyString(), anyString(), any(Callback.class));
 UserService userService = new UserService(getContext(), userApiService);
 
 // act
 userService.login("whateverEmail", "whateverPassword", mock(Callback.class));
 
 // assert
 assertTrue(userService.isLogin());
 }
  • 61. public void testLoginSuccess() throws Exception {
 // arrange
 UserApiService userApiService = mock(UserApiService.class);
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 Callback callback = (Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(userApiService).login(anyString(), anyString(), any(Callback.class));
 UserService userService = new UserService(getContext(), userApiService);
 
 // act
 userService.login("whateverEmail", "whateverPassword", mock(Callback.class));
 
 // assert
 assertTrue(userService.isLogin());
 }
  • 62. public void testLoginSuccess() throws Exception {
 // arrange
 UserApiService userApiService = mock(UserApiService.class);
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 Callback callback = (Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(userApiService).login(anyString(), anyString(), any(Callback.class));
 UserService userService = new UserService(getContext(), userApiService);
 
 // act
 userService.login("whateverEmail", "whateverPassword", mock(Callback.class));
 
 // assert
 assertTrue(userService.isLogin());
 }
  • 63. public void testLoginSuccess() throws Exception {
 // arrange
 UserApiService userApiService = mock(UserApiService.class);
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 Callback callback = (Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(userApiService).login(anyString(), anyString(), any(Callback.class));
 UserService userService = new UserService(getContext(), userApiService);
 
 // act
 userService.login("whateverEmail", "whateverPassword", mock(Callback.class));
 
 // assert
 assertTrue(userService.isLogin());
 }
  • 64. public void testLoginSuccess() throws Exception {
 // arrange
 UserApiService userApiService = mock(UserApiService.class);
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 Callback callback = (Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(userApiService).login(anyString(), anyString(), any(Callback.class));
 UserService userService = new UserService(getContext(), userApiService);
 
 // act
 userService.login("whateverEmail", "whateverPassword", mock(Callback.class));
 
 // assert
 assertTrue(userService.isLogin());
 }
  • 65. public void testLoginSuccess() throws Exception {
 // arrange
 UserApiService userApiService = mock(UserApiService.class);
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 Callback callback = (Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(userApiService).login(anyString(), anyString(), any(Callback.class));
 UserService userService = new UserService(getContext(), userApiService);
 
 // act
 userService.login("whateverEmail", "whateverPassword", mock(Callback.class));
 
 // assert
 assertTrue(userService.isLogin());
 }
 
 public void testLoginFailure() throws Exception {
 // arrange
 UserApiService userApiService = mock(UserApiService.class);
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 Callback callback = (Callback) invocation.getArguments()[2];
 callback.onFailure();
 return null;
 }
 }).when(userApiService).login(anyString(), anyString(), any(Callback.class));
 UserService userService = new UserService(getContext(), userApiService);
 
 // act
 userService.login("whateverEmail", "whateverPassword", mock(Callback.class));
 
 // assert
 assertFalse(userService.isLogin());
 }
  • 68. 1. 2. 3. public class MainActivityTest extends TestCase {
 
 }
  • 69. public class MainActivityTest extends TestCase {
 
 }
  • 70. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 
 public MainActivityTest() {
 super(MainActivity.class);
 } 
 }
  • 71. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 
 public MainActivityTest() {
 super(MainActivity.class);
 } 
 public void setUp() throws Exception {
 super.setUp();
 clearSharedPref();
 getActivity();
 }
 
 private void clearSharedPref() {
 getInstrumentation().getTargetContext().getSharedPreferences (UserService.SHARED_PREF_NAME, 0).edit().clear().commit();
 }
 }
  • 72. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLayout() throws Exception {
 // arrange
 
 // act
 
 // assert
 Espresso.onView(ViewMatchers.withId(R.id.email))
 .check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
 Espresso.onView(ViewMatchers.withId(R.id.password))
 .check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
 Espresso.onView(ViewMatchers.withId(R.id.enter_button))
 .check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
 } 
 }
  • 73. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLayout() throws Exception {
 // arrange
 
 // act
 
 // assert
 Espresso.onView(ViewMatchers.withId(R.id.email))
 .check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
 Espresso.onView(ViewMatchers.withId(R.id.password))
 .check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
 Espresso.onView(ViewMatchers.withId(R.id.enter_button))
 .check(ViewAssertions.matches(ViewMatchers.isDisplayed()));
 } 
 }
  • 74. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLayout() throws Exception {
 // arrange
 
 // act
 
 // assert
 onView(withId(R.id.email))
 .check(matches(isDisplayed()));
 onView(withId(R.id.password))
 .check(matches(isDisplayed()));
 onView(withId(R.id.enter_button))
 .check(matches(isDisplayed()));
 } 
 }
  • 75. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLayout() throws Exception {
 // arrange
 
 // act
 
 // assert
 onView(withId(R.id.email))
 .check(matches(isDisplayed()));
 onView(withId(R.id.password))
 .check(matches(isDisplayed()));
 onView(withId(R.id.enter_button))
 .check(matches(isDisplayed()));
 } 
 }
  • 76. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLayout() throws Exception {
 // arrange
 
 // act
 
 // assert
 onView(withId(R.id.email))
 .check(matches(isDisplayed()));
 onView(withId(R.id.password))
 .check(matches(isDisplayed()));
 onView(withId(R.id.enter_button))
 .check(matches(isDisplayed()));
 } 
 }
  • 77. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLayout() throws Exception {
 // arrange
 
 // act
 
 // assert
 onView(withId(R.id.email))
 .check(matches(isDisplayed()));
 onView(withId(R.id.password))
 .check(matches(isDisplayed()));
 onView(withId(R.id.enter_button))
 .check(matches(isDisplayed()));
 } 
 }
  • 78. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLayout() throws Exception {
 // arrange
 
 // act
 
 // assert
 onView(withId(R.id.email))
 .check(matches(isDisplayed()));
 onView(withId(R.id.password))
 .check(matches(isDisplayed()));
 onView(withId(R.id.enter_button))
 .check(matches(isDisplayed()));
 } 
 } Works!!
  • 79. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 onView(ViewMatchers.withId(R.id.email))
 .perform(typeText("whateverEmail"));
 onView(ViewMatchers.withId(R.id.password))
 .perform(typeText("whateverPassword"));
 onView(ViewMatchers.withId(R.id.enter_button))
 .perform(click());
 
 // assert
 onView(withText("Second Page"))
 .check(matches(isDisplayed()));
 } 
 }
  • 80. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 onView(withId(R.id.email))
 .perform(typeText("whateverEmail"));
 onView(ViewMatchers.withId(R.id.password))
 .perform(typeText("whateverPassword"));
 onView(ViewMatchers.withId(R.id.enter_button))
 .perform(click());
 
 // assert
 onView(withText("Second Page"))
 .check(matches(isDisplayed()));
 } 
 }
  • 81. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 onView(withId(R.id.email))
 .perform(typeText("whateverEmail"));
 onView(withId(R.id.password))
 .perform(typeText("whateverPassword"));
 onView(ViewMatchers.withId(R.id.enter_button))
 .perform(click());
 
 // assert
 onView(withText("Second Page"))
 .check(matches(isDisplayed()));
 } 
 }
  • 82. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 onView(withId(R.id.email))
 .perform(typeText("whateverEmail"));
 onView(withId(R.id.password))
 .perform(typeText("whateverPassword"));
 onView(withId(R.id.enter_button))
 .perform(click());
 
 // assert
 onView(withText("Second Page"))
 .check(matches(isDisplayed()));
 } 
 }
  • 83. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 onView(withId(R.id.email))
 .perform(typeText("whateverEmail"));
 onView(withId(R.id.password))
 .perform(typeText("whateverPassword"));
 onView(withId(R.id.enter_button))
 .perform(click());
 
 // assert
 onView(withText("Second Page"))
 .check(matches(isDisplayed()));
 } 
 }
  • 84. public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 onView(withId(R.id.email))
 .perform(typeText("whateverEmail"));
 onView(withId(R.id.password))
 .perform(typeText("whateverPassword"));
 onView(withId(R.id.enter_button))
 .perform(click());
 
 // assert
 onView(withText("Second Page"))
 .check(matches(isDisplayed()));
 } 
 }
  • 85. after doing some research…
  • 86. use Dagger2 for Dependency Injection
  • 87. public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 mUserService.login(email, password, new UserApiService.Callback() {
 @Override
 public void onSuccess() {
 goToSecondPage();
 }
 
 @Override
 public void onFailure() {
 
 }
 });
 }
  • 88. public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 mUserService.login(email, password, new UserApiService.Callback() {
 @Override
 public void onSuccess() {
 goToSecondPage();
 }
 
 @Override
 public void onFailure() {
 
 }
 });
 }
  • 89. public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 mUserService.login(email, password, new UserApiService.Callback() {
 @Override
 public void onSuccess() {
 goToSecondPage();
 }
 
 @Override
 public void onFailure() {
 
 }
 });
 } @Provides
 @Singleton
 UserService provideUserService(UserApiService userApiService){
 return new UserService(mAppContext, userApiService);
 } release
  • 90. public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 mUserService.login(email, password, new UserApiService.Callback() {
 @Override
 public void onSuccess() {
 goToSecondPage();
 }
 
 @Override
 public void onFailure() {
 
 }
 });
 } @Provides
 @Singleton
 UserService provideUserService(UserApiService userApiService){
 return new UserService(mAppContext, userApiService);
 } release
  • 91. public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 mUserService.login(email, password, new UserApiService.Callback() {
 @Override
 public void onSuccess() {
 goToSecondPage();
 }
 
 @Override
 public void onFailure() {
 
 }
 });
 } 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } @Provides
 @Singleton
 UserService provideUserService(UserApiService userApiService){
 return new UserService(mAppContext, userApiService);
 } debug
  • 92. public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 mUserService.login(email, password, new UserApiService.Callback() {
 @Override
 public void onSuccess() {
 goToSecondPage();
 }
 
 @Override
 public void onFailure() {
 
 }
 });
 } 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } @Provides
 @Singleton
 UserService provideUserService(UserApiService userApiService){
 return new UserService(mAppContext, userApiService);
 } debug
  • 93. public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {
 String email = mEmailEditText.getText().toString();
 String password = mPasswordEditText.getText().toString();
 mUserService.login(email, password, new UserApiService.Callback() {
 @Override
 public void onSuccess() {
 goToSecondPage();
 }
 
 @Override
 public void onFailure() {
 
 }
 });
 } 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } @Provides
 @Singleton
 UserService provideUserService(UserApiService userApiService){
 return new UserService(mAppContext, userApiService);
 } debug Keep Instance
  • 95. 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } public class MainActivityTest extends MainActivityTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 getActivity();
 UserServiceComponent.Initializer.getInstance().inject(this);
 }
  • 96. 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } public class MainActivityTest extends MainActivityTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 getActivity();
 UserServiceComponent.Initializer.getInstance().inject(this);
 } public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {

  • 97. 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } Keep Instance public class MainActivityTest extends MainActivityTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 getActivity();
 UserServiceComponent.Initializer.getInstance().inject(this);
 } public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {

  • 98. 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } Keep Instance public class MainActivityTest extends MainActivityTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 getActivity();
 UserServiceComponent.Initializer.getInstance().inject(this);
 } public class MainActivity extends AppCompatActivity {
 ...
 
 @Inject
 UserService mUserService;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 UserServiceComponent.Initializer.init(getApplicationContext()).inject(this);
 ... } public void onEnterButtonClick(View view) {

  • 99. 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } Keep Instance public class MainActivityTest extends MainActivityTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 getActivity();
 UserServiceComponent.Initializer.getInstance().inject(this);
 }
  • 100. 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } Keep Instance public class MainActivityTest extends MainActivityTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 getActivity();
 UserServiceComponent.Initializer.getInstance().inject(this);
 } public class MainActivityTestCase extends ActivityInstrumentationTestCase2<MainActivity> {
 
 @Inject
 protected UserService mMockUserService;
 
 public MainActivityTestCase() {
 super(MainActivity.class);
 }
 }

  • 101. 
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 return mMockUserService;
 } Keep Instance public class MainActivityTest extends MainActivityTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 getActivity();
 UserServiceComponent.Initializer.getInstance().inject(this);
 } public class MainActivityTestCase extends ActivityInstrumentationTestCase2<MainActivity> {
 
 @Inject
 protected UserService mMockUserService;
 
 public MainActivityTestCase() {
 super(MainActivity.class);
 }
 }

  • 102. public class MainActivityTest extends MainActivityTestCase {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 onView(ViewMatchers.withId(R.id.email))
 .perform(typeText("whateverEmail"));
 onView(ViewMatchers.withId(R.id.password))
 .perform(typeText("whateverPassword"));
 onView(ViewMatchers.withId(R.id.enter_button))
 .perform(click());
 
 // assert
 onView(withText("Second Page"))
 .check(matches(isDisplayed()));
 } 
 }
  • 103. public class MainActivityTest extends MainActivityTestCase {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 UserApiService.Callback callback = (UserApiService.Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(mMockUserService).login(anyString(), anyString(), any(UserApiService.Callback.class));
 
 // act
 onView(withId(R.id.email))
 .perform(ViewActions.typeText("whateverEmail"));
 onView(withId(R.id.password))
 .perform(ViewActions.typeText("whateverPassword"));
 onView(withId(R.id.enter_button))
 .perform(ViewActions.click());
 
 // assert
 onView(withText("Second Page"))
 .check(ViewAssertions.matches(isDisplayed()));
 }
 ...
  • 104. public class MainActivityTest extends MainActivityTestCase {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 UserApiService.Callback callback = (UserApiService.Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(mMockUserService).login(anyString(), anyString(), any(UserApiService.Callback.class));
 
 // act
 onView(withId(R.id.email))
 .perform(ViewActions.typeText("whateverEmail"));
 onView(withId(R.id.password))
 .perform(ViewActions.typeText("whateverPassword"));
 onView(withId(R.id.enter_button))
 .perform(ViewActions.click());
 
 // assert
 onView(withText("Second Page"))
 .check(ViewAssertions.matches(isDisplayed()));
 }
 ...
  • 105. public class MainActivityTest extends MainActivityTestCase {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 UserApiService.Callback callback = (UserApiService.Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(mMockUserService).login(anyString(), anyString(), any(UserApiService.Callback.class));
 
 // act
 onView(withId(R.id.email))
 .perform(ViewActions.typeText("whateverEmail"));
 onView(withId(R.id.password))
 .perform(ViewActions.typeText("whateverPassword"));
 onView(withId(R.id.enter_button))
 .perform(ViewActions.click());
 
 // assert
 onView(withText("Second Page"))
 .check(ViewAssertions.matches(isDisplayed()));
 }
 ...
  • 106. public class MainActivityTest extends MainActivityTestCase {
 ... 
 public void testLoginSuccess() throws Exception {
 // arrange
 doAnswer(new Answer() {
 @Override
 public Object answer(InvocationOnMock invocation) throws Throwable {
 UserApiService.Callback callback = (UserApiService.Callback) invocation.getArguments()[2];
 callback.onSuccess();
 return null;
 }
 }).when(mMockUserService).login(anyString(), anyString(), any(UserApiService.Callback.class));
 
 // act
 onView(withId(R.id.email))
 .perform(ViewActions.typeText("whateverEmail"));
 onView(withId(R.id.password))
 .perform(ViewActions.typeText("whateverPassword"));
 onView(withId(R.id.enter_button))
 .perform(ViewActions.click());
 
 // assert
 onView(withText("Second Page"))
 .check(ViewAssertions.matches(isDisplayed()));
 }
 ... Works!!
  • 107.
  • 108. • sometimes failed • static variable • local storage • not easy to test all stuff • no a best way you can follow frequent problems
  • 109. • Pattern (MVP, DI) • Structure • follow up the android geeks what I learned
  • 110. • mock object called when activity onCreate • UI testing for a fragment with interaction with certain activity • find out the best test sturcture still need to figure out