测试架构设计评估系统 - 基于行为的测试





5.00/5 (3投票s)
我们将使用之前介绍的评估框架来评估使用行为模式的测试。找到相应的评分和理由。
引言
在我之前的文章《测试架构设计的评估系统》中,我向大家介绍了八个用于测试架构设计的评估标准。为了更全面地理解该系统,我将用它来评估几个实际示例,为每个标准进行评分,并解释我的理由。我们将要评估的第二类测试是基于行为的测试(乐高式测试)。如果您不熟悉行为设计模式(乐高设计模式),可以阅读我的文章《自动化测试中的高级行为设计模式(第二部分)》。
基于行为的测试
抽象行为
public abstract class WaitableActionBehaviour : IBehaviour
{
public void Execute()
{
this.PerformAct();
this.PerformPostActWait();
}
protected abstract void PerformAct();
protected abstract void PerformPostActWait();
}
通常,一个行为会执行一个页面特定的工作流程——执行操作并等待一个条件。行为有不同的类型——仅操作、仅断言、两者结合或添加额外的预/后等待条件(等待页面加载或等待元素可见)。上面是所有行为的基类,它首先执行操作,然后等待某事发生。
具体行为
public class PreviewShoppingCartPageProceedBehaviour : WaitableActionBehaviour
{
private readonly PreviewShoppingCartPage previewShoppingCartPage;
private readonly SignInPage signInPage;
public PreviewShoppingCartPageProceedBehaviour()
{
this.previewShoppingCartPage =
UnityContainerFactory.GetContainer().Resolve<PreviewShoppingCartPage>();
this.signInPage =
UnityContainerFactory.GetContainer().Resolve<SignInPage>();
}
protected override void PerformAct()
{
this.previewShoppingCartPage.ClickProceedToCheckoutButton();
}
protected override void PerformPostActWait()
{
this.signInPage.WaitForPageToLoad();
}
}
特定行为的具体实现不必重写基类的所有方法(如果存在后/预等待和断言方法,则类可以只重写其中一个)。行为会持有所有依赖页面或其他服务的私有实例。它们通过 Unity IoC 容器在行为的构造函数中初始化。
带参数的行为
public class ShippingAddressPageFillDifferentBillingBehaviour : ActionBehaviour
{
private readonly ShippingAddressPage shippingAddressPage;
private readonly ShippingPaymentPage shippingPaymentPage;
private readonly PerfectSystemTestsDesign.Data.ClientPurchaseInfo clientPurchaseInfo;
public ShippingAddressPageFillDifferentBillingBehaviour(ClientPurchaseInfo clientPurchaseInfo)
{
this.shippingAddressPage = UnityContainerFactory.GetContainer().Resolve<ShippingAddressPage>();
this.shippingPaymentPage = UnityContainerFactory.GetContainer().Resolve<ShippingPaymentPage>();
this.clientPurchaseInfo = clientPurchaseInfo;
}
protected override void PerformAct()
{
this.shippingAddressPage.ClickDifferentBillingCheckBox(this.clientPurchaseInfo);
this.shippingAddressPage.ClickContinueButton();
this.shippingPaymentPage.ClickBottomContinueButton();
this.shippingAddressPage.FillBillingInfo(this.clientPurchaseInfo);
}
}
如果需要,特定的行为可以接受自定义参数。
测试中的行为使用
[TestMethod]
public void Purchase_SimpleBehaviourEngine()
{
var itemUrl = "/Selenium-Testing-Cookbook-Gundecha-Unmesh/dp/1849515743";
var itemPrice = "40.49";
var clientPurchaseInfo = new ClientPurchaseInfo(
new ClientAddressInfo()
{
FullName = "John Smith",
Country = "United States",
Address1 = "950 Avenue of the Americas",
State = "New York",
City = "New York City",
Zip = "10001-2121",
Phone = "00164644885569"
});
clientPurchaseInfo.CouponCode = "99PERDIS";
var clientLoginInfo = new ClientLoginInfo()
{
Email = "g3984159@trbvm.com",
Password = "ASDFG_12345"
};
PerfectSystemTestsDesign.Behaviours.Core.BehaviourExecutor.Execute(
new ItemPageNavigationBehaviour(itemUrl),
new ItemPageBuyBehaviour(),
new PreviewShoppingCartPageProceedBehaviour(),
new SignInPageLoginBehaviour(clientLoginInfo),
new ShippingAddressPageFillShippingBehaviour(clientPurchaseInfo),
new ShippingAddressPageFillDifferentBillingBehaviour(clientPurchaseInfo),
new ShippingAddressPageContinueBehaviour(),
new ShippingPaymentPageContinueBehaviour(),
new PlaceOrderPageAssertFinalAmountsBehaviour(itemPrice));
}
行为被添加到一个特殊的行为执行器列表中,该执行器负责以适当的方式执行它们。如果行为依赖于任何数据,则在传递给其构造函数时提供。
行为设计模式的优点
- 可读性强
- 可以详细查看工作流程的步骤
如果您不想执行某些断言的微型工作流程,只需不将其行为包含在列表中即可。遵循最小知识原则,因为您只将所需数据传递给行为的构造函数。
行为设计模式的缺点
引入了大量新类。编写新测试的速度变慢,因为现在需要初始化所有必需的行为。测试编写过程更容易出错,因为您可能会弄错步骤顺序或为某些行为参数分配错误的值。
评估基于行为的测试——评估系统
可维护性
[Binding]
public class SignInPageLoginBehaviour : WaitableActionBehaviour
{
private readonly SignInPage signInPage;
private readonly ShippingAddressPage shippingAddressPage;
private ClientLoginInfo clientLoginInfo;
public SignInPageLoginBehaviour()
{
this.signInPage =
UnityContainerFactory.GetContainer().Resolve<SignInPage>();
this.shippingAddressPage =
UnityContainerFactory.GetContainer().Resolve<ShippingAddressPage>();
}
[When(@"I login with email = ""([^""]*)"" and pass = ""([^""]*)""")]
public void LoginWithEmailAndPass(string email, string password)
{
this.clientLoginInfo = new ClientLoginInfo
{
Email = email,
Password = password
};
base.Execute();
}
protected override void PerformPostActWait()
{
this.shippingAddressPage.WaitForPageToLoad();
}
protected override void PerformAct()
{
this.signInPage.Login(this.clientLoginInfo.Email, this.clientLoginInfo.Password);
}
}
可维护性评为优秀(5)。行为是某些用例的微型工作流程。如果用例需要更改,只需在此处编辑。由于行为仅按需添加,因此并非对所有情况都执行。如果您修复了一个行为,更改将仅影响使用它的测试。
基于行为的测试 | |
可维护性 | 5 |
可读性 | |
代码复杂度指数 | |
可用性 | |
灵活性 | |
学习曲线 | |
最少知识 |
可读性
BehaviourExecutor.Execute(
new ItemPageNavigationBehaviour(itemUrl),
new ItemPageBuyBehaviour(),
new PreviewShoppingCartPageProceedBehaviour(),
new SignInPageLoginBehaviour(clientLoginInfo),
new ShippingAddressPageFillShippingBehaviour(clientPurchaseInfo),
new ShippingAddressPageFillDifferentBillingBehaviour(clientPurchaseInfo),
new ShippingAddressPageContinueBehaviour(),
new ShippingPaymentPageContinueBehaviour(),
new PlaceOrderPageAssertFinalAmountsBehaviour(itemPrice));
可读性评估为非常好(4)。由于行为的名称具有自描述性,您可以猜测其用例。此外,由于您列出了多个行为来定义更大的工作流程,因此步骤的顺序对读者来说是直接可见的。
基于行为的测试 | |
可维护性 | 5 |
可读性 | 4 |
代码复杂度指数 | |
可用性 | |
灵活性 | |
学习曲线 | |
最少知识 |
代码复杂度指数
行为类小巧简单。然而,测试类更复杂,因为您需要初始化整个行为的执行链。
基于行为的测试 | |
可维护性 | 5 |
可读性 | 4 |
代码复杂度指数 | 4 |
可用性 | |
灵活性 | |
学习曲线 | |
最少知识 |
可用性
BehaviourExecutor.Execute(
new ItemPageNavigationBehaviour(itemUrl),
new ItemPageBuyBehaviour(),
new PreviewShoppingCartPageProceedBehaviour(),
new SignInPageLoginBehaviour(clientLoginInfo),
new ShippingAddressPageFillShippingBehaviour(clientPurchaseInfo),
new ShippingAddressPageFillDifferentBillingBehaviour(clientPurchaseInfo),
new ShippingAddressPageContinueBehaviour(),
new ShippingPaymentPageContinueBehaviour(),
new PlaceOrderPageAssertFinalAmountsBehaviour(itemPrice));
测试框架 API 并不复杂。但是,您应该知道要在大工作流程中指定的行为的确切名称。此外,您应该注意它们的正确顺序。有可能弄错某些步骤的顺序。编写工作量更大,因为您需要初始化多个新类。
基于行为的测试 | |
可维护性 | 5 |
可读性 | 4 |
代码复杂度指数 | 4 |
可用性 | |
灵活性 | |
学习曲线 | |
最少知识 |
灵活性
如果您想跳过一些可选的微型工作流程,只需不将其添加到执行器的链中。如果您必须添加一个仅对少量用例有效的自定义微型工作流程,则情况也是如此。您只需要创建行为并将其添加到该特定用例的行为列表中。
基于行为的测试 | |
可维护性 | 5 |
可读性 | 4 |
代码复杂度指数 | 4 |
可用性 | 4 |
灵活性 | 5 |
学习曲线 | |
最少知识 |
学习曲线
对于测试框架 API 的学习曲线来说,属于平均水平(4),因为用户应该知道行为的确切顺序。此外,他/她应该熟悉所有行为的正确名称以及想要调用的确切实现。可能会有多个实现,其中略有不同。
基于行为的测试 | |
可维护性 | 5 |
可读性 | 4 |
代码复杂度指数 | 4 |
可用性 | 4 |
灵活性 | 5 |
学习曲线 | 4 |
最少知识 |
最少知识
您只将必需的参数传递给具体行为。因此,该评分被评为优秀。
基于行为的测试 | |
可维护性 | 5 |
可读性 | 4 |
代码复杂度指数 | 4 |
可用性 | 4 |
灵活性 | 5 |
学习曲线 | 4 |
最少知识 | 5 |
在本系列的下一篇文章中,我将使用评估系统来评估基于 SpecFlow 的测试。
您可以观看我关于该系统的会议演讲,或下载完整的幻灯片。
设计与架构
- 创建混合测试框架 – Selenium 驱动控件
- 创建混合测试框架 – Selenium Driver 实现
- 创建混合测试自动化框架——接口契约
- 创建混合测试框架 – 测试框架驱动实现
- 创建混合测试框架 – 测试框架驱动控件
- 创建混合测试框架 – 高级元素查找扩展
- 创建混合测试框架 – 动态配置执行引擎
- 创建混合测试框架 - 抽象单元测试框架
这篇文章《测试架构设计评估系统 - 基于行为的测试》首次出现在Automate The Planet。
所有图片均从 DepositPhotos.com 购买,不可免费下载和使用。
许可协议