1
0
mirror of https://github.com/oliexdev/openScale.git synced 2025-08-27 10:15:00 +02:00

added UI teser Espresso.

added an automatic Screenshot recorder
added an UI user add test
This commit is contained in:
OliE
2018-01-20 06:50:53 +01:00
parent 8070f5b003
commit 20fff62c5b
5 changed files with 386 additions and 13 deletions

View File

@@ -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'
}

View File

@@ -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);
}
}
}

View File

@@ -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));
}
};
}
}

View File

@@ -206,6 +206,7 @@ public class UserSettingsActivity extends Activity {
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));
}
@@ -216,6 +217,7 @@ public class UserSettingsActivity extends Activity {
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));
}

View File

@@ -8,7 +8,7 @@
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/scrollView4" >
android:id="@+id/scrollViewUserData" >
<LinearLayout
android:layout_width="match_parent"
@@ -17,18 +17,19 @@
android:padding="5dp" >
<TableLayout
android:id="@+id/tableUserData"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:stretchColumns="*" >
<TableRow
android:id="@+id/tableRow1"
android:id="@+id/rowUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView1"
android:id="@+id/lblUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_user_name" />
@@ -47,11 +48,12 @@
</TableRow>
<TableRow
android:id="@+id/tableRow2"
android:id="@+id/rowBodyHeight"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/lblBodyHeight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_body_height" />
@@ -67,12 +69,12 @@
</TableRow>
<TableRow
android:id="@+id/tableRow3"
android:id="@+id/rowGender"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView3"
android:id="@+id/lblGender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_gender" />
@@ -102,12 +104,12 @@
</TableRow>
<TableRow
android:id="@+id/tableRow4"
android:id="@+id/rowUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView4"
android:id="@+id/lblUnit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_scale_unit" />
@@ -142,12 +144,12 @@
</TableRow>
<TableRow
android:id="@+id/tableRow5"
android:id="@+id/rowBirthday"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView5"
android:id="@+id/lblBirthday"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_birthday" />
@@ -169,6 +171,7 @@
android:layout_height="wrap_content" >
<TextView
android:id="@+id/lblInitialWeight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_initial_weight" />
@@ -183,11 +186,12 @@
</TableRow>
<TableRow
android:id="@+id/tableRow6"
android:id="@+id/rowGoalWeight"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/lblGoalWeight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_goal_weight" />
@@ -202,12 +206,12 @@
</TableRow>
<TableRow
android:id="@+id/tableRow7"
android:id="@+id/rowGoalDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView7"
android:id="@+id/lblGoalDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label_goal_date" />