浓缩摘要_测试浓缩咖啡匹配器

2023-11-07 13:59

本文主要是介绍浓缩摘要_测试浓缩咖啡匹配器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

浓缩摘要

If you are using instrumentation tests in your Android app, it is likely that you are using Espresso— allowing you to define expectations about your app screens and how to interact with them.

如果您在Android应用程序中使用检测测试,则很可能是在使用Espresso允许您定义对应用程序屏幕以及如何与之交互的期望。

During your day-by-day as a developer you will eventually implement some custom views. However, Espresso won’t have the ability to assert the specific behaviors of your custom view out of the box. To make it possible you will have to create your own Espresso matchers. In this article I want to show you how to create a simple Matcher and how to run tests for it in the JVM.

在作为开发人员的日常工作中, 最终将实现一些自定义视图 。 但是, Espresso无法开箱即用地声明您的自定义视图的特定行为。 为了使之成为可能,您将必须创建自己的Espresso匹配器。 在本文中, 我想向您展示如何创建一个简单的Matcher以及如何在JVM中对其运行测试。

The example we will follow is the implementation of a custom Button that has a loading state. I will break it down into 3 steps: naive implementation of the LoadingButton , creation of an appropriate Matcher and the test for that Matcher . At the end I will just showcase a simple usage of our new tested Matcher.

我们将遵循的示例是具有加载状态的自定义Button的实现。 我将它分解为3个步骤:天真实施的LoadingButton ,适当的创建Matcher和测试该Matcher 。 最后,我将展示新测试的Matcher的简单用法

Image for post
Image for post
The `LoadingButton` in non-loading and loading states
`LoadingButton`处于非加载和加载状态
  1. Creating the LoadingButton

    创建 LoadingButton

For the sake of simplicity I’m not going to focus on the implementation of the LoadingButton. The only relevant part is that we would have a setter/getter for the loading state.

为了简单起见,我将不着重于LoadingButton.的实现LoadingButton. 唯一相关的部分是,我们将为加载状态 setter/getter一个setter/getter

