显示空闲链表和隐式空闲链表_使用空闲资源添加Espresso UI测试

显示空闲链表和隐式空闲链表

You may want to read the Spanish version of this article in Droid-Latam’s publication

您可能需要阅读Droid-Latam出版物中的西班牙语版本

Espresso is the framework we use while writing UI tests for our Android apps. In general terms its use is quite easy, however, writing UI tests when some synchronization process (i.e querying data from a remote datasource) is made within the app, may be tedious because Espresso needs to know when the synchronization ends (the app is idle). This is when working with Idling Resources comes to the context.

Espresso是我们在为Android应用编写UI测试时使用的框架。 一般来说,它的使用非常容易,但是,当在应用程序内进行某些同步过程( 即从远程数据源查询数据 )时编写UI测试可能很乏味,因为Espresso需要知道同步何时结束( 应用程序处于空闲状态) )。 这是与空闲资源一起使用时的上下文。

Imagine we are UI testing a screen that has a list of something, then the consume of a get API endpoint needs to be done, and we have to wait for the API response, populate the list with each item.

想象一下,我们正在UI测试一个包含一系列内容的屏幕,然后需要完成get API端点的消耗,并且我们必须等待API响应,并在列表中填充每个项目。

Image for post
The screen we want to UI test
我们要进行UI测试的屏幕

This process (getting, loading and displaying the data)may take from some milliseconds up to a couple of seconds. Espresso doesn’t really know when our app is idle because it only sees 15 ms in the future, then if the response takes more than this the UI test will fail.

此过程(获取,加载和显示数据)可能需要几毫秒到几秒钟的时间。 Espresso并不真正知道我们的应用何时处于空闲状态,因为它将来只会看到15毫秒 ,如果响应所花费的时间超过此时间,则UI测试将失败。

Espresso provides a container class into which we can place our app’s idling resources (IdlingRegistry) that introduces minimal overhead to the app, and Android Devs team provides a recommended approach as follows:

Espresso提供了一个容器类,我们可以在其中放置应用程序的空闲资源(IdlingRegistry),从而将应用程序的开销降到最低, Android Devs团队提供了一种推荐的方法 ,如下所示:

The idea is to perform only the registration and unregistration operations in our tests classes and placing the idling resource logic itself in our app’s production code, which means that we have to create our idling resource “marker” within our production code, then before the app calls the api endpoint we set a mark indicating espresso that the process is starting and just after we have the result we let espresso know about it, then it can continue with the test after all data is obtained.

这个想法是仅在测试类中执行注册和注销操作,并将空闲资源逻辑本身放置在应用程序的生产代码中,这意味着我们必须在生产代码中然后在应用程序之前创建空闲资源“标记”调用api端点时,我们设置一个标记来指示espresso该过程正在开始,并且在获得结果后,我们立即告知espresso,然后在获取所有数据后继续进行测试。

一步步 (Step by Step)

Firstly, register and unregister the idling resources within @Before and @After test methods respectively:

首先,分别在@Before@After测试方法中注册和注销空闲资源:

@LargeTest
@RunWith(AndroidJUnit4::class)
class HomeFragmentUITest {


    @get:Rule
    val activityTestRule = ActivityScenarioRule(MainActivity::class.java)


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


    @After
    fun tearDown() {
        IdlingRegistry.getInstance().unregister(EspressoIdlingResource.countingIdlingResource)
    }


    @Test
    fun initial_state_home_screen_UI_test() {
        activityTestRule.scenario.moveToState(Lifecycle.State.RESUMED)
        onView(withId(R.id.home_photos_progress_container)).check(matches(not(isDisplayed())))
        onView(withId(R.id.home_photos_list)).check(matches(isDisplayed()))
    }
}

Secondly, creates the IdlingResource (EspressoIdlingResource), and for this case we use a CountingIdlingResource, that comes with Espresso and lets us call increment each time we start a task and decrement when it finishes. That way we can control more than one task running concurrently. This resource is placed within a production package, not androidTest package:

