Skip to content

Commit

Permalink
added UI teser Espresso.
Browse files Browse the repository at this point in the history
added an automatic Screenshot recorder
added an UI user add test
  • Loading branch information
oliexdev committed Jan 20, 2018
1 parent 8070f5b commit 20fff62
Show file tree
Hide file tree
Showing 5 changed files with 386 additions and 13 deletions.
2 changes: 2 additions & 0 deletions android_app/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ dependencies {
implementation 'android.arch.persistence.room:testing:1.0.0'
implementation 'com.android.support.test:runner:1.0.1'
implementation 'com.android.support.test:rules:1.0.1'
implementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation 'com.android.support.test.espresso:espresso-contrib:3.0.1'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/* Copyright (C) 2018 olie.xdev <olie.xdev@googlemail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.health.openscale.gui;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.runner.screenshot.BasicScreenCaptureProcessor;
import android.support.test.runner.screenshot.ScreenCapture;
import android.support.test.runner.screenshot.Screenshot;
import android.test.suitebuilder.annotation.LargeTest;

import com.health.openscale.R;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.IOException;
import java.util.Locale;

import static android.os.Environment.DIRECTORY_PICTURES;
import static android.os.Environment.getExternalStoragePublicDirectory;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.contrib.DrawerActions.close;
import static android.support.test.espresso.contrib.DrawerActions.open;
import static android.support.test.espresso.contrib.NavigationViewActions.navigateTo;
import static android.support.test.espresso.matcher.ViewMatchers.withId;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class ScreenshotRecorder {
private Context context;

@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class, false , false);

private void setLangauge(String language, String country) {
Locale locale = new Locale(language, country);
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration config = res.getConfiguration();
config.locale = locale;
res.updateConfiguration(config, res.getDisplayMetrics());
}

@Before
public void initRecorder() {
context = InstrumentationRegistry.getTargetContext();
}

@Test
public void captureScreenshots() {
setLangauge("en", "EN");
screenshotRecorder();

setLangauge("de", "DE");
screenshotRecorder();
}

private void screenshotRecorder() {
mActivityTestRule.launchActivity(null);

captureScreenshot("overview");

onView(withId(R.id.drawer_layout))
.perform(open()); // Open Drawer

onView(withId(R.id.navigation_view))
.perform(navigateTo(R.id.nav_graph));

onView(withId(R.id.drawer_layout))
.perform(close()); // Close Drawer

captureScreenshot("graph");

onView(withId(R.id.drawer_layout))
.perform(open()); // Open Drawer

onView(withId(R.id.navigation_view))
.perform(navigateTo(R.id.nav_table));

onView(withId(R.id.drawer_layout))
.perform(close()); // Close Drawer

captureScreenshot("table");

onView(withId(R.id.drawer_layout))
.perform(open()); // Open Drawer

onView(withId(R.id.navigation_view))
.perform(navigateTo(R.id.nav_statistic));

onView(withId(R.id.drawer_layout))
.perform(close()); // Close Drawer

captureScreenshot("statistic");

onView(withId(R.id.drawer_layout))
.perform(open()); // Open Drawer

onView(withId(R.id.navigation_view))
.perform(navigateTo(R.id.nav_settings));

captureScreenshot("settings");

pressBack();

mActivityTestRule.finishActivity();
}

private void captureScreenshot(String name) {
BasicScreenCaptureProcessor processor = new BasicScreenCaptureProcessor();

ScreenCapture capture = Screenshot.capture();
capture.setFormat(Bitmap.CompressFormat.PNG);
capture.setName(name);
try {
String filename = processor.process(capture);

// rename file to remove UUID suffix
File folder = new File(getExternalStoragePublicDirectory(DIRECTORY_PICTURES) + "/screenshots/openScale_" + Locale.getDefault().getLanguage());
if (!folder.exists()) {
folder.mkdir();
}

File from = new File(getExternalStoragePublicDirectory(DIRECTORY_PICTURES) + "/screenshots/" + filename);
File to = new File(getExternalStoragePublicDirectory(DIRECTORY_PICTURES) + "/screenshots/openScale_" + Locale.getDefault().getLanguage() + "/screen_" + name + ".png");
from.renameTo(to);
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/* Copyright (C) 2018 olie.xdev <olie.xdev@googlemail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.health.openscale.gui;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.ViewInteraction;
import android.support.test.espresso.contrib.PickerActions;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.DatePicker;

import com.health.openscale.R;
import com.health.openscale.core.OpenScale;
import com.health.openscale.core.datatypes.ScaleUser;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
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 java.util.Calendar;
import java.util.Locale;

import static android.support.test.espresso.Espresso.onView;
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.replaceText;
import static android.support.test.espresso.action.ViewActions.scrollTo;
import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class UserAddTest {
private static final double DELTA = 1e-15;

private Context context;

@Rule
public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class, false, false);

private void setLangauge(String language, String country) {
Locale locale = new Locale(language, country);
Locale.setDefault(locale);
Resources res = context.getResources();
Configuration config = res.getConfiguration();
config.locale = locale;
res.updateConfiguration(config, res.getDisplayMetrics());
}

@Before
public void initTest() {
context = InstrumentationRegistry.getTargetContext();

// set app language to English
setLangauge("en", "EN");

// Set first start to true to get the user add dialog
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putBoolean("firstStart", true).commit();
}

@After
public void verifyUserAdd() {
ScaleUser user = OpenScale.getInstance(context).getSelectedScaleUser();

assertEquals("test", user.getUserName());
assertEquals(180, user.getBodyHeight());
assertEquals(80, user.getInitialWeight(), DELTA);
assertEquals(60, user.getGoalWeight(), DELTA);

Calendar birthday = Calendar.getInstance();
birthday.setTimeInMillis(0);
birthday.set(Calendar.YEAR, 1990);
birthday.set(Calendar.MONTH, Calendar.JANUARY);
birthday.set(Calendar.DAY_OF_MONTH, 19);
birthday.set(Calendar.HOUR_OF_DAY, 0);

assertEquals(birthday.getTime().getTime(), user.getBirthday().getTime());

Calendar goalDate = Calendar.getInstance();
goalDate.setTimeInMillis(0);
goalDate.set(Calendar.YEAR, 2018);
goalDate.set(Calendar.MONTH, Calendar.JANUARY);
goalDate.set(Calendar.DAY_OF_MONTH, 31);
goalDate.set(Calendar.HOUR_OF_DAY, 0);

assertEquals(goalDate.getTime().getTime(), user.getGoalDate().getTime());
}

@Test
public void userAddTest() {
mActivityTestRule.launchActivity(null);

ViewInteraction editText = onView(
allOf(withId(R.id.txtUserName),
childAtPosition(
allOf(withId(R.id.rowUserName),
childAtPosition(
withId(R.id.tableUserData),
0)),
1)));
editText.perform(scrollTo(), click());

ViewInteraction editText2 = onView(
allOf(withId(R.id.txtUserName),
childAtPosition(
allOf(withId(R.id.rowUserName),
childAtPosition(
withId(R.id.tableUserData),
0)),
1)));
editText2.perform(scrollTo(), replaceText("test"), closeSoftKeyboard());

ViewInteraction editText3 = onView(
allOf(withId(R.id.txtBodyHeight),
childAtPosition(
allOf(withId(R.id.rowBodyHeight),
childAtPosition(
withId(R.id.tableUserData),
1)),
1)));
editText3.perform(scrollTo(), replaceText("180"), closeSoftKeyboard());

onView(withId(R.id.txtBirthday)).perform(click());
onView(withClassName(Matchers.equalTo(DatePicker.class.getName()))).perform(PickerActions.setDate(1990, 1, 19));
onView(withId(android.R.id.button1)).perform(click());

ViewInteraction editText5 = onView(
allOf(withId(R.id.txtInitialWeight),
childAtPosition(
allOf(withId(R.id.tableRowInitialWeight),
childAtPosition(
withId(R.id.tableUserData),
5)),
1)));
editText5.perform(scrollTo(), replaceText("80"), closeSoftKeyboard());

ViewInteraction editText6 = onView(
allOf(withId(R.id.txtGoalWeight),
childAtPosition(
allOf(withId(R.id.rowGoalWeight),
childAtPosition(
withId(R.id.tableUserData),
6)),
1)));
editText6.perform(scrollTo(), replaceText("60"), closeSoftKeyboard());

onView(withId(R.id.txtGoalDate)).perform(click());
onView(withClassName(Matchers.equalTo(DatePicker.class.getName()))).perform(PickerActions.setDate(2018, 1, 31));
onView(withId(android.R.id.button1)).perform(click());

ViewInteraction button3 = onView(
allOf(withId(R.id.btnOk),
childAtPosition(
childAtPosition(
withClassName(is("android.widget.LinearLayout")),
1),
2)));
button3.perform(scrollTo(), click());
}

private static Matcher<View> childAtPosition(
final Matcher<View> parentMatcher, final int position) {

return new TypeSafeMatcher<View>() {
@Override
public void describeTo(Description description) {
description.appendText("Child at position " + position + " in parent ");
parentMatcher.describeTo(description);
}

@Override
public boolean matchesSafely(View view) {
ViewParent parent = view.getParent();
return parent instanceof ViewGroup && parentMatcher.matches(parent)
&& view.equals(((ViewGroup) parent).getChildAt(position));
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ private boolean validateInput()
public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {
Calendar cal = Calendar.getInstance();
cal.set(selectedYear, selectedMonth, selectedDay, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
birthday = cal.getTime();
txtBirthday.setText(dateFormat.format(birthday));
}
Expand All @@ -216,6 +217,7 @@ public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int
public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {
Calendar cal = Calendar.getInstance();
cal.set(selectedYear, selectedMonth, selectedDay, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
goal_date = cal.getTime();
txtGoalDate.setText(dateFormat.format(goal_date));
}
Expand Down
Loading

0 comments on commit 20fff62

Please sign in to comment.