是时候来学习SOLID中的“L”了! Liskov替换原则是以计算机科学家Barbara Liskov的名字命名的,她在1987年首次提出了这一概念。该原则指出,你应该能够在不进行任何更改情况下,在程序中使用子类对象替换超类对象。
为了能够更好地理解这一点,让我们使用一个测试人员非常熟悉的例子:等待一个元素。下面是一个名为waitforeelement的类,它有两个方法: waitForElementToBeVisible和waitForElementToBeClickable:
class WaitForElement {
constructor() {}
async waitForElementToBeVisible(locator) {
await driver
.wait(until.elementIsVisible
(driver.findElement(locator)),10000)
}
async waitForElementToBeClickable(locator) {
await driver
.wait(until.elementIsEnabled
(driver.findElement(locator)),10000)
}
}
这个类可以用来定位各种类型的元素。现在假设测试人员创建了一个专门用于单击下拉列表中的元素的类,它扩展了现有的waitforement类:
class WaitForDropdownSelection extends WaitForElement {
constructor() {
super()
}
async waitForElementToBeClickable(locator) {
let selection = await driver
.wait(until.elementIsEnabled(driver.findElement(locator)),
10000)
selection.click()
}
}
如果我们要使用waitforeement类从城市的下拉列表中选择一个城市,它看起来像这样:
let waitForInstance = new WaitForElement()
waitForInstance.waitForElementToBeVisible
(By.id(‘cities’)).click()
waitForInstance.waitForElementToBeClickable
(By.id(‘New York’)).click()
但是如果我们要使用WaitForDropdownSelection类来选择一个城市,它看起来像这样:
let waitForDropdownInstance = new WaitForDropdownSelection()
waitForDropdownInstance.waitForElementToBeVisible
(By.id(‘cities’)).click()
waitForDropdownInstance.waitForElementToBeClickable
(By.id(‘New York’))
你看出区别了吗?当我们在WaitForDropdownSelection类中使用waitForElementToBeClickable方法时,该方法包含点击元素的操作:
selection.click()
但是,当我们在waitforeelement类中使用waitForElementToBeClickable方法时,该方法不包含点击操作。 这违反了 Liskov 替换原则。
为了解决这个问题,我们可以更新WaitForDropdownSelection中的waitForElementToBeClickable方法,使其不包含 click ( )命令,然后添加第二个方法,用于等待并点击。
class WaitForDropdownSelection extends WaitForElement {
constructor() {
super()
}
async waitForElementToBeClickable(locator) {
await driver
.wait(until.elementIsEnabled
(driver.findElement(locator)), 10000)
}
async waitForElementAndClick(locator) {
let selection = await driver
.wait(until.elementIsEnabled
(driver.findElement(locator)), 10000)
selection.click()
}
}
现在我们已经对代码做了一些调整,使这些类可以互换使用。
使用WaitForElement类:
let waitForInstance = new WaitForElement()
waitForInstance.waitForElementToBeVisible
(By.id(‘cities’)).click()
waitForInstance.waitForElementToBeClickable
(By.id(‘New York’)).click()
使用WaitForDropdownSelection类:
let waitForDropdownInstance = new WaitForDropdownSelection()
waitForDropdownInstance.waitForElementToBeVisible
(By.id(‘cities’)).click()
waitForDropdownInstance.waitForElementToBeClickable
(By.id(‘New York’)).click()
或者我们可以使用WaitForDropdownSelection类中的新方法来代替:
let waitForDropdownInstance = new WaitForDropdownSelection()
waitForDropdownInstance.waitForElementToBeVisible
(By.id(‘cities’)).click()
waitForDropdownInstance.waitForElementAndClick
(By.id(‘New York’))
使用扩展类是在添加新功能时避免重复代码的好方法。但要确保在扩展类时,这些方法是可以互通的。