自动化测试中的设计模式

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前,正在 星球 内带小伙伴们做第一个项目:全栈前后端分离博客项目,采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 204 小节,累计 32w+ 字,讲解图:1416 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 870+ 小伙伴加入,欢迎点击围观

在我以前的“ 自动化测试中的设计模式 ”系列文章中,我详细解释了如何通过 页面对象 门面 单例 的实现来使您的测试自动化框架更好。当我们必须为更复杂的用例场景编写测试时,通常会越来越难遵循 开闭原则 ,这是 solid 的主要原则之一。在本系列的这一部分,我将使用 策略设计模式 为电子商务模块创建可扩展验证器。

到目前为止,在“自动化测试中的设计模式”系列中

1. 页面对象模式

2. 高级页面对象模式

3. 门面设计模式

4. 单例设计模式

5. 流畅的页面对象模式

6. ioc 容器和页面对象

7. 策略设计模式

8. 高级策略设计模式

9. 观察者设计模式

10. 通过事件和委托的观察者设计模式

11. 通过 iobservable 和 iobserver 的观察者设计模式

定义

计算机编程 中, 策略模式 (也称为 策略模式 )是一种 软件设计模式 ,可以在运行时选择 算法 的行为。

  • 定义了一系列算法。
  • 封装了每个算法。
  • 使算法在该系列中可以互换。
  • 代码更易于维护,因为修改或理解策略不需要您理解整个主要对象。

uml类图

参与者

参与此模式的类和对象是:

  • istrategy (iordervalidationstrategy) – 定义所有算法通用的接口。上下文类调用接口来执行由具体策略标识的算法。
  • concretestrategy (salestaxordervalidationstrategy) - 使用策略接口实现算法。
  • context (purchasecontext) – 依赖于 istrategy 。包装对具体策略的调用,可以为访问其数据的策略提供接口。

策略设计模式c#代码

测试的测试用例

以下测试的主要目标是从 亚马逊 购买不同的商品。此外,应验证购买过程最后一步的价格——税费、运费、礼品包装费等。

1. 导航 到项目页面

2.点击 继续结账

3.使用 现有 客户端 登录


4. 填写 运输信息


5. 选择 运输速度

6. 选择 支付方式


7. 验证 订单摘要


测试相关类 设计 的主要目标是在购买流程的最后一页实现不同价格的解耦和可扩展验证。

将使用以下 类结构

如您所见,测试的设计大量使用了 页面对象模式 。不同页面没有任何异常,所以我不会在这里粘贴每个页面的代码,因为它与文章的主题无关。最有趣的逻辑可能位于 shippingaddresspage 中。


 public class shippingaddresspage : basepagesingleton<shippingaddresspage, shippingaddresspagemap>
{
    public void clickcontinuebutton()
    {
        this.map.continuebutton.click();
    }
public void fillshippinginfo(clientpurchaseinfo clientinfo)
{
    this.map.countrydropdown.selectbytext(clientinfo.country);
    this.map.fullnameinput.sendkeys(clientinfo.fullname);
    this.map.address1input.sendkeys(clientinfo.address1);
    this.map.cityinput.sendkeys(clientinfo.city);
    this.map.zipinput.sendkeys(clientinfo.zip);
    this.map.phoneinput.sendkeys(clientinfo.phone);
    this.map.shiptothisaddress.click();
}

}


clientpurchaseinfo 类保存有关客户购买的数据,大部分数据是通过字符串属性填充的。


 public class shippingaddresspage : basepagesingleton<shippingaddresspage, shippingaddresspagemap>
{
    public void clickcontinuebutton()
    {
        this.map.continuebutton.click();
    }
public void fillshippinginfo(clientpurchaseinfo clientinfo)
{
    this.map.countrydropdown.selectbytext(clientinfo.country);
    this.map.fullnameinput.sendkeys(clientinfo.fullname);
    this.map.address1input.sendkeys(clientinfo.address1);
    this.map.cityinput.sendkeys(clientinfo.city);
    this.map.zipinput.sendkeys(clientinfo.zip);
    this.map.phoneinput.sendkeys(clientinfo.phone);
    this.map.shiptothisaddress.click();
}

}

没有策略设计模式的实现

通过使用 门面设计模式, 可以轻松地使用例自动化。


 public class shippingaddresspage : basepagesingleton<shippingaddresspage, shippingaddresspagemap>
{
    public void clickcontinuebutton()
    {
        this.map.continuebutton.click();
    }
public void fillshippinginfo(clientpurchaseinfo clientinfo)
{
    this.map.countrydropdown.selectbytext(clientinfo.country);
    this.map.fullnameinput.sendkeys(clientinfo.fullname);
    this.map.address1input.sendkeys(clientinfo.address1);
    this.map.cityinput.sendkeys(clientinfo.city);
    this.map.zipinput.sendkeys(clientinfo.zip);
    this.map.phoneinput.sendkeys(clientinfo.phone);
    this.map.shiptothisaddress.click();
}

}

这种解决方案的主要缺点是针对不同税务验证案例的不同方法的数量。如果需要引入新的税收验证,则应添加打破 开放封闭原则的 新方法。

策略设计模式实现

