test improvements, bug fixes

This commit is contained in:
Milos Kozak 2019-12-12 21:37:09 +01:00
parent 44e3a15d47
commit 119f9f4f13
8 changed files with 76 additions and 24 deletions

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps package info.nightscout.androidaps
import androidx.test.espresso.NoMatchingViewException import androidx.test.espresso.ViewAction
import androidx.test.espresso.ViewInteraction import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers
@ -9,7 +9,19 @@ fun ViewInteraction.isDisplayed(): Boolean {
try { try {
check(matches(ViewMatchers.isDisplayed())) check(matches(ViewMatchers.isDisplayed()))
return true return true
} catch (e: NoMatchingViewException) { } catch (e: Throwable) {
return false return false
} }
} }
fun ViewInteraction.waitAndPerform(viewActions: ViewAction): ViewInteraction? {
val startTime = System.currentTimeMillis()
while (!isDisplayed()) {
Thread.sleep(100)
if (System.currentTimeMillis() - startTime >= 5000) {
throw AssertionError("View not visible after 5000 milliseconds")
}
}
return perform(viewActions)
}

View file

@ -14,14 +14,26 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest import androidx.test.filters.LargeTest
import androidx.test.rule.ActivityTestRule import androidx.test.rule.ActivityTestRule
import androidx.test.rule.GrantPermissionRule import androidx.test.rule.GrantPermissionRule
import info.nightscout.androidaps.data.Profile
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
import info.nightscout.androidaps.plugins.source.RandomBgPlugin
import info.nightscout.androidaps.setupwizard.SetupWizardActivity import info.nightscout.androidaps.setupwizard.SetupWizardActivity
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.SP import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.isRunningTest
import org.hamcrest.CoreMatchers.allOf import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.Description import org.hamcrest.Description
import org.hamcrest.Matcher import org.hamcrest.Matcher
import org.hamcrest.Matchers import org.hamcrest.Matchers
import org.hamcrest.TypeSafeMatcher import org.hamcrest.TypeSafeMatcher
import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -65,26 +77,27 @@ adb shell settings put global animator_duration_scale 0 &
@Test @Test
fun setupWizardActivityTest() { fun setupWizardActivityTest() {
Assert.assertTrue(isRunningTest())
// Welcome page // Welcome page
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).perform(click())
// Language selection // Language selection
onView(withText("English")).perform(scrollTo(), click()) onView(withText("English")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Agreement page // Agreement page
onView(withText("I UNDERSTAND AND AGREE")).perform(scrollTo(), click()) onView(withText("I UNDERSTAND AND AGREE")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Loction permission // Loction permission
var askButton = onView(withText("Ask for permission")) var askButton = onView(withText("Ask for permission"))
if (askButton.isDisplayed()) { if (askButton.isDisplayed()) {
askButton.perform(scrollTo(), click()) askButton.perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
} }
// Store permission // Store permission
askButton = onView(withText("Ask for permission")) askButton = onView(withText("Ask for permission"))
if (askButton.isDisplayed()) { if (askButton.isDisplayed()) {
askButton.perform(scrollTo(), click()) askButton.perform(scrollTo(), click())
onView(withText("OK")).perform(click()) onView(withText("OK")).perform(click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
} }
// Units selection // Units selection
onView(withText("mmol/L")).perform(scrollTo(), click()) onView(withText("mmol/L")).perform(scrollTo(), click())
@ -97,16 +110,16 @@ adb shell settings put global animator_duration_scale 0 &
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).perform(click())
// Age selection // Age selection
onView(withText("Adult")).perform(scrollTo(), click()) onView(withText("Adult")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Insulin selection // Insulin selection
onView(withText("Ultra-Rapid Oref")).perform(scrollTo(), click()) onView(withText("Ultra-Rapid Oref")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// BG source selection // BG source selection
onView(withText("Random BG")).perform(scrollTo(), click()) onView(withText("Random BG")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Profile selection // Profile selection
onView(withText("Local Profile")).perform(scrollTo(), click()) onView(withText("Local Profile")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Local profile - DIA // Local profile - DIA
onView(withTagValue(Matchers.`is`("LP_DIA"))).perform(scrollTo(), ViewActions.replaceText("6.0")) onView(withTagValue(Matchers.`is`("LP_DIA"))).perform(scrollTo(), ViewActions.replaceText("6.0"))
// Local profile - IC // Local profile - IC
@ -140,7 +153,7 @@ adb shell settings put global animator_duration_scale 0 &
.perform(scrollTo(), click()) .perform(scrollTo(), click())
onView(allOf(withId(R.id.ok), isDisplayed())).perform(click()) onView(allOf(withId(R.id.ok), isDisplayed())).perform(click())
onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Profile switch // Profile switch
askButton = onView(withText("Do Profile Switch")) askButton = onView(withText("Do Profile Switch"))
if (askButton.isDisplayed()) { if (askButton.isDisplayed()) {
@ -148,28 +161,46 @@ adb shell settings put global animator_duration_scale 0 &
onView(allOf(withId(R.id.ok), isDisplayed())).perform(click()) onView(allOf(withId(R.id.ok), isDisplayed())).perform(click())
onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click()) onView(Matchers.allOf(withText("OK"), isDisplayed())).perform(click())
while (ProfileFunctions.getInstance().profile == null) SystemClock.sleep(100) while (ProfileFunctions.getInstance().profile == null) SystemClock.sleep(100)
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
} }
// Pump // Pump
onView(withText("Virtual Pump")).perform(scrollTo(), click()) onView(withText("Virtual Pump")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// APS // APS
onView(withText("OpenAPS SMB")).perform(scrollTo(), click()) onView(withText("OpenAPS SMB")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Open Closed Loop // Open Closed Loop
onView(withText("Closed Loop")).perform(scrollTo(), click()) onView(withText("Closed Loop")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Loop // Loop
askButton = onView(withText("Enable loop")) askButton = onView(withText("Enable loop"))
if (askButton.isDisplayed()) { if (askButton.isDisplayed()) {
askButton.perform(scrollTo(), click()) askButton.perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
} }
// Sensitivity // Sensitivity
onView(withText("Sensitivity Oref1")).perform(scrollTo(), click()) onView(withText("Sensitivity Oref1")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click()) onView(withId(R.id.next_button)).waitAndPerform(click())
// Objectives // Objectives
onView(allOf(withText("Start"), isDisplayed())).perform(scrollTo(), click()) onView(allOf(withText("Start"), isDisplayed())).perform(scrollTo(), click())
onView(withId(R.id.finish_button)).waitAndPerform(click())
// Verify settings
Assert.assertEquals(Constants.MMOL, ProfileFunctions.getSystemUnits())
Assert.assertEquals(17.0, HardLimits.maxBolus(), 0.0001) // Adult
Assert.assertTrue(RandomBgPlugin.isEnabled(PluginType.BGSOURCE))
Assert.assertTrue(LocalProfilePlugin.isEnabled(PluginType.PROFILE))
val p = ProfileFunctions.getInstance().profile
Assert.assertNotNull(p)
Assert.assertEquals(2.0, p!!.ic, 0.0001)
Assert.assertEquals(3.0 * Constants.MMOLL_TO_MGDL, p.isfMgdl, 0.0001)
Assert.assertEquals(1.1, p.getBasalTimeFromMidnight(0), 0.0001)
Assert.assertEquals(6.0 * Constants.MMOLL_TO_MGDL, p.targetLowMgdl, 0.0001)
Assert.assertTrue(VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP))
Assert.assertTrue(OpenAPSSMBPlugin.getPlugin().isEnabled(PluginType.APS))
Assert.assertTrue(LoopPlugin.getPlugin().isEnabled(PluginType.LOOP))
Assert.assertTrue(SensitivityOref1Plugin.getPlugin().isEnabled(PluginType.SENSITIVITY))
Assert.assertTrue(ObjectivesPlugin.objectives[0].isStarted)
} }
private fun childAtPosition( private fun childAtPosition(

View file

@ -28,6 +28,7 @@ import info.nightscout.androidaps.plugins.constraints.objectives.events.EventNtp
import info.nightscout.androidaps.plugins.constraints.objectives.events.EventObjectivesUpdateGui import info.nightscout.androidaps.plugins.constraints.objectives.events.EventObjectivesUpdateGui
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective.ExamTask import info.nightscout.androidaps.plugins.constraints.objectives.objectives.Objective.ExamTask
import info.nightscout.androidaps.receivers.NetworkChangeReceiver import info.nightscout.androidaps.receivers.NetworkChangeReceiver
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
@ -217,6 +218,7 @@ class ObjectivesFragment : Fragment() {
scrollToCurrentObjective() scrollToCurrentObjective()
startUpdateTimer() startUpdateTimer()
RxBus.send(EventObjectivesUpdateGui()) RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
} else { } else {
// move out of UI thread // move out of UI thread
Thread { Thread {
@ -234,6 +236,7 @@ class ObjectivesFragment : Fragment() {
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100)) RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
SystemClock.sleep(1000) SystemClock.sleep(1000)
RxBus.send(EventObjectivesUpdateGui()) RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
SystemClock.sleep(100) SystemClock.sleep(100)
scrollToCurrentObjective() scrollToCurrentObjective()
} else { } else {
@ -254,6 +257,7 @@ class ObjectivesFragment : Fragment() {
scrollToCurrentObjective() scrollToCurrentObjective()
startUpdateTimer() startUpdateTimer()
RxBus.send(EventObjectivesUpdateGui()) RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
} else } else
// move out of UI thread // move out of UI thread
Thread { Thread {
@ -270,6 +274,7 @@ class ObjectivesFragment : Fragment() {
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100)) RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
SystemClock.sleep(1000) SystemClock.sleep(1000)
RxBus.send(EventObjectivesUpdateGui()) RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
SystemClock.sleep(100) SystemClock.sleep(100)
scrollToCurrentObjective() scrollToCurrentObjective()
} else { } else {
@ -284,12 +289,14 @@ class ObjectivesFragment : Fragment() {
objective.startedOn = 0 objective.startedOn = 0
scrollToCurrentObjective() scrollToCurrentObjective()
RxBus.send(EventObjectivesUpdateGui()) RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
} }
} }
holder.unFinish.setOnClickListener { holder.unFinish.setOnClickListener {
objective.accomplishedOn = 0 objective.accomplishedOn = 0
scrollToCurrentObjective() scrollToCurrentObjective()
RxBus.send(EventObjectivesUpdateGui()) RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
} }
if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted && objective.specialActionEnabled()) { if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted && objective.specialActionEnabled()) {
// generate random request code if none exists // generate random request code if none exists

View file

@ -13,6 +13,7 @@ import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.isRunningTest
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.util.* import java.util.*
import kotlin.math.PI import kotlin.math.PI
@ -54,7 +55,7 @@ object RandomBgPlugin : PluginBase(PluginDescription()
} }
override fun specialEnableCondition(): Boolean { override fun specialEnableCondition(): Boolean {
return VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP) && MainApp.engineeringMode return VirtualPumpPlugin.getPlugin().isEnabled(PluginType.PUMP) && (MainApp.engineeringMode || isRunningTest())
} }
override fun handleNewData(intent: Intent) { override fun handleNewData(intent: Intent) {

View file

@ -434,7 +434,7 @@ public class SWDefinition {
add(screenSetupWizard) add(screenSetupWizard)
.add(screenLanguage) .add(screenLanguage)
.add(screenEula) .add(screenEula)
.add(isRunningTest() ? screenPermissionBattery : null) // cannot mock ask battery optimalization .add(isRunningTest() ? null : screenPermissionBattery) // cannot mock ask battery optimalization
.add(screenPermissionBt) .add(screenPermissionBt)
.add(screenPermissionStore) .add(screenPermissionStore)
.add(screenImport) .add(screenImport)
@ -462,7 +462,7 @@ public class SWDefinition {
add(screenSetupWizard) add(screenSetupWizard)
.add(screenLanguage) .add(screenLanguage)
.add(screenEula) .add(screenEula)
.add(isRunningTest() ? screenPermissionBattery : null) .add(isRunningTest() ? null : screenPermissionBattery) // cannot mock ask battery optimalization
.add(screenPermissionBt) .add(screenPermissionBt)
.add(screenPermissionStore) .add(screenPermissionStore)
.add(screenImport) .add(screenImport)
@ -486,7 +486,7 @@ public class SWDefinition {
add(screenSetupWizard) add(screenSetupWizard)
.add(screenLanguage) .add(screenLanguage)
.add(screenEula) .add(screenEula)
.add(isRunningTest() ? screenPermissionBattery : null) .add(isRunningTest() ? null : screenPermissionBattery) // cannot mock ask battery optimalization
.add(screenPermissionStore) .add(screenPermissionStore)
.add(screenImport) .add(screenImport)
.add(screenUnits) .add(screenUnits)

View file

@ -187,7 +187,7 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity {
return page; return page;
page++; page++;
} }
return currentWizardPage; return Math.min(currentWizardPage, screens.size() -1);
} }
private int previousPage() { private int previousPage() {
@ -197,7 +197,7 @@ public class SetupWizardActivity extends NoSplashAppCompatActivity {
return page; return page;
page--; page--;
} }
return currentWizardPage; return Math.max(currentWizardPage, 0);
} }
@Override @Override

View file

@ -3,7 +3,7 @@ package info.nightscout.androidaps.utils
@Synchronized @Synchronized
fun isRunningTest(): Boolean { fun isRunningTest(): Boolean {
return try { return try {
Class.forName("android.support.test.espresso.Espresso") Class.forName("androidx.test.espresso.Espresso")
true true
} catch (e: ClassNotFoundException) { } catch (e: ClassNotFoundException) {
false false

View file

@ -13,6 +13,7 @@
android:orientation="horizontal"> android:orientation="horizontal">
<ImageButton <ImageButton
android:id="@+id/sw_exit"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"