简体   繁体   中英

Clear shared pref data before running any UI test android

I want to clear SharedPreferences before running any test in screen. I am using below code to achieve that but its not working.

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

}

Code to clear the SharedPreferences

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

Below are the articles that I have already gone through

Link

UPDATE

If I put Thread.sleep() right after the InstrumentationRegistry.getInstrumentation().targetContext.clearSharedPrefs() it works. How can I avoid that or is there any better approach?

Your problem can be apply because apply method works async so when you start your next test apply method might still didn't work so I suggest you to try with commit .

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

edit: my example

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

}

I have just tested this myself with a simple counter app and a text view that shows a count after tapping the screen several times.

Here is what I came up with for the setup using the ActivityScenario and an extension function on the Context class as you have also setup

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

}

As you launch the activity and move it to the resumed state where your view is on the screen you can then clear the preferences. After the test runs you move the Activity state to destroyed which finishes the Activity.

According to the docs:

ActivityScenario does't clean up device state automatically and may leave the activity keep running after the test finishes.

Another way to clear your app preferences without Thread.sleep is setting up test rules :

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()
    }
}

This ensure the app clears its preferences before activities are being launched. Simply add the rule to your test:

class HomePage {

    @get:Rule val myTestRule = MyActivityTestRule()

    // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM