自动化测试中的SOLID原则

自动化测试在软件质量保障手段中愈显重要 。但是随着自动化测试代码的规模和复杂性不断扩大,它也很容易出现测试代码重复、紧耦合等问题。而SOLID原则可以解决这一问题,作为自动化用例开发的指导原则。

探索SOLID原则

SOLID原则是一组指导软件开发人员设计高质量软件的设计原则。这些原则分别是单一职责原则(Single Responsibility Principle, SRP)、开闭原则(Open-Close Principle, OCP)、里式替换原则(Liskov Substitution Principle, LSP)、接口隔离原则(Interface Segregation Principle, ISP)和依赖反转原则(Dependency Inversion Principle, DIP)。这些原则共同帮助开发人员创建易于维护和可扩展的软件系统,提高软件的可维护性、可扩展性、可重用性和可测试性。

  1. 单一职责原则(SRP):一个类或方法应该只有一个职责。这意味着一个类不应该承担过多的职责,以避免紧密的职责耦合,从而使得类的修改和维护变得困难。
  2. 开闭原则(OCP):软件实体(如模块、类)应对扩展开放,对修改关闭。这意味着软件应该在不影响现有功能的情况下进行扩展,以适应新的需求或变化。
  3. 里式替换原则(LSP):子类应该能够替换其父类,而不会影响程序的正确性。这要求继承关系中的子类保持与父类一致的接口和行为。
  4. 接口隔离原则(ISP):客户端应该依赖于它需要的具体接口,而不是依赖于一个庞大的接口。这有助于减少类之间的耦合度,提高系统的可维护性和可重用性。
  5. 依赖反转原则(DIP):高层模块不应该依赖于低层模块,它们都应该依赖于抽象。这有助于减少代码之间的耦合度,使得代码更加灵活和可维护。

通过遵循这些原则,开发人员可以设计出更加灵活、易于理解和修改的代码,从而提高软件的质量和可靠性。

1. 单一责任原则(SRP)

下面是一些如何应用它的例子:

PageObject模型:

  • 为每个页面创建一个不同的类,例如 HomePage, LoginPage, OrdersPage 等,而不是将所有的页面定位器合并到一个单一的 “PageObject” 类中,而是将它们分布到负责各自页面的单个类中。
  • 对于较大的页面,可以考虑将它们分解成较小的 PageFragments,例如页眉、表格、页脚等。

聊聊UI自动化的PageObject设计模式

每个功能都应该有一个单独的测试类:

  • 这确保每个测试类都专门用于测试特定的功能。
  • 例如,登录测试类应该只专注于测试登录功能,而不应该测试不相关功能(如用户注册)。