您可以在此示例电子商务模块中自动执行数百个测试用例。其中一些最重要的因素与采购流程最后一页上 价格 正确性 有关。所以测试中验证的主要目标是测试是否显示了正确的价格。有几种类型的税收——销售(美国/加拿大)、增值税(欧盟国家)、礼品包装、运输等。页面对象可以在 purchasecontext 类中组合以执行新的购买, 策略设计模式 可以应用于通过特定的验证策略。



验证策略的主要方法可以通过以下接口定义。


 public class shippingaddresspage : basepagesingleton<shippingaddresspage, shippingaddresspagemap>
{
    public void clickcontinuebutton()
    {
        this.map.continuebutton.click();
    }
public void fillshippinginfo(clientpurchaseinfo clientinfo)
{
    this.map.countrydropdown.selectbytext(clientinfo.country);
    this.map.fullnameinput.sendkeys(clientinfo.fullname);
    this.map.address1input.sendkeys(clientinfo.address1);
    this.map.cityinput.sendkeys(clientinfo.city);
    this.map.zipinput.sendkeys(clientinfo.zip);
    this.map.phoneinput.sendkeys(clientinfo.phone);
    this.map.shiptothisaddress.click();
}

}


purchasecontext 类几乎与已经讨论过的 外观类 相同;唯一的区别是它依赖于 iordervalidationstrategy

具体的验证策略被传递给它的构造函数。


 public class shippingaddresspage : basepagesingleton<shippingaddresspage, shippingaddresspagemap>
{
    public void clickcontinuebutton()
    {
        this.map.continuebutton.click();
    }
public void fillshippinginfo(clientpurchaseinfo clientinfo)
{
    this.map.countrydropdown.selectbytext(clientinfo.country);
    this.map.fullnameinput.sendkeys(clientinfo.fullname);
    this.map.address1input.sendkeys(clientinfo.address1);
    this.map.cityinput.sendkeys(clientinfo.city);
    this.map.zipinput.sendkeys(clientinfo.zip);
    this.map.phoneinput.sendkeys(clientinfo.phone);
    this.map.shiptothisaddress.click();
}

}


在大多数情况下,我认为验证税收和类似金额的最佳方法是调用用于为实际电子商务模块提供支持的 实际生产 Web 服务 。它们应该已经通过单元和集成测试进行了全面测试,并且它们的输出应该得到保证。

e2e 测试的主要目标是确保页面上显示正确的价格,而不是检查真正的计算逻辑。所以在我的具体实施中


 public class shippingaddresspage : basepagesingleton<shippingaddresspage, shippingaddresspagemap>
{
    public void clickcontinuebutton()
    {
        this.map.continuebutton.click();
    }
public void fillshippinginfo(clientpurchaseinfo clientinfo)
{
    this.map.countrydropdown.selectbytext(clientinfo.country);
    this.map.fullnameinput.sendkeys(clientinfo.fullname);
    this.map.address1input.sendkeys(clientinfo.address1);
    this.map.cityinput.sendkeys(clientinfo.city);
    this.map.zipinput.sendkeys(clientinfo.zip);
    this.map.phoneinput.sendkeys(clientinfo.phone);
    this.map.shiptothisaddress.click();
}

}

我已经为增值税验证策略实施了类似的逻辑。


 public class shippingaddresspage : basepagesingleton<shippingaddresspage, shippingaddresspagemap>
{
    public void clickcontinuebutton()
    {
        this.map.continuebutton.click();
    }
public void fillshippinginfo(clientpurchaseinfo clientinfo)
{
    this.map.countrydropdown.selectbytext(clientinfo.country);
    this.map.fullnameinput.sendkeys(clientinfo.fullname);
    this.map.address1input.sendkeys(clientinfo.address1);
    this.map.cityinput.sendkeys(clientinfo.city);
    this.map.zipinput.sendkeys(clientinfo.zip);
    this.map.phoneinput.sendkeys(clientinfo.phone);
    this.map.shiptothisaddress.click();
}

}

使用 s 策略设计模式 的一个基本好处是,如果在应用程序中引入新的税收,您不必修改现有页面或 purchasecontext 。您只需要创建一个新的具体策略。

例如,如果亚马逊宣布从明天起,超级模特可以将您想要的物品直接送货上门,只需 100 美元。您可以通过创建新的 supermodelordervalidationstrategy 来处理新的税务验证。想象布拉德皮特背着冰箱,我一定会付钱看的。

使用策略设计模式进行测试


 public class shippingaddresspage : basepagesingleton<shippingaddresspage, shippingaddresspagemap>
{
    public void clickcontinuebutton()
    {
        this.map.continuebutton.click();
    }
public void fillshippinginfo(clientpurchaseinfo clientinfo)
{
    this.map.countrydropdown.selectbytext(clientinfo.country);
    this.map.fullnameinput.sendkeys(clientinfo.fullname);
    this.map.address1input.sendkeys(clientinfo.address1);
    this.map.cityinput.sendkeys(clientinfo.city);
    this.map.zipinput.sendkeys(clientinfo.zip);
    this.map.phoneinput.sendkeys(clientinfo.phone);
    this.map.shiptothisaddress.click();
}

}

使用 s 策略设计模式 创建自动化测试很容易。您唯一需要做的就是将所需的算法传递给新创建的 purchasecontext

源代码

您可以从我的 github 存储库下载完整的源代码 - https://github.com/angelovstanton/projects/tree/master/patternsinautomation.tests