在測試自動化中使用Java枚舉

在決定用于存儲測試數(shù)據(jù)的數(shù)據(jù)類型時,您可能需要滿足以下條件:
允許聲明多個屬性
無行為或行為極少
允許輕松創(chuàng)建多個相似實體
對象幾乎可以滿足這些要求。但是,創(chuàng)建多個實體將意味著創(chuàng)建幾個僅具有少量屬性且沒有行為或行為最少的對象。最小的行為轉(zhuǎn)化為少量的方法。基本上,對于您需要的每個實體,都必須創(chuàng)建一個新的對象。那將是浪費。相反,可以使用一種特殊類型的Object?Enum。
我們可以使用Enums來表示概念,例如:工作日,一年中的月份,瀏覽器或語言。在本文中,我想舉例說明Enums的用法,該枚舉具有多個屬性和一個表示國家的構造函數(shù)。您可以在本文末尾找到GitHub鏈接,以鏈接到此處示例的所有代碼。有關枚舉是什么的信息,請參考官方文檔。
在測試中使用Java枚舉:國家/地區(qū)示例
對于此示例,讓我們考慮一下,在測試中,您需要填寫國家/地區(qū)特定的注冊表。您需要在此表單中提供的一些詳細信息是:國家/地區(qū),該國家/地區(qū)的城市以及國家/地區(qū)專用的電話號碼,所有這些都屬于您要填寫注冊表格的客戶。您正在使用的網(wǎng)站在全球許多國家/地區(qū)都可以使用。
為了進行測試,讓我們縮小將要使用的國家/地區(qū)的范圍:奧地利,愛沙尼亞和西班牙。這些國家/地區(qū)中的每個國家/地區(qū)都有我們需要在注冊表格中提供的3個屬性:國家/地區(qū)名稱,城市列表和電話前綴。基于此前綴,我們可以生成一個測試電話號碼。為了代表每個國家/地區(qū),我們將使用枚舉。用于表示國家/地區(qū)的常數(shù)值為: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 Listcities; public int phoneNumberPrefix;Country(String label, Listcities, int phoneNumberPrefix) { this.label = label;this.cities = cities;this.phoneNumberPrefix = phoneNumberPrefix;}}
首先我們?yōu)閲页?shù)指定允許值的集合,以及所有屬性的允許值。我們通過聲明標簽,城市和phoneNumberPrefix來定義這些屬性的類型。它們是:一個字符串,一個字符串列表和一個整數(shù)。
構造函數(shù)在內(nèi)部用于生成Enum值。因此,例如,“ AT”具有屬性,其順序與構造函數(shù)中參數(shù)的順序相對應:“?標簽?”屬性值為“奧地利”,屬于該國家/地區(qū)的“?城市?”?列表為:“維也納”, “ Salzburg”,“ Innsbruck”和“?phoneNumberPrefix?”為43。
我們可以按如下方式檢索與Enum常量相對應的屬性:Country.CONSTANT.propertyName。例如:Country.AT.label將給我們“奧地利”。如您所見,Country屬性是靜態(tài)的。
在注冊表格上,從下拉列表中選擇國家,從另一個下拉列表中選擇城市,并通過在字段中鍵入來提供電話號碼。
為國家/地區(qū)特定信息創(chuàng)建的Page類包含以下條目:
private WebElement countryDropdown;private WebElement cityDropdown;public WebElement phoneNumberField;public WebElement submitButton;public Select countrySelect() {return new Select(countryDropdown);}public Select citySelect() {return new Select(cityDropdown);}
countrySelect()方法將返回一個Select(引用)國家/地區(qū)下拉列表。同樣,citySelect()方法返回引用城市下拉菜單的Select。phoneNumberField WebElement將用于輸入電話號碼。
在本文中,我將省略打開瀏覽器,打開網(wǎng)頁和關閉瀏覽器的部分。您可以在本文結尾處提供的GitHub存儲庫中看到所有這些部分。
方案1:填寫西班牙客戶的注冊表
打開瀏覽器并訪問注冊頁面后,測試將需要填寫西班牙客戶的詳細信息。我們將選擇國家/地區(qū),然后選擇瓦倫西亞市,然后輸入由10位數(shù)字組成的隨機電話號碼。注冊表的國家部分如下所示:

因此,我們將為此活動創(chuàng)建一個新測試:
void selectCountryCityAndTypePhoneNumber() {}
首先,我們將選擇國家。這意味著,從國家/地區(qū)下拉列表中,我們將選擇與“ 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));現(xiàn)在,最后一步意味著需要生成電話號碼,其第一個數(shù)字代表國家/地區(qū)前綴。可以從枚舉中檢索前綴,如下所示:Country.ES.phoneNumberPrefix。生成由10個字符組成的隨機數(shù):Country.ES.phoneNumberPrefix + randomNumeric(8)。
為了使用“ randomNumeric”方法,您需要首先從Apache Commons庫中導入相應的類,如下所示:
import?static?org.apache.commons.lang3.RandomStringUtils.randomNumeric;如果您的項目中沒有此庫,則應將其導入。對于Maven項目,您只需要在“ pom.xml”文件中添加以下條目(確保您使用的是最新版本):
<dependency><groupId>org.apache.commonsgroupId><artifactId>commons-lang3artifactId><version>3.9version>dependency>
完整的測試現(xiàn)在是:
@Testvoid selectCountryCityAndTypePhoneNumber() {page.countrySelect().selectByVisibleText(Country.ES.label);page.citySelect().selectByVisibleText(Country.ES.cities.get(2));page.phoneNumberField.sendKeys(Country.ES.phoneNumberPrefix + randomNumeric(8));}
方案2:檢查可用的國家
在第二和第三測試場景中,我們將檢查國家和城市下拉列表僅顯示期望值。此示例中的下拉列表的工作方式如下:未打開(未單擊它們)時,“國家/地區(qū)”下拉列表顯示為空選擇,而“城市”下拉列表則完全為空。此時的城市下拉列表已禁用,您無法從中選擇任何選項。

