Kaspresso:您正在等待的自动测试框架

曾经或正在从事Android自动测试的每个人都知道这是一种痛苦。
您会厌倦大量的任务和问题,因此休假无济于事。 人们甚至因为自动测试而辞职。

痛苦,痛苦和折磨不可避免地导致新事物和美丽事物的出现。 我们试图汇总所有必须采取的措施,并与来自Avito和HH的人员一起努力,创造出可以使您与自动测试的关系变得无比美好和富有成果的东西。

见面: Kaspresso-您正在等待的自动测试框架!



我立即注意到,网络上有两个非常高品质的视频,专用于KaspressoAdbServerKaspresso的辅助,但同时是一个强大而独立的项目):

1. Dmitry Movchan,Eugene Matsyuk-如何开始编写自动测试而不发疯
2. Egor Kournikov-UI测试唯一需要的

他们详细描述了创建库的历史:我们如何从解决一个问题转到解决另一个问题,以及最终发生了什么。 我强烈推荐它。

因此,在本文中,我将仅讨论要点和芯片,以便您可以快速了解此框架的含义以及它要解决的任务。 胆量和细节可以在视频和文档中找到。

为什么我们甚至需要我们自己的框架?


每个开始编写自动测试的开发人员都会不可避免地提出以下问题:

  1. 如何开始编写自动测试?
  2. 选择什么工具?
  3. 如果没有必要的工具怎么办?
  4. 最佳做法是什么?

此外,每个团队都在尝试以自己的方式解决这些问题。 结果,对他们没有一个单一的答案,也无处窥视如何正确地做。 因此,编写和支持自动测试对公司来说是昂贵的,这使自动化的可行性受到质疑。

同时,测试自动化追求良好的目标。 它使您始终可以拥有绿色的随时可用的向导。 这意味着您可以快速推出该版本。
唯一的问题是找到上述问题的答案。 但是对于所有团队来说,它们几乎都是相同的。 那么为什么不自动化他们的解决方案呢?

我们从框架中想要什么?


让我们从框架中稍微透露一下我们的期望。

良好的可读性


默认情况下,只有Espresso库在Android中对我们可用。 当然,还有Appium + Cucumber,从理论上讲,它允许您同时在两个平台上编写测试。 但是社区有信心朝着第一个工具迈进。 我不会描述上述库的所有优缺点:网络上有关于此的信息。 例如,这里是相对较新的链接之一: Appium与Espresso。 选择什么以及如何使用?

所以,意式浓缩咖啡 这不是一个不错的工具,但它的api有点内外。 看一个简单的代码:

@Test fun espressoTest() { onView(allOf(allOf(withId(R.id.espresso), isDescendantOfA(withId(R.id.coffee_variates))), isDescendantOfA(withId(R.id.content)))) .check(matches(withEffectiveVisibility(View.VISIBLE))) } 

您必须考虑弄清楚,对吗?

来自泰国和澳大利亚的众神向我们提供了Kakao库,您可以一目了然地了解您的测试正在发生什么。 这是相同的代码,但使用Kakao:

 @Test fun kakaoTest() { mainScreen { myView.isVisible() } } 

好多了。 但是现在想象一下,您已经自动化了整个测试用例。 代码是什么样的?

 @RunWith(AndroidJUnit4::class) class OpenHomeScreenTest: TestCase() { @Test fun test() { MainScreen() { homeButton.click() } HomeScreen() { title { isVisible() hasAnyText() } } } } 

主要问题是,查看此测试,很难将其与您自动化的测试用例关联起来。 当然,您可以添加日志或类似的东西。 或输入dsl,它会立即改变测试的外观:

 @RunWith(AndroidJUnit4::class) class OpenHomeScreenTest: TestCase() { @Test fun test() { step(“1. Open Home screen”) { MainScreen() { homeButton.click() } } step(“2. Check Home title”) { HomeScreen() { title { isVisible() hasAnyText() } } } } } 

同意,它看起来完全不同。

稳定度


任何用于ui测试的库都会失败。 相同的操作可以成功执行50次,并且在第51次中断时没有明显的原因。 在第52次运行中,一切都恢复了。 这样的“懈怠”会严重破坏您的神经。

我们认为,为什么不尝试拦截Kakao-Espresso的所有动作,并在那里添加旨在处理此类随机错误的其他行为。

这就是Kakao库2.1版诞生的方式,使您可以集成到所有Espresso调用中。

此外,我们创建了自己的拦截器,您可以使用它们来更改拨号对等方的行为,或者例如更改日志。 此外,这些拦截器是可定制的,因此您可以根据需要定制它们。 在码头上阅读更多内容。

具体来说,作为对抗易碎测试的一部分-如果您的某些操作引发异常,则Kaspresso将尝试:

  • 卷动 也许您的视图在屏幕上根本不可见。
  • 删除可能来自上帝的系统对话,知道在哪里。
  • 重复打断电话两秒钟。

通过这些步骤,我们通过易变的测试完全解决了该问题!

记录中


自动测试伴随的主要问题之一是缺少可理解的日志记录,当测试崩溃时,这尤其不够。 坐着,想知道什么和如何落在这里。

由于上述拦截,我们得以构建相当广泛的日志记录系统。

让我们看一个例子:





默认情况下,Kaspresso会记录您的所有操作,选择测试的每个步骤,显示执行时间等。

浓咖啡测试中的完整Adb


