专栏首页用户7466307的专栏在测试自动化中使用Java枚举

在测试自动化中使用Java枚举

在决定用于存储测试数据的数据类型时,您可能需要满足以下条件:

  • 允许声明多个属性
  • 无行为或行为极少
  • 允许轻松创建多个相似实体

对象几乎可以满足这些要求。但是,创建多个实体将意味着创建几个仅具有少量属性且没有行为或行为最少的对象。最小的行为转化为少量的方法。基本上,对于您需要的每个实体,都必须创建一个新的对象。那将是浪费。相反,可以使用一种特殊类型的Object Enum。

我们可以使用Enums来表示概念,例如:工作日,一年中的月份,浏览器或语言。在本文中,我想举例说明Enums的用法,该枚举具有多个属性和一个表示国家的构造函数。您可以在本文末尾找到GitHub链接,以链接到此处示例的所有代码。有关枚举是什么的信息,请参考官方文档。

在测试中使用Java枚举:国家/地区示例

对于此示例,让我们考虑一下,在测试中,您需要填写国家/地区特定的注册表。您需要在此表单中提供的一些详细信息是:国家/地区,该国家/地区的城市以及国家/地区专用的电话号码,所有这些都属于您要填写注册表格的客户。您正在使用的网站在全球许多国家/地区都可以使用。

为了进行测试,让我们缩小将要使用的国家/地区的范围:奥地利,爱沙尼亚和西班牙。这些国家/地区中的每个国家/地区都有我们需要在注册表格中提供的3个属性:国家/地区名称,城市列表和电话前缀。基于此前缀,我们可以生成一个测试电话号码。为了代表每个国家/地区,我们将使用枚举。用于表示国家/地区的常数值为:AT,EE和ES。

我们将声明枚举如下:

public enum Country {
    AT("Austria", Arrays.asList("Vienna", "Salzburg", "Innsbruck"), 43),
    EE("Estonia", Arrays.asList("Tallinn", "Haapsalu", "Tartu"), 372),
    ES("Spain", Arrays.asList("Malaga","Madrid","Valencia","Corralejo"), 34);

    public final String label;
    public final List<String> cities;
    public int phoneNumberPrefix;

    Country(String label, List<String> cities, int phoneNumberPrefix) {
        this.label = label;
        this.cities = cities;
        this.phoneNumberPrefix = phoneNumberPrefix;
    }
}

首先我们为国家常数指定允许值的集合,以及所有属性的允许值。我们通过声明标签,城市和phoneNumberPrefix来定义这些属性的类型。它们是:一个字符串,一个字符串列表和一个整数。

构造函数在内部用于生成Enum值。因此,例如,“ AT”具有属性,其顺序与构造函数中参数的顺序相对应:“ 标签 ”属性值为“奥地利”,属于该国家/地区的“ 城市 ” 列表为:“维也纳”, “ Salzburg”,“ Innsbruck”和“ phoneNumberPrefix ”为43。

我们可以按如下方式检索与Enum常量相对应的属性:Country.CONSTANT.propertyName。例如:Country.AT.label将给我们“奥地利”。如您所见,Country属性是静态的。

在注册表格上,从下拉列表中选择国家,从另一个下拉列表中选择城市,并通过在字段中键入来提供电话号码。

为国家/地区特定信息创建的Page类包含以下条目:

@FindBy(css = "#country") private WebElement countryDropdown;
@FindBy(css = "#city") private WebElement cityDropdown;
@FindBy(css = "#phone") public WebElement phoneNumberField;
@FindBy(css = "[type='submit']") public WebElement submitButton;

public Select countrySelect() {
    return new Select(countryDropdown);
}

public Select citySelect() {
    return new Select(cityDropdown);
}

countrySelect()方法将返回一个Select(引用)国家/地区下拉列表。同样,citySelect()方法返回引用城市下拉菜单的Select。phoneNumberField WebElement将用于输入电话号码。

在本文中,我将省略打开浏览器,打开网页和关闭浏览器的部分。您可以在本文结尾处提供的GitHub存储库中看到所有这些部分。

方案1:填写西班牙客户的注册表

打开浏览器并访问注册页面后,测试将需要填写西班牙客户的详细信息。我们将选择国家/地区,然后选择瓦伦西亚市,然后输入由10位数字组成的随机电话号码。注册表的国家部分如下所示:

因此,我们将为此活动创建一个新测试:

@Test
void selectCountryCityAndTypePhoneNumber() {
}

首先,我们将选择国家。这意味着,从国家/地区下拉列表中,我们将选择与“ ES”枚举条目的“ 标签 ”属性相对应的值。这很容易检索:Country.ES.label。选择国家的步骤如下:

page.countrySelect().selectByVisibleText(Country.ES.label);