package com.example.uiimport android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatButtonclass LoadingButton @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : AppCompatButton(context, attrs, defStyleAttr) {var isLoading: Boolean = falseset(value) {// make the button show the loading state....field = value}}

2. Creating the WithButtonLoading Matcher

2.创建 WithButtonLoading 匹配器

When creating a custom Matcher for a custom property of your View you should extend a BoundedMatcher<T, S extends T> . When extending it you will have to override two methods:

View的自定义属性创建自定义Matcher ,应扩展BoundedMatcher<T, S extends T> 。 扩展它时,您将必须重写两个方法:

  • describeTo(description: Description) — here you should add a relevant message to description so that you can understand better when this matcher assertion fails.

    describeTo(description: Description) -在此处应在description添加一条相关消息,以便在此匹配器断言失败时可以更好地理解。

  • matchesSafely(item: S): Boolean — you should return a Boolean stating whether or not the given item respects your logic.

    matchesSafely(item: S): Boolean —您应该返回一个Boolean说明给定item是否符合您的逻辑。

In our example we would do as follows:

在我们的示例中,我们将执行以下操作:

package com.example.testingimport android.view.View
import androidx.test.espresso.matcher.BoundedMatcher
import com.example.ui.LoadingButton
import org.hamcrest.Descriptioninternal class WithButtonLoadingMatcher :BoundedMatcher<View, LoadingButton>(LoadingButton::class.java) {override fun describeTo(description: Description) {description.appendText("with button in loading state")}override fun matchesSafely(item: LoadingButton): Boolean = item.isLoading
}

In this case we would use describeTo to describe our component (a button in a loading state) and the matchesSafely to assert that the given item is in the desired loading state.

在这种情况下,我们将使用describeTo描述我们的组件(处于加载状态的按钮),然后使用matchesSafely断言给定item处于所需的加载状态。

An important point is that I actually made this class internal as this exposes an implementation detail. It is an observed good practice on Espresso matchers to have public wrappers of the internal matchers that provide friendlier/more readable APIs.

重要的一点是,我实际上使此类成为internal类,因为这暴露了实现细节。 在Espresso匹配器上,观察到的良好做法是使用内部匹配器的公共包装程序来提供更友好/更易读的API。

We would then define a public ButtonMatchers that provides methods to create matchers that check if the button is loading or not loading.

然后,我们将定义一个公共ButtonMatchers ,它提供用于创建匹配器的方法,以检查按钮是否正在加载。

package com.example.testing.internalimport android.view.View
import org.hamcrest.CoreMatchers.not
import org.hamcrest.Matcherobject ButtonMatchers {fun isLoading(): Matcher<View> = WithButtonLoadingMatcher()fun isNotLoading(): Matcher<View> = not(WithButtonLoadingMatcher())
}

3. Creating the Test

3.创建测试

In order to test this matcher in with a fast approach and with no need to run instrumentation tests, we will leverage FragmentScenario which are able to run on top of JVM. This will create reliable and fast tests when compared with the instrumentation tests.

为了以一种快速的方法来测试此匹配器,并且无需运行测试,我们将利用能够在JVM之上运行的FragmentScenario 。 与仪器测试相比,这将创建可靠且快速的测试。

The idea is that we will use FragmentScenario + Roboelectrict to launch a Fragment that inflates our LoadingButton , so that we can interact with it and perform assertions regarding the Matcher behavior.

这个想法是,我们将使用FragmentScenario + Roboelectrict启动一个使我们的LoadingButton膨胀的Fragment ,以便我们可以与它进行交互并执行有关Matcher行为的断言。

Below you can see that we are testing the behavior of ButtonMatchers.isLoading matcher: if the Matcher behaves correctly when the button is loading and not loading.

在下面,您可以看到我们正在测试ButtonMatchers.isLoading匹配器的行为:如果在加载和不加载按钮时Matcher行为正确。

package com.example.testingimport androidx.test.espresso.Espresso.onView
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.example.testing.ButtonMatchers.isLoading
import com.example.testing.scenario.launchViewInFragment
import com.example.ui.LoadingButton
import junit.framework.AssertionFailedError
import org.hamcrest.CoreMatchers.instanceOf
import org.junit.Assert.assertThrows
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config@Config(sdk = [28])
@RunWith(AndroidJUnit4::class)
class ButtonMatchersTest {@Testfun whenButtonIsLoading_isLoadingMatcher_ShouldNotThrowException() {launchViewInFragment {LoadingButton(context).apply { isLoading = true }}onView(instanceOf(LoadingButton::class.java)).check(matches(isLoading()))}@Testfun whenButtonIsNotLoading_isLoadingMatcher_ShouldThrowException() {launchViewInFragment {LoadingButton(context).apply { isLoading = false }}assertThrows(AssertionFailedError::class.java) {onView(instanceOf(LoadingButton::class.java)).check(matches(isLoading()))}}
}

The magic happens on launchViewInFragment , which takes a function that creates the View that will be inflated in the Fragment .

魔术发生在launchViewInFragment ,它采用了一个创建将在Fragment launchViewInFragmentView的函数。

The internals of launchViewInFragment make use of FragmentScenario to setup and launch the test.

launchViewInFragment的内部使用FragmentScenario来设置和启动测试。

package com.example.testing.scenarioimport android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.testing.FragmentScenario
import androidx.fragment.app.testing.launchFragmentInContainerinternal fun launchViewInFragment(instantiate: ViewBuilder.() -> View?): FragmentScenario<Fragment> =launchFragmentInContainer(instantiate = { ViewHostFragment(instantiate) })/*** An empty [Fragment]. This [Fragment] is used to host a [View] in [launchViewInFragment].** @see [launchViewInFragment] for more details.*/
internal class ViewHostFragment constructor(private val viewFactory: ViewBuilder.() -> View?
) : Fragment() {override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {val args = ViewBuilder(requireContext(), inflater, container, savedInstanceState)return viewFactory(args)}
}internal data class ViewBuilder internal constructor(val context: Context,val inflater: LayoutInflater,val container: ViewGroup? = null,val savedInstanceState: Bundle? = null
)

If we then run our tests and, the output on Android Studio will be the following:

如果然后运行测试,则Android Studio上的输出将如下所示:

Image for post

You can see that it has a initial overheard time spent, but after that the tests run really fast. And the more tests you have the less the overhead will be noticeable in the full test run time.

您可以看到它有一个最初的听说时间,但是之后测试运行得非常快。 而且您拥有的测试越多,在整个测试运行时间内的开销就越小。

To finalize I just wanted to briefly show how we would use our new Matchers in an instrumentation test. In this example, we assume the button loading state is toggled everytime you click it. You can see the matchers being used on the assertButtonIsLoading and assertButtonIsNotLoading .

最后,我只想简单地展示一下如何在仪器测试中使用新的Matchers 。 在此示例中,我们假设每次单击按钮时都会切换按钮的加载状态。 您可以看到在assertButtonIsLoadingassertButtonIsNotLoading上使用的匹配器。

package com.example.matchersimport androidx.test.core.app.launchActivity
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.example.testing.internal.ButtonMatchers.isLoading
import com.example.testing.internal.ButtonMatchers.isNotLoadingimport org.junit.Test
import org.junit.runner.RunWith@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {@Testfun verifyButtonToggleBehavior() {launchActivity<MainActivity>()assertButtonIsNotLoading()clickButton()assertButtonIsLoading()clickButton()assertButtonIsNotLoading()}private fun assertButtonIsLoading() {onView(withId(R.id.loadingButton)).check(matches(isLoading()))}private fun assertButtonIsNotLoading() {onView(withId(R.id.loadingButton)).check(matches(isNotLoading()))}private fun clickButton() {onView(withId(R.id.loadingButton)).perform(click())}
}

You can find a sample project describing this example here.

您可以在此处找到描述此示例示例项目

  • Espresso

    浓咖啡

  • FragmentScenario

    片段场景

  • Creating a CustomViewMatcher by Thiago Lopes Silva

    由Thiago Lopes Silva 创建CustomViewMatcher

翻译自: https://proandroiddev.com/testing-espresso-matchers-1c3c587d7d39

浓缩摘要


http://www.taodudu.cc/news/show-8177388.html

相关文章:

  • JavaScript浓缩咖啡(一)
  • 地面互动投影
  • 什么是地面互动投影
  • 互动投影的有哪些特点及其应用
  • 地面互动投影解决方案
  • 互动投影技术在未来广阔的发展空间
  • 治疗风寒感冒的小偏方
  • PhpStrom 安装后环境配置(502 Bad Gateway 小偏方)
  • 爬虫小偏方系列:robots.txt 快速抓取网站的小窍门
  • 老中医推荐11个治疗咳嗽小偏方
  • 值得收藏的民间小偏方
  • python爬虫解决频繁访问_Python爬虫小偏方:突破登录和访问频率限制,多研究对方不同终端产品...
  • 一些小偏方
  • 爬虫小偏方系列:robots.txt快速抓取网站的小窍门
  • 个人小偏方:对付感冒的十二种偏方
  • c++之搜索算法
  • 高项 真题 问题归纳
  • 关闭vue.js代码规范Eslint,脚手架新版以及旧版,简单方式
  • 自定义脚手架
  • vue脚手架搭建入门精通
  • php脚手架,从零开始搭建自己的前端脚手架(一)
  • 基于QT的汽车销售管理
  • C#窗体 登录实名注册密码找回
  • discuz!3.2设置实名注册的简易方法
  • OKALEIDO解决NFT流动性不足难题,更有创新平台通证分配方案
  • 阿里巴巴2016研发工程师笔试题(四)
  • 基于图论的奖金分配问题
  • Web 前端 之 Vue 脚手架环境的安装搭建/并创建Vue脚手架工程简单整理(内含:国内环境安装搭建 下载速度慢 的简单解决办法)
  • 搭建SpringBoot脚手架工程(2):代码格式化/质量审核/提交检查
  • 满分题库-二级建筑师工程法规考试宝典
  • 这篇关于浓缩摘要_测试浓缩咖啡匹配器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



    http://www.chinasem.cn/article/364101

    相关文章

    Nginx中location实现多条件匹配的方法详解

    《Nginx中location实现多条件匹配的方法详解》在Nginx中,location指令用于匹配请求的URI,虽然location本身是基于单一匹配规则的,但可以通过多种方式实现多个条件的匹配逻辑... 目录1. 概述2. 实现多条件匹配的方式2.1 使用多个 location 块2.2 使用正则表达式

    golang字符串匹配算法解读

    《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

    SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程

    《SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程》本文详细介绍了如何在虚拟机和宝塔面板中安装RabbitMQ,并使用Java代码实现消息的发送和接收,通过异步通讯,可以优化... 目录一、RabbitMQ安装二、启动RabbitMQ三、javascript编写Java代码1、引入

    C++使用栈实现括号匹配的代码详解

    《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

    Nginx设置连接超时并进行测试的方法步骤

    《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接

    关于Gateway路由匹配规则解读

    《关于Gateway路由匹配规则解读》本文详细介绍了SpringCloudGateway的路由匹配规则,包括基本概念、常用属性、实际应用以及注意事项,路由匹配规则决定了请求如何被转发到目标服务,是Ga... 目录Gateway路由匹配规则一、基本概念二、常用属性三、实际应用四、注意事项总结Gateway路由

    如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

    《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

    性能测试介绍

    性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

    字节面试 | 如何测试RocketMQ、RocketMQ?

    字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

    【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

    ✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi