Очистите общие предварительные данные перед запуском любого теста пользовательского интерфейса Android.

Я хочу очистить SharedPreferences перед запуском любого теста на экране. Я использую приведенный ниже код для достижения этого, но он не работает.

@RunWith(AndroidJUnit4::class)
class HomePage{

   private lateinit var activityScenario: ActivityScenario<HomeActivity>

   @Before
   fun setUp() {
    IdlingRegistry.getInstance().register(EspressoIdlingResource.countingIdlingResource)

    activityScenario = ActivityScenario.launch(HomeActivity::class.java)

    InstrumentationRegistry.getInstrumentation().targetContext.clearSharedPrefs() 

  }

  @Test
  fun testConditionA(){
    //Do something
   }

  @Test
  fun testConditionB(){
    //Do something
 }

}

Код для очистки SharedPreferences

fun Context.clearSharedPrefs() =
        this.getSharedPreferences("name", Context.MODE_PRIVATE).edit().clear().commit()

Ниже приведены статьи, которые я уже прошел

Ссылка

ОБНОВЛЕНИЕ

Если я поставлю Thread.sleep() сразу после InstrumentationRegistry.getInstrumentation().targetContext.clearSharedPrefs(), это сработает. Как я могу избежать этого или есть лучший подход?


person rupesh    schedule 09.04.2020    source источник


Ответы (3)


Ваша проблема может быть apply, потому что метод apply работает асинхронно, поэтому, когда вы начнете свой следующий тест, метод apply может все еще не работать, поэтому я предлагаю вам попробовать commit.

fun Context.clearSharedPrefs() =
    this.getSharedPreferences("name", Context.MODE_PRIVATE).edit().clear().commit()

редактировать: мой пример

@RunWith(AndroidJUnit4::class)
class HomePage{

private lateinit var activityScenario: ActivityScenario<MainActivity>

@Before
fun setUp() {
    val context = InstrumentationRegistry.getInstrumentation().targetContext;
    context.getSharedPreferences("name", Context.MODE_PRIVATE).edit().clear().commit()
}

@Test
fun testConditionA(){
    val context = InstrumentationRegistry.getInstrumentation().targetContext;
    context.getSharedPreferences("name", Context.MODE_PRIVATE).edit().putBoolean("asd", true).commit()

    val a = context.getSharedPreferences("name", Context.MODE_PRIVATE).getBoolean("asd", false)

    Assert.assertEquals(a, true)
}

@Test
fun testConditionB(){
    val context = InstrumentationRegistry.getInstrumentation().targetContext;
    val a = context.getSharedPreferences("name", Context.MODE_PRIVATE).getBoolean("asd", false);

    Assert.assertEquals(a, false)
}

}

person VolkanSahin45    schedule 09.04.2020
comment
Я изменил приложение для фиксации, но все еще не работает. - person rupesh; 09.04.2020
comment
Можете ли вы проверить запуск метода перед каждым тестом? - person VolkanSahin45; 09.04.2020
comment
Я написал небольшой пример вашего кода, и он сработал - person VolkanSahin45; 09.04.2020
comment
Если я поставлю Thread.sleep() сразу после InstrumentationRegistry.getInstrumentation().targetContext.clearSharedPrefs() , это сработает. Как я могу избежать этого или есть лучший подход? Спасибо за ваш ответ. - person rupesh; 09.04.2020
comment
вы можете попробовать написать clearSharedPrefs как обычную функцию или встроенную функцию, а не функцию расширения - person VolkanSahin45; 09.04.2020
comment
Давайте продолжим обсуждение в чате. - person rupesh; 09.04.2020

Я только что проверил это сам с помощью простого приложения-счетчика и текстового представления, которое показывает счет после нескольких касаний экрана.

Вот что я придумал для настройки, используя ActivityScenario и функцию расширения в классе Context, как вы также настроили

@RunWith(AndroidJUnit4::class)
class AppTest {

    private lateinit var  activityScenario: ActivityScenario<HomeActivity>

    @Before
    fun setup() {

        activityScenario = ActivityScenario.launch(MainActivity::class.java)
        activityScenario.moveToState(Lifecycle.State.RESUMED)

        InstrumentationRegistry.getInstrumentation().targetContext.clearSharedPrefs()
    }

    @After
    fun tearDown(){
        activityScenario.moveToState(Lifecycle.State.DESTROYED)
    }

    @Test
    fun testConditionA(){
        //Do something
    }

    @Test
    fun testConditionB(){
        //Do something
    }

}

Когда вы запускаете действие и переводите его в возобновленное состояние, когда ваш вид находится на экране, вы можете очистить настройки. После запуска теста вы перемещаете состояние Activity в уничтоженное, что завершает действие.

Согласно документам:

ActivityScenario не очищает состояние устройства автоматически и может продолжать работу после завершения теста.

person kandroidj    schedule 09.04.2020
comment
Он решает это, уничтожая Activity после каждого теста. Лучше всего перевести его в возобновленное состояние, потому что это означает, что он находится на экране и активен. - person kandroidj; 09.04.2020
comment
Я делаю activityScenario.close() в @After . Это то же самое, что destroy activity - person rupesh; 09.04.2020

Еще один способ очистить настройки приложения без Thread.sleep — настроить правила тестирования:

class MyActivityTestRule : ActivityTestRule<MyActivity>(MyActivity::class.java, false, true) {

    val preferences = ApplicationProvider.getApplicationContext<Application>()
            .getSharedPreferences(NAME, MODE)

    override fun beforeActivityLaunched() {
        preferences.edit().clear().commit()
        // or ApplicationProvider.getApplicationContext<Application>().clearSharedPrefs()
    }
}

Это гарантирует, что приложение очистит свои настройки перед запуском действий. Просто добавьте правило в свой тест:

class HomePage {

    @get:Rule val myTestRule = MyActivityTestRule()

    // ...
}
person Aaron    schedule 10.04.2020