无需注册和SMS即可对交钥匙Web应用程序进行自动化测试

通常,Web应用程序由大量具有不同文本和控件的动态重组表单组成。测试这样的应用程序将成为一场噩梦。

您需要单击100500页并检查所有功能...在下一个发行版之前,请再次检查相同的内容...然后再次...明天再次。在某个时候,验证开始所花的时间比开发新功能所需的时间更长。 “ e2e测试呢?” - 你问。但是,首先,它们仍然需要编写。其次,在开始编写它们之前,您需要编写测试用例。很多测试用例。

如果在阅读这些内容时额头上满是汗水,请不要担心。在本文中,我将与您分享我们如何在Tinkoff上自动测试其中一个Web应用程序而无需编写单个测试用例和e2e测试的想法。




自动编写测试用例


碰巧的是,测试我们的Web应用程序主要与接口检查有关。您需要检查屏幕上是否存在该按钮,是否显示了所需的标题和文本,并且在input输入无效值时,会出现错误消息。

因此,在编写测试用例时,您需要记录所有操作:

  • “按下按钮”
  • “输入了XXX的值”
  • “在下拉列表中选择值YYY”

并检查:

  • “出现的文字:XXX”
  • “出现错误消息:YYY”
  • “出现标题:ZZZ”

在分析了Web应用程序的所有功能之后,我们确定了大约30种独特的操作和检查。显然,该过程可以自动化。为此,您只需要在页面上跟踪测试人员的所有操作以及网站对这些操作的反应即可。

让我们从拦截事件开始。要跟踪与按钮,单选按钮和复选框等控件的交互,您需要预订click事件。每个框架对此都有自己的方法。例如,Angular中的fromEvent以及JavaScript和React中的document.addEventListener。对于诸如日历或输入之类的输入控件,仅您要订阅的事件类型将更改:焦点将变为单击而不是单击。

fromEvent(this.elementRef.nativeElement, 'click')
.subscribe(tagName => {
 	if (tagName === 'BUTTON') {
   		this.testCaseService.addAction(`   "${action.name}"`);
 	} else if (tagName === 'INPUT-CALENDAR') {
   		this.testCaseService
     			.addAction(`  "${action.name}" "${action.value}"`);
 	}
});

最后,最重要的是检查。站点响应测试人员的行为应采取的方式。

测试人员通常检查什么?例如,他在input中输入了无效值,该站点以错误消息作为响应。或者,假设我们单击了一个按钮,作为响应,出现了一个新屏幕,更改了标题,出现了新文本,并重建了控件。所有这些更改都与DOM树中的更改有关。有很多选项可以跟踪它们。例如,您可以在React和JavaScript中使用MutationObserver或在Angular中使用ngAfterViewInit(在网站上感兴趣的表单元素上放置一个指令)。

ngAfterViewInit() {
    const tagName = this.nativeElement.nodeName;
	const text = this.nativeElement.textContent;
    if (['SPAN', 'P'].includes(tagName)) {
 	 	 this.testCaseService.addContent(`** ** "${text}"\n`);
     } else if (tagName === 'H1') {
 	  	this.testCaseService.addContent(`** ** "${text}"\n`);
     } …	
}

该代码将非常依赖于布局。让我们看一下标记。这些按钮取自Google翻译器。


<div class="tlid-input-button input-button header-button tlid-input-button-text text-icon" role="tab" tabindex="-1">
  	<div class="text"></div>
</div>
<div class="tlid-input-button input-button header-button tlid-input-button-docs documents-icon" role="tab" tabindex="-1">
 	 <div class="text"></div>
</div>

尽管按钮并未表示为按钮标签,但查看标记,您仍然可以使用“ input-button” css类选择页面上的所有按钮,并且可以从嵌套的“ text” css类中获取按钮名称。

完成了一半的工作,剩下的只是写下我们跟踪到测试用例中的所有内容。

我们包括针对特定按键组合的站点上所有动作的拦截,并且仅在测试电路上。我们通过特定的组合键停止拦截站点上的所有事件。这使您可以从任何地方启动和停止测试用例的自动记录。

自动编写端到端测试


如果您查看自动生成的测试用例,那么这些本质上就是简化为相同形式的用户脚本。因此,它们可以转换为e2e测试。您甚至可以在拦截所有操作和检查后绕过测试用例立即编写e2e测试。

现在,有很多基于行为脚本的带有小黄瓜表示法的不同框架:SpecFlow,xBehave.net。,Cucumber.js,CodeceptJS等。

要从测试用例中获取功能,您需要在操作之前和之前添加When 关键字所有检查然后和。

获取自动生成的e2e测试:

Feature:   2-
  Background:
 	When  "" ""

  Scenario:
 	When    " - "
 	Then    "  "
 	And   " - "
 	When    "  " ""
 	When    "" "  "
 	When    ""

要运行测试运行,生成的功能很少-您需要为所有操作和检查编写一个处理程序。

有个好消息:您无需为每个功能编写处理程序。就像我已经说过的,尽管站点上有很多不同的表格,但我们只有30种独特的操作和检查,这意味着用于所有e2e测试的通用处理器中将使用完全相同数量的方法。代码会稍有不同-取决于所选择的框架以及网站上的小黄瓜符号和布局。但是编写处理程序本身并不需要很多时间。

When('   {string}', async function (button: string) {
	const xpath = "//button";
	const btn = await getItemByText(xpath, button);
	await waitAndClick(btn);
});
When('  {string} {string}', async function (label: string, text: string) {
	const xpath = "//*[contains(text(),'" + label + "')]/ancestor::outline";
	await inputSendKeys(currentBrowser().element(by.xpath(xpath)), text);
});

现在,检查下一个任务,将自动为测试人员编写一个测试用例,并运行自动生成的e2e测试。

简而言之,您需要:

  1. 订阅与控件进行交互的事件以及网站对这些操作的反应(通过跟踪DOM树的重建)。
  2. 将数据从第1段转换为e2e测试。
  3. 编写用于运行e2e测试的常规处理程序。

这种方法将帮助您摆脱常规。您可以自动编写测试用例和e2e测试,以进行与接口相关的简单检查。我们走得更远,还自动检查数据库中的记录并发送给第三方服务。

在莫斯科的Heisenbug-2019大会上讨论了此问题以及版本,技术堆栈,甚至讨论了实施的第一阶段的问题及其解决方案

在本文中,我尝试不涉及细节就传达主要思想。

结论


现在,我们平均需要2分钟来编写一个测试用例和一个e2e测试-当我们想要手动编写测试用例和e2e测试时,这比初始计算快60倍。

我们没有更改团队中的流程。不再需要分配用于编写测试用例的测试能力,并将其带给自动化团队。

我们完全摆脱了回归的概念。如果早些时候进行了为期两周的冲刺,则回归花费了我们3天以上的时间,现在回归需要花费时间来运行所有e2e测试,而这仅需要2个小时。

手动编写e2e测试时,很难与测试并行进行。现在,e2e测试是在任务测试期间自动编写的,并且测试人员无需两次检查相同的功能。

结果,我们的团队在不改变组成的情况下开始更加高效地工作。

All Articles