我从测试脚本的过程语言开始了我的自动化职业,现在开始学习OOP的概念,但是在学习了OOP的概念之后,我对如何使用封装,继承,多态性和抽象这四个主要的OOP原理不感到自信。测试脚本和设计。我想知道将面向对象的设计用于测试人员的最佳实践。

#1 楼

除了采用这些特定的原理并尝试与之匹配之外,另一种方法可能是着重于:



DRY-确保不要不必要地重复代码

可读-使用真实的英语单词并避免使用大多数缩写词

简单-使用“单一职责”以确保功能仅执行一项操作

Maintainable-目标为了使新手易于理解的代码

为了实现上述目标,您可以使用封装,继承,多态性和抽象,但是它们将是实现上述目标的工具,而不是单独实现这些目标的工具。 。

评论


+1表示建议DRY。我认为,如果有人只专注于保持代码DRY,他们可以走很长的路...而无需了解太多技术术语。

– Vishal Aggarwal
18年5月16日在11:31



#2 楼

我不认为对于测试人员如何使用OOP原则可能会有一些特别的建议,因为一旦您打开IDE并开始编写代码,您就不再是测试人员,而是开始成为测试人员。但是,下面是我的经验显示的内容。

封装

您将在测试中使用此原理,以将公共方法和字段与私有方法和字段分开。当您编写某些代码时(尤其是在开发测试框架时),您可能拥有在某些规定的情况下或以某些规定的顺序被调用的代码,而在不同情况下调用该代码可能会破坏框架状态。因此,您将该代码标记为私有,以便使用您的框架的测试人员将无法调用该代码段并引入不一致之处。

将某种形式的私有和公共部分隔离开也是有意义的。测试类中的实用程序代码,即使您是唯一的测试人员,因为您可能会忘记最初将什么逻辑放在代码中。

继承

它被广泛用于测试中。可以使用它(但不限于此)通过其他测试来扩展现有测试类,或将公共实用程序代码存储在父类中。这也广泛用于Page Object设计模式中,因为真实UI的各个部分通常会扩展该UI的其他部分,因此使用继承机制将该模型转移到您的Page Object模型是有意义的。

多态性

多态性通常用于测试框架开发中,而不是测试本身中。您可能希望测试框架方法支持不同类型的传入数据,以便引入名称相同但接受不同类型参数的方法。当您引入新的公共代码并尝试为使用框架的旧测试保持向后兼容性时,或者仅向框架引入一些灵活性时,可以使用此方法。例如,您提供了一种重置测试数据的方法。您的框架支持将测试数据存储在文件或数据库中。因此,您将介绍方法resetTestData。一个接受对文件的引用,另一个接受对数据库的引用。后面的示例也可以使用Abstraction的概念来实现。

抽象

抽象广泛用于测试框架开发。使用抽象原理的示例是众所周知的WebDriver。在开发框架时,您会将某些功能的实现委派给使用框架的人员。这为您的框架增加了一些灵活性和可扩展性。让我们看一下前面的原理描述中显示的示例。与其介绍不同的resetTestData方法,不如像abstraction那样介绍TestDataSource,并定义实现该抽象的类将要实现的方法。假设您定义了抽象规定要实现reset方法,并且您不在乎该方法的实现方式(该方法背后的逻辑是什么)。

在此体系结构中,您的框架只知道它应该对实现TestDataSource概念的对象调用reset。使用您的框架的人比您更了解您,他们以哪种格式存储测试数据,因此它们不受文件或数据库的限制,可以自由使用自己的存储。这样就减少了“现成”的功能,但使框架更加灵活(通常框架开发人员提供抽象的一些基本实现,以便人们在某些基本环境中开始使用它的技能就会减少)。

评论


很好的答案!我希望我可以多次投票赞成。

– Vishal Aggarwal
18年5月16日在11:28

@VishalAggarwal-您总是可以分配赏金来奖励:-)

–Peter M.-代表莫妮卡(Monica)
18年5月16日在14:17

继续@VishalAggarwal认为这个问题的答案值得赏识;-)

– Nitin Rastogi
18年5月17日在3:47



@ NitinRastogi,如果你们仔细阅读,我称赞了答案,而不是问题:)

– Vishal Aggarwal
18年5月17日在7:49



@VishalAggarwal赏金计划仅是一个很好的答案,而不是这个问题:)

– Nitin Rastogi
18年5月17日在8:41

#3 楼

OOP概念在开发结构良好的测试自动化框架中起着重要作用。仅分享测试自动化中常见OOP应用程序的一些简单示例。我在这些示例中使用Java和Selenium Webdriver。

