Source
1. build.gradle(module.app)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dependencies { | |
implementation fileTree(dir: 'libs', include: ['*.jar']) | |
implementation 'com.android.support:appcompat-v7:28.0.0' | |
implementation 'com.android.support.constraint:constraint-layout:1.1.3' | |
testImplementation 'junit:junit:4.12' | |
/*Espresso testing */ | |
androidTestImplementation 'com.android.support.test:runner:1.0.2' | |
androidTestImplementation 'com.android.support.test:rules:1.0.2' | |
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' | |
} | |
//full code of this section | |
//Start from here | |
apply plugin: 'com.android.application' | |
android { | |
compileSdkVersion 28 | |
defaultConfig { | |
applicationId "com.amirul.loginespressotesting" | |
minSdkVersion 15 | |
targetSdkVersion 28 | |
versionCode 1 | |
versionName "1.0" | |
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" | |
} | |
buildTypes { | |
release { | |
minifyEnabled false | |
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | |
} | |
} | |
} | |
dependencies { | |
implementation fileTree(dir: 'libs', include: ['*.jar']) | |
implementation 'com.android.support:appcompat-v7:28.0.0' | |
implementation 'com.android.support.constraint:constraint-layout:1.1.3' | |
testImplementation 'junit:junit:4.12' | |
/*Espresso testing */ | |
androidTestImplementation 'com.android.support.test:runner:1.0.2' | |
androidTestImplementation 'com.android.support.test:rules:1.0.2' | |
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' | |
} | |
//end |
2. MainActivity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.amirul.loginespressotesting; | |
import android.content.Intent; | |
import android.support.v7.app.AppCompatActivity; | |
import android.os.Bundle; | |
import android.text.TextUtils; | |
import android.util.Patterns; | |
import android.view.KeyEvent; | |
import android.view.View; | |
import android.view.inputmethod.EditorInfo; | |
import android.widget.Button; | |
import android.widget.EditText; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
/* | |
* **************************************************************************** | |
* * Created by : Md Amirul Islam on 11/9/2018 at 8.11 PM. | |
* * Email : amirul.csejust@gmail.com | |
* * | |
* * Purpose: To test all element of UI | |
* * | |
* * Last edited by : Md Amirul Islam on 11/11/2018. | |
* * | |
* * Last Reviewed by : <Reviewer Name> on <mm/dd/yy> | |
* **************************************************************************** | |
*/ | |
public class MainActivity extends AppCompatActivity { | |
private EditText mEmailEditText, mPasswordEditText; | |
private TextView show; | |
private Button btnSubmit; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
mEmailEditText = (EditText)findViewById(R.id.etEmailInput); | |
mPasswordEditText = (EditText)findViewById(R.id.etPassInput); | |
mPasswordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { | |
@Override | |
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { | |
if(actionId ==R.id.login || actionId == EditorInfo.IME_NULL){ | |
login(); | |
return true; | |
} | |
return false; | |
} | |
}); | |
btnSubmit = (Button)findViewById(R.id.btnSubmit); | |
btnSubmit.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
login(); | |
} | |
}); | |
} | |
private void login() { | |
/*Reset errors */ | |
mEmailEditText.setError(null); | |
mPasswordEditText.setError(null); | |
/*getting value from email and pass*/ | |
String email = mEmailEditText.getText().toString(); | |
String password = mPasswordEditText.getText().toString(); | |
boolean cancel = false; | |
View focusView = null; | |
/*check for a valid Email*/ | |
if (TextUtils.isEmpty(email)){ | |
mEmailEditText.setError("This field is required"); | |
focusView = mEmailEditText; | |
cancel = true; | |
}else if (!isEmailVaild(email)){ | |
mEmailEditText.setError(getString(R.string.error_invalid_email)); | |
focusView = mEmailEditText; | |
cancel = true; | |
} | |
// Check for a valid password. | |
if (TextUtils.isEmpty(password)) { | |
mPasswordEditText.setError(getString(R.string.error_field_required)); | |
focusView = mPasswordEditText; | |
cancel = true; | |
} else if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) { | |
mPasswordEditText.setError(getString(R.string.error_invalid_password)); | |
focusView = mPasswordEditText; | |
cancel = true; | |
} | |
if (cancel) { | |
focusView.requestFocus(); | |
} else { | |
if (email.equals("amir@gmail.com") && password.equals("123456")) { | |
loginSuccessfully(email); | |
} else { | |
Toast.makeText(getApplicationContext(), getString(R.string.error_login_failed), Toast.LENGTH_SHORT).show(); | |
} | |
} | |
} | |
private boolean isEmailVaild(String email) { | |
return Patterns.EMAIL_ADDRESS.matcher(email).matches(); | |
} | |
private boolean isPasswordValid(String password) { | |
return password.length() > 4; | |
} | |
private void loginSuccessfully(String email) { | |
Intent intent = new Intent(MainActivity.this, Welcome.class); | |
intent.putExtra("email", email); | |
startActivity(intent); | |
finish(); | |
Toast.makeText(getApplicationContext(), getString(R.string.login_successfully), Toast.LENGTH_SHORT).show(); | |
} | |
} | |
//full code : https://github.com/amirul12/loginAndroidEspresso |
3. xml layout of the mainActivity class activity_main.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:background="@drawable/login_bg" | |
tools:context=".MainActivity"> | |
<LinearLayout | |
android:padding="20dp" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_centerVertical="true" | |
android:layout_centerHorizontal="true" | |
android:orientation="vertical"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="20dp" | |
android:gravity="center" | |
android:orientation="vertical"> | |
<ImageView | |
android:layout_width="200dp" | |
android:layout_height="50dp" | |
android:src="@drawable/logo" | |
android:transitionName="logo" /> | |
</LinearLayout> | |
<TextView | |
android:text="Email" | |
android:layout_marginTop="30dp" | |
android:textSize="18dp" | |
android:textColor="#ffffff" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" /> | |
<EditText | |
android:id="@+id/etEmailInput" | |
android:layout_marginTop="10dp" | |
android:hint="Enter Email" | |
android:textColor="#ffffff" | |
android:textColorHint="#A9A9A9" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:layout_marginTop="10dp" | |
android:textSize="18dp" | |
android:text="Password" | |
android:textColor="#ffffff" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" /> | |
<EditText | |
android:id="@+id/etPassInput" | |
android:layout_marginTop="10dp" | |
android:hint="Enter Password" | |
android:textColorHint="#A9A9A9" | |
android:imeActionId="@+id/login" | |
android:imeActionLabel="Login" | |
android:imeOptions="actionUnspecified" | |
android:inputType="textPassword|numberPassword" | |
android:textColor="#ffffff" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" /> | |
<Button | |
android:clickable="true" | |
android:id="@+id/btnSubmit" | |
android:layout_marginTop="10dp" | |
android:text="Submit" | |
android:focusable="true" | |
android:elevation="20dp" | |
android:background="@drawable/button_bg" | |
android:textColor="@android:color/white" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:layout_gravity="center_horizontal" | |
android:gravity="center_horizontal" | |
android:layout_marginTop="20dp" | |
android:id="@+id/show" | |
android:text="show" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" /> | |
</LinearLayout> | |
</RelativeLayout> |
4. welcome Activity and this layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.amirul.loginespressotesting; | |
import android.support.v7.app.AppCompatActivity; | |
import android.os.Bundle; | |
import android.widget.TextView; | |
public class Welcome extends AppCompatActivity { | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_welcome); | |
String welcomeMessage = String.format("Hi %s!", getIntent().getStringExtra("email")); | |
TextView tvEmail = (TextView) findViewById(R.id.tv_welcome); | |
tvEmail.setText(welcomeMessage); | |
} | |
} | |
=================== | |
<?xml version="1.0" encoding="utf-8"?> | |
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context=".Welcome"> | |
<TextView | |
android:id="@+id/tv_welcome" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="center_horizontal" | |
android:text="Welcome" | |
android:textSize="30sp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
</android.support.constraint.ConstraintLayout> | |
5. Testing MainActivity which is Login form .
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.amirul.loginespressotesting; | |
import android.support.annotation.StringRes; | |
import android.support.test.rule.ActivityTestRule; | |
import android.support.test.runner.AndroidJUnit4; | |
import android.view.View; | |
import android.widget.EditText; | |
import org.hamcrest.Description; | |
import org.hamcrest.Matcher; | |
import org.hamcrest.TypeSafeMatcher; | |
import org.junit.After; | |
import org.junit.Before; | |
import org.junit.Rule; | |
import org.junit.Test; | |
import org.junit.runner.RunWith; | |
import static android.provider.Settings.System.getString; | |
import static android.support.test.espresso.Espresso.onView; | |
import static android.support.test.espresso.action.ViewActions.clearText; | |
import static android.support.test.espresso.action.ViewActions.click; | |
import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; | |
import static android.support.test.espresso.action.ViewActions.typeText; | |
import static android.support.test.espresso.assertion.ViewAssertions.matches; | |
import static android.support.test.espresso.matcher.RootMatchers.withDecorView; | |
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; | |
import static android.support.test.espresso.matcher.ViewMatchers.withId; | |
import static android.support.test.espresso.matcher.ViewMatchers.withText; | |
import static org.hamcrest.core.IsNot.not; | |
import static org.junit.Assert.*; | |
/* | |
* **************************************************************************** | |
* * Created by : Md Amirul Islam on 11/9/2018 at 8.11 PM. | |
* * Email : amirul.csejust@gmail.com | |
* * | |
* * Purpose: To test all element of UI | |
* * | |
* * Last edited by : Md Amirul Islam on 11/11/2018. | |
* * | |
* * Last Reviewed by : <Reviewer Name> on <mm/dd/yy> | |
* **************************************************************************** | |
*/ | |
@RunWith(AndroidJUnit4.class) | |
public class MainActivityTest2 { | |
// To launch the mentioned activity under testing | |
@Rule | |
public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<>(MainActivity.class); | |
@Test | |
public void emailIsEmpty() { | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).perform(clearText()); | |
delay(2000); | |
onView(withId(R.id.btnSubmit)).perform(click()); | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).check(matches(withError(getString(R.string.error_field_required)))); | |
delay(2000); | |
} | |
@Test | |
public void passwordIsEmpty() { | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).perform(typeText("email@email.com"), closeSoftKeyboard()); | |
delay(2000); | |
onView(withId(R.id.etPassInput)).perform(clearText()); | |
delay(2000); | |
onView(withId(R.id.btnSubmit)).perform(click()); | |
delay(2000); | |
onView(withId(R.id.etPassInput)).check(matches(withError(getString(R.string.error_field_required)))); | |
delay(2000); | |
} | |
@Test | |
public void emailIsInvalid() { | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).perform(typeText("invalid"), closeSoftKeyboard()); | |
delay(2000); | |
onView(withId(R.id.btnSubmit)).perform(click()); | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).check(matches(withError(getString(R.string.error_invalid_email)))); | |
delay(2000); | |
} | |
@Test | |
public void passwordIsTooShort() { | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).perform(typeText("amir@email.com"), closeSoftKeyboard()); | |
delay(2000); | |
onView(withId(R.id.etPassInput)).perform(typeText("1234"), closeSoftKeyboard()); | |
delay(2000); | |
onView(withId(R.id.btnSubmit)).perform(click()); | |
delay(2000); | |
onView(withId(R.id.etPassInput)).check(matches(withError(getString(R.string.error_invalid_password)))); | |
delay(2000); | |
} | |
@Test | |
public void loginFailed() { | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).perform(typeText("incorrect@email.com"), closeSoftKeyboard()); | |
onView(withId(R.id.etPassInput)).perform(typeText("123456"), closeSoftKeyboard()); | |
delay(2000); | |
onView(withId(R.id.btnSubmit)).perform(click()); | |
onView(withText(getString(R.string.error_login_failed))) | |
.inRoot(withDecorView(not(activityTestRule.getActivity().getWindow().getDecorView()))) | |
.check(matches(isDisplayed())); | |
delay(2000); | |
} | |
@Test | |
public void loginSuccessfully_shouldShowWelcomeMessage() { | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).perform(typeText("amir@gmail.com"), closeSoftKeyboard()); | |
onView(withId(R.id.etPassInput)).perform(typeText("123456"), closeSoftKeyboard()); | |
delay(2000); | |
onView(withId(R.id.btnSubmit)).perform(click()); | |
onView(withId(R.id.tv_welcome)).check(matches(withText("Hi amir@gmail.com!"))); | |
} | |
@Test | |
public void loginSuccessfully_shouldShowToast() { | |
delay(2000); | |
onView(withId(R.id.etEmailInput)).perform(typeText("amir@gmail.com"), closeSoftKeyboard()); | |
onView(withId(R.id.etPassInput)).perform(typeText("123456"), closeSoftKeyboard()); | |
delay(2000); | |
onView(withId(R.id.btnSubmit)).perform(click()); | |
onView(withText(getString(R.string.login_successfully))) | |
.inRoot(withDecorView(not(activityTestRule.getActivity().getWindow().getDecorView()))) | |
.check(matches(isDisplayed())); | |
delay(2000); | |
} | |
private String getString(@StringRes int resourceId) { | |
return activityTestRule.getActivity().getString(resourceId); | |
} | |
private static Matcher<View> withError(final String expected) { | |
return new TypeSafeMatcher<View>() { | |
@Override | |
protected boolean matchesSafely(View item) { | |
if (item instanceof EditText) { | |
return ((EditText)item).getError().toString().equals(expected); | |
} | |
return false; | |
} | |
@Override | |
public void describeTo(Description description) { | |
description.appendText("Not found error message" + expected + ", find it!"); | |
} | |
}; | |
} | |
private void delay(long item) { | |
try { | |
Thread.sleep(item); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
//full code : https://github.com/amirul12/loginAndroidEspresso |