接下来,我们需要从相应的下拉列表中选择城市。完成访问城市列表的操作:Country.ES.cities。访问与Valencia相对应的List元素(第三个元素)已完成:Country.ES.cities.get(2)。从城市下拉列表中选择此值:

page.citySelect().selectByVisibleText(Country.ES.cities.get(2));

现在,最后一步意味着需要生成电话号码,其第一个数字代表国家/地区前缀。可以从枚举中检索前缀,如下所示:Country.ES.phoneNumberPrefix。生成由10个字符组成的随机数:Country.ES.phoneNumberPrefix + randomNumeric(8)。

为了使用“ randomNumeric”方法,您需要首先从Apache Commons库中导入相应的类,如下所示:

import static org.apache.commons.lang3.RandomStringUtils.randomNumeric;

如果您的项目中没有此库,则应将其导入。对于Maven项目,您只需要在“ pom.xml”文件中添加以下条目(确保您使用的是最新版本):

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.9</version>
</dependency>

完整的测试现在是:

@Test
void selectCountryCityAndTypePhoneNumber() {
    page.countrySelect().selectByVisibleText(Country.ES.label);
    page.citySelect().selectByVisibleText(Country.ES.cities.get(2));
    page.phoneNumberField.sendKeys(Country.ES.phoneNumberPrefix + randomNumeric(8));
}

方案2:检查可用的国家

在第二和第三测试场景中,我们将检查国家和城市下拉列表仅显示期望值。此示例中的下拉列表的工作方式如下:未打开(未单击它们)时,“国家/地区”下拉列表显示为空选择,而“城市”下拉列表则完全为空。此时的城市下拉列表已禁用,您无法从中选择任何选项。

单击国家/地区下拉列表后,您将看到可用选项列表。我们希望该列表具有与在Enum中指定为' label '属性的值相同的值。但是,我们需要记住,出于显示目的,国家/地区下拉列表还包含一个不带任何文本的条目。要求说我们不想在下拉列表中有任何预定义的选择。

选择国家/地区后,即可使用城市下拉菜单进行互动。取决于您选择的国家,单击城市下拉列表后,您应该只会看到与该国家相对应的城市。请记住,此下拉菜单还具有空文本选项,用于显示。

我们要编写的测试需要检查我们想要并已存储在Enum中的所有国家和城市是否存在于其相应的下拉列表中。还要记住,每个下拉列表中都有空条目。

让我们从方案编号2开始,即检查国家/地区下拉列表是否包含正确的值。我们将首先构建“预期”内容。我们知道我们已经将期望值存储为Enum中的“ label ”参数,但是我们还需要处理下拉菜单中显示的空文本选项。请记住,我们将使用Selenium读取网页中的值,并将它们作为String返回,我们可以创建一个预期的String国家值列表。首先,我将创建列表并向其中添加第一个元素,它是一个空字符串。这将对应于国家下拉列表中的空字符串。

List<String> expectedCountries = new ArrayList<>();
expectedCountries.add("");

现在,我们需要添加枚举中所有的' label '值。为此,我们需要遍历所有Enum项,并将每个对应的“ label ”字符串值添加到预期字符串列表中。我们将使用' Country.values() '方法遍历每个Enum条目。

for (Country country : Country.values()) {
    expectedCountries.add(country.label);
}

此时,我们的预期国家列表包含4个条目:“”,“奥地利”,“爱沙尼亚”,“西班牙”。

现在,我们可以从网页上读取国家/地区值,并将其存储到“实际”值列表中。因为我们正在处理“选择”,所以我们需要遍历属于“选择”的所有“选项” WebElement。我们需要将“ getText()”应用于每个“选项”,并将这些结果字符串添加到实际字符串列表中。

List<String> actualCountries = new ArrayList<>();
for (WebElement option : page.countrySelect().getOptions()) {
    actualCountries.add(option.getText());
}

在比较预期列表和实际列表之前,我们需要考虑一下,枚举标签和下拉选项值的顺序可能不相同。因此,我们应该对它们进行排序,然后进行比较。

Collections.sort(expectedCountries);
Collections.sort(actualCountries);
assertEquals(expectedCountries, actualCountries);

完整代码如下:

@Test
void checkCountries() {
    List<String> expectedCountries = new ArrayList<>();
    expectedCountries.add("");
    for (Country country : Country.values()) {
        expectedCountries.add(country.label);
    }
    List<String> actualCountries = new ArrayList<>();
    for (WebElement option : page.countrySelect().getOptions()) {
        actualCountries.add(option.getText());
    }
    Collections.sort(expectedCountries);
    Collections.sort(actualCountries);
    assertEquals(expectedCountries, actualCountries);
}

方案3:检查可用城市

在我们之前的场景中,我们实际上不需要与任何下拉列表进行交互。但是,在这种情况下,我们需要检查每个选定的国家/地区,在城市下拉列表中仅显示正确的城市。因为JavaScript是在从国家/地区下拉列表中选择一个国家/地区后将信息加载到城市/下拉菜单中的一种,所以该测试将:选择每个国家/地区,并针对每个选定的国家/地区检查城市下拉列表。