// Single Responsibility Principle (SRP)
// Example: Creating separate test classes for each feature or user story
public class LoginTest
{[Test]public void UserCanLoginSuccessfully(){// Test logic for login functionality}
}public class ShoppingCartTest
{[Test]public void UserCanAddItemToCart(){// Test logic for adding items to the shopping cart}
}public class CheckoutTest
{[Test]public void UserCanCheckoutSuccessfully(){// Test logic for checkout functionality}
}

自定义 WebdriverFactory 类:我们可以自定义每个 WebDriver 实现,并为特定的 WebDriver 添加扩展。

public class WebDriverFactory{private IWebDriver Driver;public IWebDriver InitDriver(AppiumLocalService appiumLocalService, EnvironmentConfig environmentConfig){switch (platformName){case PlatformName.Web:switch (browserName){case BrowserName.FireFox://Add Firefox browser Optionsbreak;case BrowserName.Chrome://Add Chrome browser Optionsbreak;}break;}return Driver;}  }

Helper 类:

  • 你应该避免创建一个包含所有当前方法的helper类,而是考虑将这些类逻辑地分开。
  • 例如,为 FileHelpers、DatabaseHelpers、CsvHelpers、JsonHelpers 等提供不同的帮助器类。

一个方法应该只负责一个动作:

  • 当方法计算一个值时,它应该只专注于执行计算,而不从文件、数据库或其他外部源读取该值。任何额外的操作都应该在单独的类或方法中处理。在创建类或方法时,请记住考虑实例的真正目的,并避免用不相关的逻辑重载它。

2. 开闭原则(OCP)

下面是如何应用开闭原则的例子:

API Data Objects:

  • 假如今天我们已经实现了RegisterApiV1的版本1 (v1) ,即创建了一个注册表数据对象类。
  • 六个月后,RegisterApiV1引入了新版本,增加了额外的逻辑,并向 Register 特性添加了新的字段。
  • 与其更新现有的类,不如基于当前的类创建一个子类,这种方法使我们能够利用现有的类字段/属性,并在新类中合并新的属性。
public class RegisterApiV1{public string FirstName { get; set; }public string LastName { get; set; }public string Email { get; set; }public string Photo { get; set; }public string UId { get; set; }}public class RegisterApiV2 : RegisterApiV1{public DateTime DateOfBirth { get; set; }}

BaseTest类实现:

  • 我们设计一个大多数测试类都继承的基类。在未来,假如你想要添加只与特定测试类相关的特定逻辑。例如,创建一个基于用户类型从Json文件中检索用户数据的帐户功能的基类.
//UIBaseTest
public class UIBaseTest{[AssemblyInitialize]public static void Init(TestContext testContext){//Assembly Initialization code}[TestInitialize]public void Setup(){//SetUp code}[TestCleanup]public void TearDown(){//TearDown code}}// Account BaseTest
public class AccountBaseTest : UIBaseTest{protected static Login GetUserData(string userType){//Method to get userdata from json}}

3. 里式替换原则(LSP)

超类的对象应该可以被其子类的对象替换,而不会影响程序的正确性。在测试自动化中,该原则强调编写独立于被测系统实现细节的测试的重要性。该原则可以确保我们的测试保持健壮,不受底层代码库变更的影响。

例如:使用高级抽象(例如接口或抽象类)而不是具体实现来编写测试。

// Liskov Substitution Principle (LSP)
// Example: Writing tests using high-level abstractions
public interface ILoginPage
{void EnterCredentials(string username, string password);void ClickLoginButton();
}public class LoginPage : ILoginPage
{public void EnterCredentials(string username, string password){// Implementation for entering credentials}public void ClickLoginButton(){// Implementation for clicking login button}
}public class LoginTest
{[Test]public void UserCanLoginSuccessfully(){ILoginPage loginPage = new LoginPage();loginPage.EnterCredentials("username", "password");loginPage.ClickLoginButton();// Test assertion...}
}

在我们的测试自动化解决方案中应用Liskov替换原则有助于确保我们的测试是可维护的、可扩展的和可重用的。这是通过使用多态性来创建适应性和通用的测试来实现的,使它们适合我们应用程序中的变更。

4. 接口隔离原则(ISP)

客户端应该依赖于它需要的具体接口,而不是依赖于一个庞大的接口。在测试自动化的上下文中,该原则促使我们为测试组件设计清晰简洁的接口,有助于创建模块化和可维护的测试模块,其中每个测试只依赖于它需要的接口,而不是与整个系统紧密耦合。

例如:定义接口(例如,ILoginPage,IShoppingCartPage),以确保测试只依赖于它们需要的方法。

// Interface Segregation Principle (ISP)
// Example: Defining small, focused interfaces for test actions
public interface IShoppingCartPage
{void AddItemToCart(string item);void RemoveItemFromCart(string item);
}public class ShoppingCartPage : IShoppingCartPage
{public void AddItemToCart(string item){// Implementation for adding item to cart}public void RemoveItemFromCart(string item){// Implementation for removing item from cart}
}public class ShoppingCartTest
{[Test]public void UserCanAddItemToCart(){IShoppingCartPage shoppingCartPage = new ShoppingCartPage();shoppingCartPage.AddItemToCart("Product A");// Test assertion...}
}

通过在我们的测试自动化中应用接口隔离原则,我们可以使代码更具可扩展性、模块化和可维护性。这种方法允许我们创建适合各种Web元素类型的接口,避免与某些Web元素无关的方法的不必要依赖。

5. 依赖反转原则(DIP)

高层模块不应该依赖于低层模块,它们都应该依赖于抽象。这有助于减少代码之间的耦合度,使得代码更加灵活和可维护。

例如:创建模拟对象,以将测试与外部依赖(如数据库或API)隔离开来。

// Dependency Inversion Principle (DIP)
// Example: Using dependency injection frameworks or creating mock objects
public interface IDatabase
{void SaveData(string data);
}public class Database : IDatabase
{public void SaveData(string data){// Implementation for saving data to the database}
}public class MockDatabase : IDatabase
{public void SaveData(string data){// Mock implementation for testing}
}public class DataProcessor
{private readonly IDatabase _database;public DataProcessor(IDatabase database){_database = database;}public void ProcessData(string data){// Process data..._database.SaveData(data);}
}public class DataProcessorTest
{[Test]public void DataIsSavedToDatabase(){IDatabase mockDatabase = new MockDatabase();DataProcessor dataProcessor = new DataProcessor(mockDatabase);dataProcessor.ProcessData("Test data");// Test assertion...}
}

在测试自动化中采用 SOLID 原则的优点

采用 SOLID 原则可以帮助软件开发人员避免常见的设计问题,并创建敏捷产品。它增强了代码的可读性、可维护性和可测试性。在测试自动化中实现这些原则:

  • 减少依赖性,增强模块化、可测试性和可维护性。
  • 增强代码理解、扩展和可伸缩性,以快速适应业务需求。
  • 改进设计和代码质量,防止单个更改破坏整个应用程序。
  • 提高测试覆盖率并简化调试过程。
  • 减少维护工作量,使代码重构变得快速而轻松。


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/616586.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI PC元年,华为的一张航海图、一艘渡轮和一张船票

今天,从学术研究者到产业投资者,无不认为大模型掀起了一场人工智能的完美风暴。 所谓“完美风暴”,指的是一项新技术的各个要素,以新的方式互相影响、彼此加强,组合在一起形成了摧枯拉朽般的力量。 而我们每个人&#…

数据结构 (JAVA):链表(2)_双向链表(构造、头插、尾插、中间插入、删除等操作及实现代码)

前言 上次,我们介绍了顺序表和单链表的相关概念,以及实现了它们的增加、删除、查找等操作,今天我们介绍另一种链表——双向链表。 一、双向链表 1.1 双向链表的结构: 每个结点存在两个指针域,分别存储该结点的前继结…

云服务器租用一年、1个月优惠价格表,阿里/腾讯/京东/华为云

现在租一个服务器多少一个月?优惠价格低至3.8元1个月,租用一个月云服务器收费价格表:阿里云和腾讯云2核2G3M服务器优惠价格61元一年,折合一个月5元,京东云轻量云主机5.8元一个月,华为云服务器优惠价格3.8元…

Linux02(项目部署,手动和自动部署,JDK版本问题,安装软件,安装软件,安装JDK,Tomcat,MySQL,Irzsz)

目录 一、安装软件 1. 安装准备工作 1 Linux里的软件安装方式 2 上传软件到Linux 3 拍照虚拟机快照 2. 安装JDK 1 卸载自带jdk 2 解压JDK 3 配置环境变量 4 测试JDK 3. 安装Tomcat 1 解压Tomcat 2 修改防火墙设置 3 测试Tomcat 启动Tomcat 访问Tomcat 查看Tom…

Arrow, 一个六边形的 Python 时间库

文章目录 Arrow, 一个六边形的 Python 时间库第一部分:背景介绍第二部分:库是什么?第三部分:如何安装这个库?第四部分:库函数使用方法第五部分:场景应用第六部分:常见Bug及解决方案第…

NzN的数据结构--归并排序及计数排序

篇接上文,今天要学习的是归并排序以及非比较排序--计数排序。这么励志的日更博主,你怎么能不三连一下呢? 目录 一、归并排序 1. 递归实现 2. 非递归实现 3. 特性总结 二、非比较排序--计数排序 三、排序算法复杂度及稳定性分析 一、归并…

03-JAVA设计模式-责任链模式

责任链模式 什么是责任链模式 责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,允许你将请求沿着处理者链进行传递。每个处理者均对请求进行某些处理,并可决定是否将请求沿着链传递下去。这种模式给予请求的处理…

Windows版Apache5.7解压直用(免安装-绿色-项目打包直接使用)

windows下Apache分类 Apache分为 安装版和解压版 安装版: 安装方便,下一步------下一步就OK了,但重装系统更换环境又要重新来一遍,会特别麻烦 解压版(推荐): 这种方式(项目打包特别方便&#…

String类中常见面试题

1.string类属于基本类型吗? string类不是基本类型;它属于引用数据类型 2.操作字符串的类有哪些?有什么区别? 有三种:string,stringBuilder,stringBuffer 区别: String:不可变类,字符串一旦被创建就不能…

给你的AppImage创建桌面快捷方式

原文链接 https://www.cnblogs.com/HGNET/p/16396589.html 运行环境:Ubuntu 22.04 LTS 1.首先准备好AppImage文件并放在一个你知道的地方 2.打开终端,在/usr/share/applications下新建APP.desktop文件(APP可以改成你的应用名称) cd /usr/s…

【C++算法竞赛 · 图论】图的存储

前言 图的存储 邻接矩阵 方法 复杂度 应用 例题 题解 邻接表 方法 复杂度 应用 前言 上一篇文章中(【C算法竞赛 图论】图论基础),介绍了图论相关的概念和一种图的存储的方法,这篇文章将会介绍剩下的两种方法&#xff…

Sonatype Nexus 服务器迁移

因为服务器的升级和调整,有时候会对安装 Sonatype Nexus 的服务器进行迁移到新服务器上。 从技术架构上来说,Sonatype Nexus 我们使用的是 AWS 的存储,所以我们并不需要拷贝大量的数据。 文件夹结构 在备份和恢复之前,我们需要…