在自动化测试中,设计模式的应用可以极大地提高测试的灵活性和可维护性。本文将介绍如何使用行为设计模式来构建类似于乐高积木的系统测试。将探讨如何进一步改进行为驱动测试,并展示如何使用统一容器工厂来解决参数传递问题。
在改进的行为设计模式中,参与的类和对象包括:
在之前的示例中,存在一个主要问题,即无法正确传递参数给行为。它们都依赖于静态测试上下文类。众所周知,使用静态不是最佳实践。另一个问题是,ExecutionEngine中工作流的定义不够灵活。如果需要添加一个新步骤,需要在几乎所有测试都依赖的主类中进行更改。希望提高测试的灵活性。
与之前的示例相比,一个主要区别是IBehaviour接口只包含一个Execute方法。
public interface IBehaviour {
void Execute();
}
另一个主要区别是,有多个基于它们需要解决的用例的行为基类。有只包含动作的和只包含断言的类。认为这将导致更好的面向对象设计,而不是只覆盖提供的方法的一部分。
public abstract class ActionBehaviour : IBehaviour {
public void Execute() {
this.PerformAct();
}
protected abstract void PerformAct();
}
public abstract class AssertBehaviour : IBehaviour {
public void Execute() {
this.Assert();
}
protected abstract void Assert();
}
public abstract class WaitableActionBehaviour : IBehaviour {
public void Execute() {
this.PerformAct();
this.PerformPostActWait();
}
protected abstract void PerformAct();
protected abstract void PerformPostActWait();
}
这个类在需要执行一个动作然后等待某事时很有用,例如,等待页面加载或元素变为可见。
public class WaitableAssertableActionBehaviour : IBehaviour {
public void Execute() {
this.PerformPreActWait();
this.PerformPreActAssert();
this.PerformAct();
this.PerformPostActAssert();
this.PerformPostActWait();
this.PerformPostActWaitAssert();
}
protected virtual void PerformPreActWait() { }
protected virtual void PerformPreActAssert() { }
protected virtual void PerformAct() { }
protected virtual void PerformPostActAssert() { }
protected virtual void PerformPostActWait() { }
protected virtual void PerformPostActWaitAssert() { }
}
这个类几乎与之前的示例中的类相同,因为它太复杂了,包含了所有可能的工作流步骤。如果无法使用其他可用的行为基类,则建议仅使用它。
现在行为接受所需的itemUrl作为构造函数的参数。依赖的ItemPage不是在BehavioursExecutor中解析的,而是通过UnityContainerFactory类的帮助在行为本身中解析的,该类提供了当前Unity IoC容器的实例。由于它只需要导航到一个页面,因此它实现了简单的ActionBehaviour基类。
public class ItemPageNavigationBehaviour : ActionBehaviour {
private readonly ItemPage itemPage;
private readonly string itemUrl;
public ItemPageNavigationBehaviour(string itemUrl) {
this.itemPage = UnityContainerFactory.GetContainer().Resolve();
this.itemUrl = itemUrl;
}
protected override void PerformAct() {
this.itemPage.Navigate(this.itemUrl);
}
}
它是一个静态类,包含一个静态方法GetContainer,返回当前的Unity IoC容器实例。它也可以实现为单例。
public static class UnityContainerFactory {
private static IUnityContainer unityContainer;
static UnityContainerFactory() {
unityContainer = new UnityContainer();
}
public static IUnityContainer GetContainer() {
return unityContainer;
}
}
更改几乎与应用于ItemPageNavigationBehaviour的更改相同,除了类继承了WaitableActionBehaviour。它覆盖了PerformPostActWait方法,在该方法中等待送货地址页面加载。
public class SignInPageLoginBehaviour : WaitableActionBehaviour {
private readonly SignInPage signInPage;
private readonly ShippingAddressPage shippingAddressPage;
private readonly ClientLoginInfo clientLoginInfo;
public SignInPageLoginBehaviour(ClientLoginInfo clientLoginInfo) {
this.signInPage = UnityContainerFactory.GetContainer().Resolve();
this.shippingAddressPage = UnityContainerFactory.GetContainer().Resolve();
this.clientLoginInfo = clientLoginInfo;
}
protected override void PerformPostActWait() {
this.shippingAddressPage.WaitForPageToLoad();
}
protected override void PerformAct() {
this.signInPage.Login(this.clientLoginInfo.Email, this.clientLoginInfo.Password);
}
}
执行器现在不包含任何复杂逻辑,它只包含一个接受行为工作流数组的Execute方法。
public static class BehaviourExecutor {
public static void Execute(params IBehaviour[] behaviours) {
foreach (var behaviour in behaviours) {
behaviour.Execute();
}
}
}
与之前的变体相比,可以注意到一些显著的变化。首先,需要通过new运算符传递行为,并传递任何所需的参数。以前,通过typeof运算符传递行为。不再需要初始化静态测试上下文。
认为这些更改使测试更加灵活、可读和可维护。
设计模式在自动化测试中的应用