最初,adb在Espresso测试中不可用。 是的,有adb shell ,但是功能比完整adb少得多。 但是其中有很多东西可以在测试中派上用场。

我们已经创建了一个单独的AdbServer库,该库将向您的测试返回完整的adb ! 上面的视频详细介绍了我们的战斗方式和过程( )。

使用Android操作系统


卡巴斯基实验室的测试细节使得我们必须在Android OS上进行大量工作:设置一些设置,将文件上传到系统等。所有这些促使我们标准化了系统的所有工作,创建了一组清晰的界面,可通过单个入口点类Device访问

这些接口是什么,它们在做什么? 让我给您看一下Yegor演示文稿中的几张幻灯片:









文档在这里

在后台,主要使用AdbServer和UiAutomator。
但是! 如果您突然对接口的实现不满意,可以通过Configurator设置实现。

DocLoc的屏幕快照(文档和本地化)


在所有有本地化的项目中,通常都需要使用不同的语言来截取屏幕截图,以将其作为插图提供给翻译人员。 毕竟,如果不查看特定行的位置和使用方式,很难进行正确的翻译。 因此,我希望能够快速并立即以所有语言拍摄屏幕截图。 包括系统对话框的屏幕截图。 您可能还需要旧屏幕上的屏幕截图,而无需进行全局重构。

所有这些使您可以立即使用Kaspresso。 在文档中阅读更多内容

架构和最佳实践


Kaspresso的关键任务之一就是创建一个这样的dsl,它将促使您使用正确的测试体系结构和正确的编写方式。

关于此主题的很多副本都被打乱了,因为不幸的是,您在任何地方都找不到这样的规则。 您最多可以找到有关Page Object的文章。

因此,我们不遗余力地在文档中以及在视频1视频2中强调了这些问题。
此外,Sasha Blinov写了一篇有关Kotlin DSL和优雅测试的出色文章 。 本文中描述的dsl由Kaspresso提供。

回到Mobius,我们提出了一个选项,该选项可绕开不可避免的基础架构问题,提出如何加速自动测试的影响并将其快速集成到PullRequest中的方法。 我们在这里详细讨论。

如果您已经进行了许多测试,如何连接和配置Kaspresso


主要的魅力在于,如果您已经有许多用Kakao编写的测试并且想要实现Kaspresso,那么您无需重写任何内容! 只需从特殊的TestCase类继承您的测试类即可。 仅此而已!

那是:

 @RunWith(AndroidJUnit4::class) class OpenHomeScreenTest { private val mainScreen = MainScreen() private val homeScreen = HomeScreen() @get:Rule val activityTestRule = ActivityTestRule(MainActivity::class.java, true, false) @Test fun test() { ... } } 

它变成了:

 @RunWith(AndroidJUnit4::class) class OpenHomeScreenTest : TestCase() { private val mainScreen = MainScreen() private val homeScreen = HomeScreen() @get:Rule val activityTestRule = ActivityTestRule(MainActivity::class.java, true, false) @Test fun test() { ... } } 

而且,如果您不喜欢继承,请使用类似的TestRule类。

正如我们已经提到的,Kaspresso是一个非常灵活且可自定义的框架。 通过相同名称的Kaspresso类可以使用所有设置。

默认设置为默认。 如果要自定义某些内容,它将类似于以下内容:

 @RunWith(AndroidJUnit4::class) class OpenHomeScreenTest : TestCase( Kaspresso.Builder.default().apply { viewBehaviorInterceptors.add(MyInterceptor()) flakySafetyParams.timeoutMs = 1_000 } ) { private val mainScreen = MainScreen() private val homeScreen = HomeScreen() @get:Rule val activityTestRule = ActivityTestRule(MainActivity::class.java, true, false) @Test fun test() { ... } } 

也就是说,通过TestCase 构造函数可以使用Kaspresso.Builder ,您可以在其中设置所需的所有设置。 有关配置器的详细信息写在文档中

即时计划


我们计划在不久的将来添加以下内容:

显示Allure中的测试步骤(向HeadHunter的人员打招呼)


通过特殊的拦截器,我们为Marathon准备数据。 这使我们可以查看具有以下性质的魅力报告:



PR#4中的详细信息

PS PR已经是1.0.1版,现在我们正在Marathon中准备相应的PR。
s 有一种想法是将特定部分的日志附加到每个步骤,然后将屏幕截图添加到“下降”步骤。

测试升级脚本


通常,必须检查应用程序升级的正确性。 是的,某些检查可以转移到单元测试中。 但是我们希望对整个应用程序保持冷静。

不幸的是,在纯Espresso上无法做到这一点,因为如果我们重新安装经过测试的apk,则测试将失败。 您可以尝试以某种方式欺骗跑步者,但我很难想象这种改进的外观和稳定性。
因此,在Kaspresso,我们正在基于UiAutomator准备针对此问题的解决方案。 但是,在顶部,您将拥有所有相同的熟悉的dsl,与kakao非常相似,并且具有相同的间隔支持。

有用的链接


卡斯派索
AdbServer
聊天 ,我们将很乐意回答您的所有问题

致谢


特别感谢参与该项目开发的每个人。
这非常困难,但是该死的很酷!





而不是结论


我们相信Kaspresso和AdbServer将使您的生活更加美好。
我们欢迎您的反馈,建议,Yishuyam和PulRequest!
并且请不要忘了加一个星号!

附言,最后是一次小调查=)

Source: https://habr.com/ru/post/zh-CN467617/


All Articles