單擊國家/地區(qū)下拉列表后,您將看到可用選項列表。我們希望該列表具有與在Enum中指定為'?label?'屬性的值相同的值。但是,我們需要記住,出于顯示目的,國家/地區(qū)下拉列表還包含一個不帶任何文本的條目。要求說我們不想在下拉列表中有任何預定義的選擇。

選擇國家/地區(qū)后,即可使用城市下拉菜單進行互動。取決于您選擇的國家,單擊城市下拉列表后,您應該只會看到與該國家相對應的城市。請記住,此下拉菜單還具有空文本選項,用于顯示。

我們要編寫的測試需要檢查我們想要并已存儲在Enum中的所有國家和城市是否存在于其相應的下拉列表中。還要記住,每個下拉列表中都有空條目。
?
讓我們從方案編號2開始,即檢查國家/地區(qū)下拉列表是否包含正確的值。我們將首先構建“預期”內(nèi)容。我們知道我們已經(jīng)將期望值存儲為Enum中的“?label?”參數(shù),但是我們還需要處理下拉菜單中顯示的空文本選項。請記住,我們將使用Selenium讀取網(wǎng)頁中的值,并將它們作為String返回,我們可以創(chuàng)建一個預期的String國家值列表。首先,我將創(chuàng)建列表并向其中添加第一個元素,它是一個空字符串。這將對應于國家下拉列表中的空字符串。
List<String> expectedCountries = new ArrayList<>();expectedCountries.add("");
現(xiàn)在,我們需要添加枚舉中所有的'?label?'值。為此,我們需要遍歷所有Enum項,并將每個對應的“?label?”字符串值添加到預期字符串列表中。我們將使用'?Country.values()?'方法遍歷每個Enum條目。
for (Country country : Country.values()) {expectedCountries.add(country.label);}
此時,我們的預期國家列表包含4個條目:“”,“奧地利”,“愛沙尼亞”,“西班牙”。
現(xiàn)在,我們可以從網(wǎng)頁上讀取國家/地區(qū)值,并將其存儲到“實際”值列表中。因為我們正在處理“選擇”,所以我們需要遍歷屬于“選擇”的所有“選項” 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);
完整代碼如下:
@Testvoid checkCountries() {ListexpectedCountries = new ArrayList<>(); expectedCountries.add("");for (Country country : Country.values()) {expectedCountries.add(country.label);}ListactualCountries = new ArrayList<>(); for (WebElement option : page.countrySelect().getOptions()) {actualCountries.add(option.getText());}Collections.sort(expectedCountries);Collections.sort(actualCountries);assertEquals(expectedCountries, actualCountries);}
方案3:檢查可用城市
在我們之前的場景中,我們實際上不需要與任何下拉列表進行交互。但是,在這種情況下,我們需要檢查每個選定的國家/地區(qū),在城市下拉列表中僅顯示正確的城市。因為JavaScript是在從國家/地區(qū)下拉列表中選擇一個國家/地區(qū)后將信息加載到城市/下拉菜單中的一種,所以該測試將:選擇每個國家/地區(qū),并針對每個選定的國家/地區(qū)檢查城市下拉列表。
讓我們通過遍歷可用的Enum條目開始編寫測試:
for?(Country?country?:?Country.values())?{接下來,在“ for”循環(huán)中,讓我們從“國家/地區(qū)”下拉列表中選擇與當前Enum條目的“?label?”屬性相對應的國家/地區(qū):
page.countrySelect().selectByVisibleText(country.label);此時,我們希望在城市下拉列表中填充與所選國家/地區(qū)對應的值。為了確保下拉選項正確,我們將首先創(chuàng)建“實際”城市名稱列表。我們將從網(wǎng)頁上讀取以下值:
List<String> actualCities = new ArrayList<>();for (WebElement option : page.citySelect().getOptions()) {actualCities.add(option.getText());}
我們還必須創(chuàng)建預期城市名稱列表。在枚舉中,這些存儲為字符串屬性的“?city?”列表。我們將通過首先向列表中添加一個空字符串來創(chuàng)建期望值列表。然后,我們將使用'addAll()'方法立即添加'?城市?'列表中的所有項目。
List<String> expectedCities = new ArrayList<>();expectedCities.add(0, "");expectedCities.addAll(country.cities);
現(xiàn)在剩下的唯一事情是比較實際值列表和期望值列表。當然,對這兩個列表進行排序之后。
Collections.sort(expectedCities);Collections.sort(actualCities);assertEquals(expectedCities, actualCities);
因此,對于這種情況,在遍歷每個國家/地區(qū)時,我們正在檢查與該國家/地區(qū)對應的城市列表。為每個國家/地區(qū)從頭開始創(chuàng)建預期和實際城市列表。它們僅包含與該國家/地區(qū)對應的信息。整個測試現(xiàn)在看起來像:
@Testvoid checkCities() {for (Country country : Country.values()) {page.countrySelect().selectByVisibleText(country.label);ListactualCities = new ArrayList<>(); for (WebElement option : page.citySelect().getOptions()) {actualCities.add(option.getText());}ListexpectedCities = new ArrayList<>(); expectedCities.add(0, "");expectedCities.addAll(country.cities);Collections.sort(expectedCities);Collections.sort(actualCities);assertEquals(expectedCities, actualCities);}}

