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

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

    相关文章

    性能测试介绍

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

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

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

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

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

    【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

    目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

    业务中14个需要进行A/B测试的时刻[信息图]

    在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

    hdu 3065 AC自动机 匹配串编号以及出现次数

    题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

    二分最大匹配总结

    HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

    POJ 3057 最大二分匹配+bfs + 二分

    SampleInput35 5XXDXXX...XD...XX...DXXXXX5 12XXXXXXXXXXXXX..........DX.XXXXXXXXXXX..........XXXXXXXXXXXXX5 5XDXXXX.X.DXX.XXD.X.XXXXDXSampleOutput321impossible

    OmniGlue论文详解(特征匹配)

    OmniGlue论文详解(特征匹配) 摘要1. 引言2. 相关工作2.1. 广义局部特征匹配2.2. 稀疏可学习匹配2.3. 半稠密可学习匹配2.4. 与其他图像表示匹配 3. OmniGlue3.1. 模型概述3.2. OmniGlue 细节3.2.1. 特征提取3.2.2. 利用DINOv2构建图形。3.2.3. 信息传播与新的指导3.2.4. 匹配层和损失函数3.2.5. 与Super

    二分图的最大匹配——《啊哈!算法》

    二分图 如果一个图的所有顶点可以被分为X和Y两个集合,并且所有边的两个顶点恰好一个属于X,另外一个属于Y,即每个集合内的顶点没有边相连,那么此图就是二分图。 二分图在任务调度、工作安排等方面有较多的应用。 判断二分图:首先将任意一个顶点着红色,然后将其相邻的顶点着蓝色,如果按照这样的着色方法可以将全部顶点着色的话,并且相邻的顶点着色不同,那么该图就是二分图。 java