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
import androidx.test.espresso.NoMatchingViewException
import androidx.test.espresso.ViewAction
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers
@ -9,7 +9,19 @@ fun ViewInteraction.isDisplayed(): Boolean {
try {
check(matches(ViewMatchers.isDisplayed()))
return true
} catch (e: NoMatchingViewException) {
} catch (e: Throwable) {
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.rule.ActivityTestRule
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.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.utils.HardLimits
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.isRunningTest
import org.hamcrest.CoreMatchers.allOf
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.hamcrest.Matchers
import org.hamcrest.TypeSafeMatcher
import org.junit.Assert
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -65,26 +77,27 @@ adb shell settings put global animator_duration_scale 0 &
@Test
fun setupWizardActivityTest() {
Assert.assertTrue(isRunningTest())
// Welcome page
onView(withId(R.id.next_button)).perform(click())
// Language selection
onView(withText("English")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
// Agreement page
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
var askButton = onView(withText("Ask for permission"))
if (askButton.isDisplayed()) {
askButton.perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
}
// Store permission
askButton = onView(withText("Ask for permission"))
if (askButton.isDisplayed()) {
askButton.perform(scrollTo(), click())
onView(withText("OK")).perform(click())
onView(withId(R.id.next_button)).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
}
// Units selection
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())
// Age selection
onView(withText("Adult")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
// Insulin selection
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
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
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
onView(withTagValue(Matchers.`is`("LP_DIA"))).perform(scrollTo(), ViewActions.replaceText("6.0"))
// Local profile - IC
@ -140,7 +153,7 @@ adb shell settings put global animator_duration_scale 0 &
.perform(scrollTo(), click())
onView(allOf(withId(R.id.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
askButton = onView(withText("Do Profile Switch"))
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(Matchers.allOf(withText("OK"), isDisplayed())).perform(click())
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
onView(withText("Virtual Pump")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
// APS
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
onView(withText("Closed Loop")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
// Loop
askButton = onView(withText("Enable loop"))
if (askButton.isDisplayed()) {
askButton.perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
}
// Sensitivity
onView(withText("Sensitivity Oref1")).perform(scrollTo(), click())
onView(withId(R.id.next_button)).perform(click())
onView(withId(R.id.next_button)).waitAndPerform(click())
// Objectives
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(

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.objectives.Objective.ExamTask
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
@ -217,6 +218,7 @@ class ObjectivesFragment : Fragment() {
scrollToCurrentObjective()
startUpdateTimer()
RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
} else {
// move out of UI thread
Thread {
@ -234,6 +236,7 @@ class ObjectivesFragment : Fragment() {
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
SystemClock.sleep(1000)
RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
SystemClock.sleep(100)
scrollToCurrentObjective()
} else {
@ -254,6 +257,7 @@ class ObjectivesFragment : Fragment() {
scrollToCurrentObjective()
startUpdateTimer()
RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
} else
// move out of UI thread
Thread {
@ -270,6 +274,7 @@ class ObjectivesFragment : Fragment() {
RxBus.send(EventNtpStatus(MainApp.gs(R.string.success), 100))
SystemClock.sleep(1000)
RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
SystemClock.sleep(100)
scrollToCurrentObjective()
} else {
@ -284,12 +289,14 @@ class ObjectivesFragment : Fragment() {
objective.startedOn = 0
scrollToCurrentObjective()
RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
}
}
holder.unFinish.setOnClickListener {
objective.accomplishedOn = 0
scrollToCurrentObjective()
RxBus.send(EventObjectivesUpdateGui())
RxBus.send(EventSWUpdate(false))
}
if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted && objective.specialActionEnabled()) {
// 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.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.isRunningTest
import org.slf4j.LoggerFactory
import java.util.*
import kotlin.math.PI
@ -54,7 +55,7 @@ object RandomBgPlugin : PluginBase(PluginDescription()
}
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) {

View file

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

View file

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

View file

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

View file

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