封装:

封装网页数据。在这里,数据表示页面的元素,例如文本,按钮等。

,假设您正在为StackOverflow的“用户配置文件”页面编写测试自动化程序(例如:https://sqa.stackexchange.com/users/ 20681 / shahid?tab = profile)。您想从配置文件页面获取用户名。因此,您可以封装元素并编写公共方法“ getUserName()”来访问数据。

public class ProfilePage {

    private WebDriver driver;
    private By userName = By.xpath("//h2[@class='user-card-name']"); // we are hiding the element so that it won't be directly accessible

    public ProfilePage(WebDriver driver) {
        this.driver = driver;
    }

    // public method to access the private data
    public String getUserName() {
        return driver.findElement(userName).getText();
    }
}


继承:

包含多个页面的网站,可能会有某些元素在每个页面中都很常见。例如:每页中都存在页眉,菜单,页脚等。因此,在每个页面或类中声明这些元素将带来很多冗余。我们可以做的是为那些常见元素创建一个单独的类。然后其他页面的类将继承该类。举一个简单的例子来说明这一点:

在sqa.stackexchange.com网站上,顶部有一些导航链接,例如“问题”,“标签”,“用户”等。无论您在本网站的何处,这些链接都会显示在每个页面中。由于这些元素在每个页面中都是通用的,因此我们将它们放在一个类中。

public class BasicPage {
    private WebDriver driver;

    private By questionNavLink = By.xpath("//a[@id='nav-questions']");
    private By tagNavLink = By.xpath("//a[@id='nav-tags']");
    private By userNavLink = By.xpath("//a[@id='nav-users']");

    public BasicPage(WebDriver driver) {
        this.driver = driver;
    }

    // For simplification, we are returning nothing from those navigation methods. Otherwise, we would have returned the new web pages got after navigation.

    public void goToQuestions() {
        driver.findElement(questionNavLink).click();
    }

    public void goToTags() {
        driver.findElement(tagNavLink).click();
    }

    public void goToUsers() {
        driver.findElement(userNavLink).click();
    }
}


现在,任何其他页面都可以通过继承来访问所有这些导航方法BasicPage类。

多态性:

这是我们经常使用的另一个常见概念。一个基本的示例是Selenium WebDriver脚本中最基本的代码。要在Selenium中为Chrome浏览器初始化Webdriver,我们使用:

WebDriver driver = new ChromeDriver();


再次,我们经常需要重写和重载方法,这是多态性的一部分。

#4 楼

我进入测试自动化领域已有几年了。一方面,我会说,就实践而言,应该将测试自动化项目与任何其他Java项目一样对待-您应该使用可用的Java功能,以便最终获得高质量的软件项目。我认为这是最重要的方面。
维护是关键
由于被测应用程序会定期更改(假设敏捷),因此您需要编写测试自动化项目,以便可以快速,干净地进行更改它可以满足产品的变化。这意味着:

避免使用上帝模式。
有许多小类而不是几个大上帝类(这是一种反模式)。
不要用相同的字符串进行硬编码在多个地方。理想情况下,将它们作为相关类顶部的公共静态最终String放置,以便其他人可以轻松找到它。
如果您遇到诸如用户名,状态,有效负载或其他对象这样的东西,则每个对象都有默认值,然后,checkValid()等会为它们中的每一个创建一个专用类-即使它只是String的包装。这有一些好处。
在适当的地方使用抽象和其他OOP概念。如果您是初学者,我建议您阅读几本书,尤其是Clean Code。
我发现构建器模式通常对于测试自动化,建立用户,请求主体或其他对象很有用。它足够灵活以适应将来的变化,同时也严格要求人们遵守您希望如何使用它。我还看到了工厂模式在测试自动化中多次使用。策略模式也是一种外观。
基础知识不能高估。准确命名事物,进行代码自我记录(人们很少保持注释最新)

我要说的是,测试自动化的主要缺点是Java经验非常有限的人最终会从事它的工作(例如,想要转换为自动化角色的手动测试人员)。因此,我本人只专注于上面列出的内容,并且只是

按照Clean Code保持小而简单的内容。
使类尽可能地映射到现实世界。
/>
如果您知道要测试的内容,例如它是Web / api /嵌入式等,则可能会得到更好的答案。

#5 楼

除了其他出色的答案外,我还给出一个简单的建议,只是着重于使您的代码在各个级别上保持干燥。这个简单的规则,如果虔诚地遵循,可以使一名测试人员走上干净代码的旅程。 >
如果深入思考,他会发现许多概念本身只是DRY概念的一种应用,例如继承,抽象等。