让我们通过遍历可用的Enum条目开始编写测试:

for (Country country : Country.values()) {

接下来,在“ for”循环中,让我们从“国家/地区”下拉列表中选择与当前Enum条目的“ label ”属性相对应的国家/地区:

page.countrySelect().selectByVisibleText(country.label);

此时,我们希望在城市下拉列表中填充与所选国家/地区对应的值。为了确保下拉选项正确,我们将首先创建“实际”城市名称列表。我们将从网页上读取以下值:

List<String> actualCities = new ArrayList<>();
for (WebElement option : page.citySelect().getOptions()) {
    actualCities.add(option.getText());
}

我们还必须创建预期城市名称列表。在枚举中,这些存储为字符串属性的“ city ”列表。我们将通过首先向列表中添加一个空字符串来创建期望值列表。然后,我们将使用'addAll()'方法立即添加' 城市 '列表中的所有项目。

List<String> expectedCities = new ArrayList<>();
expectedCities.add(0, "");
expectedCities.addAll(country.cities);

现在剩下的唯一事情是比较实际值列表和期望值列表。当然,对这两个列表进行排序之后。

Collections.sort(expectedCities);
Collections.sort(actualCities);
assertEquals(expectedCities, actualCities);

因此,对于这种情况,在遍历每个国家/地区时,我们正在检查与该国家/地区对应的城市列表。为每个国家/地区从头开始创建预期和实际城市列表。它们仅包含与该国家/地区对应的信息。整个测试现在看起来像:

@Test
void checkCities() {
    for (Country country : Country.values()) {
        page.countrySelect().selectByVisibleText(country.label);
        List<String> actualCities = new ArrayList<>();
        for (WebElement option : page.citySelect().getOptions()) {
            actualCities.add(option.getText());
        }
        List<String> expectedCities = new ArrayList<>();
        expectedCities.add(0, "");
        expectedCities.addAll(country.cities);
        Collections.sort(expectedCities);
        Collections.sort(actualCities);
        assertEquals(expectedCities, actualCities);
    }
}

本文分享自微信公众号 - 软件测试test(gh_d29759b02f67),作者:Coldrain

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 关于Scrapy爬虫项目运行和调试的小技巧(上篇)

    扫除运行Scrapy爬虫程序的bug之后,现在便可以开始进行编写爬虫逻辑了。在正式开始爬虫编写之前,在这里介绍四种小技巧,可以方便我们操纵和调试爬虫。

    用户7466307
  • Python中的正则表达式和示例

    模块正则表达式(RE)指定与其匹配的一组字符串(模式)。 为了理解RE的类比,MetaCharacter是有用的,重要的,并且将在模块re的功能中使用。 一共有...

    用户7466307
  • 说几个能帮助你高效工作的插件

    平时我们做开发的时候有不少(很多)的人都在使用VSCode,现在来介绍几款方便又好用的VSCode插件给大家,大家收好~

    用户7466307
  • AI化身空间站故障排查小助手​!借助AI和声音实现未雨绸缪

    我们都在电影中见过这种场景,例如在潜艇或宇宙飞船上,总工程师会突然竖起耳朵听背景嗡嗡声并说“出问题了”。博世希望教会计算机在现实生活中做到这一点,并到国际空间站...

    大数据文摘
  • 新闻动态|腾讯披露AI+产业成绩单,落地应用上百个行业

    “腾讯AI在消费互联网领域积累了海量实践,目前已经在产业互联网领域 广泛落地。”腾讯副总裁姚星认为,当前AI已进入产业应用时代。

    优图实验室
  • 小白学 Scrapy 爬虫系列之一:准备实验机器

    本系列文章中,笔者将带领大家从零开始学习爬虫编写。在跟随笔者一起实操之前,要求大家有一定的 Python 基础。之前没接触过的同学也不用担心,Python 号称...

    编程派
  • ORA-00439的解决(笔记93天)

    今天用gc配置了stream后,重启数据库后发现有以下的问题 SQL> startup ORA-00439: feature not enabled: Real...

    jeanron100
  • JDK1.9-File综合案例

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    cwl_java
  • Python爬虫小白入门(一)

    开篇语 本篇文章适用人群 >有一点点语法基础,至少知道Python这个东西,如果有其他方面语言的基础那也凑合 >会一点点Linux系统的操作,最好是ubunt...

    用户1687088
  • 写了10年代码之后,我学到的7个绝对真理

    导读:明年就是我的开发者生涯的第十个年头。整整十年!我有三分之二的时间都用在了 Web 开发上。在孩童时代,当其他小孩还在学习乐器或芭蕾舞的时候,我在自己的卧室...

    华章科技

扫码关注云+社区

领取腾讯云代金券