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

Android Testing

  • 1.
  • 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'
 }

  • 6.
  • 8.
    public class MainActivityextends 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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);
 }
 }
  • 14.
  • 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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.
  • 27.
  • 28.
  • 29.
  • 30.
    public class UserServiceTestextends TestCase {
 
 }
  • 31.
    public class UserServiceTestextends TestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 
 // assert
 
 }
 
 }
  • 32.
    public class UserServiceTestextends TestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 
 // assert
 
 }
 
 } test method prefix
  • 33.
    public class UserServiceTestextends TestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 
 // act
 
 // assert
 
 }
 
 }
  • 34.
    public class UserServiceTestextends AndroidTestCase {
 
 public void testLoginSuccess() throws Exception {
 // arrange
 PasswordValidator validator = new PasswordValidator();
 UserService userService = new UserService(getContext(), validator);
 
 // act
 
 // assert
 
 }
 
 }
  • 35.
    public class UserServiceTestextends 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 UserServiceTestextends 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 UserServiceTestextends 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 UserServiceTestextends 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 UserServiceTestextends 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 UserServiceTestextends 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 UserServiceTestextends 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 whenrunning separately(sometimes?)
  • 43.
    • passed whenrunning separately(sometimes?) • but failed running the whole tests
  • 44.
    • passed whenrunning 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 UserServiceTestextends AndroidTestCase {
 
 public void setUp() throws Exception {
 super.setUp();
 clearSharedPref();
 }
 
 private void clearSharedPref() {
 getContext().getSharedPreferences(UserService.SHARED_PREF_NAME, 0)
 .edit().clear().commit();
 }
 ...
  • 47.
  • 48.
  • 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 MainActivityextends 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 MainActivityextends 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() {
 
 }
 });
 }
 
 ... 

  • 57.
  • 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());
 }
  • 66.
  • 67.
  • 68.
    1. 2. 3. public class MainActivityTestextends TestCase {
 
 }
  • 69.
    public class MainActivityTestextends TestCase {
 
 }
  • 70.
    public class MainActivityTestextends ActivityInstrumentationTestCase2<MainActivity> {
 
 public MainActivityTest() {
 super(MainActivity.class);
 } 
 }
  • 71.
    public class MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 someresearch…
  • 86.
    use Dagger2 forDependency Injection
  • 87.
    public class MainActivityextends 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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 MainActivityextends 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
  • 94.
  • 95.
    
 @Provides
 @Singleton
 UserService provideTestUserService(UserApiService userApiService){
 returnmMockUserService;
 } 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){
 returnmMockUserService;
 } 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){
 returnmMockUserService;
 } 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){
 returnmMockUserService;
 } 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){
 returnmMockUserService;
 } 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){
 returnmMockUserService;
 } 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){
 returnmMockUserService;
 } 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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 MainActivityTestextends 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!!
  • 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 objectcalled when activity onCreate • UI testing for a fragment with interaction with certain activity • find out the best test sturcture still need to figure out
  • 111.