其次,创建IdlingResource( EspressoIdlingResource ),在这种情况下,我们使用Espresso附带的CountingIdlingResource ,让我们在每次启动任务时调用递增,在任务完成时递减。 这样,我们可以控制多个并发运行的任务。 此资源放置在生产包中,而不是androidTest包中:

package co.cdmunoz.nasaroverphotos.utils.test


import androidx.test.espresso.idling.CountingIdlingResource


object EspressoIdlingResource {


    private const val RESOURCE = "GLOBAL"


    @JvmField
    val countingIdlingResource = CountingIdlingResource(RESOURCE)


    fun increment() = countingIdlingResource.increment()


    fun decrement() {
        if (!countingIdlingResource.isIdleNow) {
            countingIdlingResource.decrement()
        }
    }
}

Finally, call increment() and decrement() methods within our production code:

最后,在我们的生产代码中调用增量()减量()方法:

//HomeFragment logic and methods
//Calls increment before the query to API
private fun initViewModels() {
        if (null == photosViewModel) {
            //creates viewModel
            //.....
            EspressoIdlingResource.increment()
            photosViewModel?.loadData()
        }
    }
private fun initObservers() {
        photosViewModel?.getPhotos()?.observe(viewLifecycleOwner, Observer { result ->
            when (result) {
                is Result.Success -> {
                    renderList(result.data)
                    EspressoIdlingResource.decrement()
                    binding.homePhotosProgressContainer.visibility = View.GONE
                    binding.homePhotosList.visibility = View.VISIBLE
                }
                is Result.InProgress -> {
                    //InProgress logic
                }
                is Result.Error -> {
                    //Error logic
                }
            }
        })
}

And this is all, now we have the chance to UI test with Espresso screens that have long process using IdlingResources.

这就是全部,现在我们有机会使用EdpressResources对Espresso屏幕进行UI测试,该过程需要很长时间。

Remember that we can use Custom Rules when repetitive tasks are being written within our tests, then you can check this article that shows how to do it easily.

请记住,当在测试中编写重复性任务时,我们可以使用“自定义规则”,然后您可以查看本文,该文章显示了如何轻松地做到这一点

在生产代码中闲置资源? (Idling Resources in the Production Code?)

To finish, you may be asking yourself: should I use Idling Resources in our production code? And to answer the question I’d like to paraphrase Jose Alcérreca from Android team:

最后,您可能会问自己: 我应该在生产代码中使用空闲资源吗? 并回答我想从Android团队解释JoseAlcérreca的问题:

On the one hand, they’re very easy to use and they do make your code more testable. On the other hand, you’re adding code to an app that will be run by potentially millions of users but will do… nothing.If you go this route, you should limit the negative effect in production. For example, if you are using a CountingIdlingResource from an object, create different versions of this object for debug and release (or for different flavors). The released version should do nothing:

一方面,它们非常易于使用,并且确实使您的代码更具可测试性。 另一方面,您正在向可能由数百万个用户运行的应用程序添加代码,但实际上却无能为力。如果采用这种方法,则应限制生产中的负面影响。 例如,如果您使用某个对象的CountingIdlingResource,则可以创建该对象的不同版本以进行调试和发布(或使用不同的样式)。 发布的版本不应执行任何操作:

object EspressoIdlingResource {


    fun increment() { // NO-OP }


    fun decrement() { // NO-OP }
}

All the code within an actual project can be found in this branch of a repo I’ve been sharing with you.

实际项目中的所有代码都可以我一直在与您共享的仓库的此分支中找到。

Also, you may refer this codelab and this article with some examples from Android Developers for more information and practical examples about Espresso.

另外,您可以参考此代码实验室和本文以及Android开发人员提供的一些示例以获取有关Espresso的更多信息和实用示例。

翻译自: https://medium.com/swlh/adding-espresso-ui-tests-with-idling-resources-c87d9fc2cce7

显示空闲链表和隐式空闲链表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值