Selenium是一款基于Web功能测试的自动化测试框架。它的应运而生经历了不同时代,组成了一系列工具集,已然成为了Web功能自动化测试的首选“武器”。
本次主要基于Web功能自动化中常见面试题和大家交流分享。下面涉及到的代码示例以JAVA语言为例,技术点笔试/面试题,共30问,分为上下两个篇章;上篇主要关注于Selenium核心技术点。
Q:Selenium中有哪些不同类型的定位器?
答:定位器可以看作一个地址,用于在网页中唯一标识一个页面元素,为了准确地识别Web元素,Selenium中有8种不同的定位方式:ID;ClassName;Name;TagName;LinkText;PartialLinkText;Xpath;CSS Selector。
Q:什么是XPath?
答:元素定位方式的一种,根据XML路径来定位Web元素,使用XPath定位元素的基本原理是在整个页面的各个元素间进行遍历,从而使用户能根据与当前元素关联的其他元素来确定当前元素的相对/绝对位置。
Xpath中“ /”和“ //”的意义如下:
(1)“ /”: 用于创建具有绝对路径的Xpath,即xpath从文档根节点/起始节点开始;
(2)“ //”: 用于创建具有相对路径的Xpath,即xpath从文档中的任何位置开始(非根节点)。
Q:WebDriver启动浏览器的脚本(列举不同类别的浏览器驱动)?
答:以下语法可用于启动浏览器:
WebDriver driver =new FirefoxDriver();
WebDriver driver =new ChromeDriver();
Q:WebDriver提供哪些常见类型的驱动程序?
答:WebDriver中常见驱动程序有(这部分建议在面试前查阅一下官网,做到实时同步更新):
· FirefoxDriver
· InternetExplorerDriver
· ChromeDriver
· SafariDriver
· OperaDriver
· AndroidDriver
Q:WebDriver中有哪些不同的等待类型?
答:Selenium WebDriver共有两类等待:
(1)隐式等待:在整个测试脚本中,每个连续测试步骤/命令间设置默认等待时间(例 如10秒)。因此,要执行后续测试步骤,需等待前一个测试步骤/命令执行完毕后,再经过10秒时,才能继续下一步。
(2)显式等待:与隐式等待不同,显式等待仅适用于特定实例, 用于中止当前执行,直到满足特定条件的元素出现为止(在允许的时间内)。
Q:driver.close() 和driver.quit() 有什么区别?
答:此二者区别如下:
· driver.close() :关闭用户当前正在使用的Web浏览器窗口,即WebDriver当前正在访问的窗口。.close() 方法既不需要任何参数,也无任何返回值;
· driver.quit() :不同于close(),quit()方法用于关闭程序已打开的所有窗口。该方法也不需要任何参数,也无任何返回值。
Q:WebDriver可以测试移动应用程序吗?
答:由于WebDriver是基于Web的测试框架,因此无法测试移动应用程序(APP),移动APP测试可以选择Appium。
Q:如何使用Selenium输入文本框?
答:使用sendKeys(“XXXXXX”)在文本框中输入字符串,例如:
WebElement username = drv.findElement(By.id(“电子邮件”));
username.sendKeys(“ sth”);
Q:如何查找元素是否显示在屏幕上?
答:WebDriver通过isDisplayed(), isSelected(), isEnabled(),这三种方法判断Web元素的可见性,这类方法将返回结果是布尔类型;Web元素可以是按钮,下拉框,复选框,单选按钮,标签等。
(1)isDisplayed():
boolean b1 = driver.findElement(By.id(“XXX”)).isDisplayed();
(2)isSelected():
boolean b2 = driver.findElement(By.id(“XXX”)).isSelected();
(3)isEnabled():
boolean b3 = driver.findElement(By.id(“XXX”)).isEnabled();
Q:如何获取Web元素中的文本?
答: Get方法用于获取指定Web元素内部文本,此方法不需要传递任何参数,直接调用即可,它返回的是字符串值。该方法常用于验证页面显示的消息,标签,错误信息等是否和预期匹配。
String Text = driver.findElement(By.id(“XXX”)).getText();
Q:如何获取下拉菜单中的值?
答: 通过WebDriver中Select类来选择下拉列表中的值:
(1)通过selectByValue(“XXX”):
Select selectByValue =new Select(driver.findElement(By.id(“某id”)));
selectByValue.selectByValue(“某选项”);
(2)通过selectByVisibleText(“XXX”):
Select selectByVisibleText =new Select (driver.findElement(By.id(“某id”)));
selectByVisibleText.selectByVisibleText(“某选项”);
(3)通过selectByIndex(X):
Select selectByIndex =new Select(driver.findElement(By.id(“某id”)));
selectByIndex.selectByIndex(3);
Q:Selenium中页面导航命令有哪些不同类型?
答:Selenium中常见的页面导航操作如下:
(1)navigate().back() – 回上一页,回到Web浏览器历史记录中的上一个网页。
例:driver.navigate().back();
(2)navigate().forward() – 去下一页, 基于浏览器的历史记录导航到下一个网页。
例:driver.navigate().forward();
(3)navigate().refresh() – 刷新当前页面。
例:driver.navigate().refresh();
(4)navigate().to() – 开启新的Web浏览器窗口,并导航到指定的URL。
例:driver.navigate().to(“https://www.atstudy.com/”);
Q:如何使用linkText单击超链接?
答:可以通过链接文本的全包含和部分包含来获取该链接的定位 。
(1)通过链接文本找到该元素,单击该元素,用户将被重定向到相应的页面;
driver.findElement(By.linkText(“超链接的内容”)).click();
(2)通过“部分包含链接文本”单击超链接,根据链接子字符串查找元素,找到后单击:
driver.findElement(By.partialLinkText(“部分链接内容”)).click();
注:partialLinkText(“XXX”)用于查找具有指定子字符串的web元素
Q:如何处理frame?
答: iframe类似于网页中的嵌套,及一个页面中嵌套多个其他完整的页面;在Selenium中基于iframe的操作如下:
(1)通过id定位iframe
driver.switchTo().frame(“目标frame的id“);
(2)通过tagName定位iframe
driver.switchTo().frame(driver.findElements(By.tagName(“iframe”).get(0));
(3)通过index定位iframe [frame(index)]
driver.switchTo().frame(0);
(4)通过frame的名字定位[frame(Name of Frame)]
driver.switchTo().frame(“name of the frame”);
Q:findElement()和findElements()分别用于何种场合?
答:单一匹配和多匹配的区别;
(1)findElement() :用于查找当前网页中与指定定位中,可以匹配的第一个元素,值得一提注意的是,仅返回第一个匹配上的元素;
WebElement element =driver.findElements(By.xpath(“//指定路径”));
(2)findElements() —— 用于查找当前网页中与指定定位匹配的所有元素,所有匹配的元素都将被提取并存储在WebElements列表中;
List <WebElement> elementList =driver.findElements(By.xpath(“//指定路径”));
Q:如何在列表中找到多个Web元素?
答:在进行Web测试时,我们经常会遇到一系列相同类型的元素,例如以有序/无序列表形式排列的多个超链接,图像等,要定位一系列同类型的元素,在JAVA中可以通过WebElement List来完成;
假定以下代码用来循环点击页面中有序/无序列表包含的每个相同类型的超链接元素:
Sample code:
// 创建一个列表,专门用于存放WebElement类型的对象
List <WebElement> elementList = driver.findElements(By.xpath("//指定路径"));
// 获取列表长度
int listSize = elementList.size();
// 遍历列表
for (int i=0; i<listSize; i++)
{
// 点击列表中当前元素链接,进入链接所在页面
serviceProviderLinks.get(i).click();
//回到前一页
driver.navigate().back();
}
Q:如何处理基于Web的弹出窗口?
A:WebDriver中提供了专门用于处理Alert弹框的API,包含四种常用方法:
(1) void dismiss(): 单击弹出窗口中的“取消”按钮;
(2) void accept(): 单击弹出窗口中的“确定”按钮;
(3) String getText(): 返回显示在Alert框中的文本;
(4) void sendKeys(String stringToSend): 以字符串形式输入内容至Alert框中。
Sample code:
// 单击弹出窗口中的“确定”按钮Alert alert = driver.switchTo().alert();alert.accept();
Q:如何通过WebDriver触发鼠标悬停事件?
A:WebDriver提供了广泛的交互应用API,用户可以利用这些API自动触发鼠标/键盘事件。Action API就是这样一种交互性应用API,它可以模拟单个用户的交互动作。
例如我们可以通过Action API将鼠标悬停在某个下拉菜单上,然后打开其中的选项列表。
Sample Code:
// 初始化
Action APIActions actions=new Actions(driver);// 鼠标悬停的到下拉菜单上actions.moveToElement(driver.findElement(By.id("下拉菜单的ID"))).perform();// 定位并点击下拉菜单中某个选项WebElement subLinkOption = driver.findElement(By.id("某选项的ID"));subLinkOption.click();
Q:如何获取元素的CSS属性?
A:通过get() 方法获取web元素css的属性值。
例如获取某web元素CSS中“font-size”的属性值:
driver.findElement(By.id(“某元素ID“)).getCssValue(“font-size”);
Q:WebDriver中如何捕获屏幕截图?
WebDriver中如何捕获屏幕截图?
答:通过selenium提供的TakesScreenshot和OutputType 完成屏幕截图。
Sample Code:
// 获取截屏File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);// 将截屏保存到指位置FileUtils.copyFile(scrFile, new File("C:\\CaptureScreenshot\\sample.jpg"))
Q:web测试中如何验证网页标题是否正确?
A:可以结合junit/testNG中的断言。
// 验证页面标题内容是否正确assertTrue
(“验证当前页面标题正确性:”,driver.getTitle().equals(“预期页面标题内容”));
Q:selenium如何处理基于Windows的弹出窗口?
A:Selenium仅支持Web应用程序测试,不支持基于Windows的应用程序。但可以通过一些第三方工具处理windows弹框,例如AutoIT,Robot。
Q:什么时候应该使用Selenium Grid?
A:Selenium Grid能在多个平台和浏览器上同时执行相同/不同的测试脚本,从而实现分布式测试执行,Selenium Grid在不同环境下执行测试脚本的特性,可以大大节省自动化测试的执行时间,大幅提高效率。
Q:列举Selenium的局限性有哪些?
A:Selenium有以下不足之处:
(1) Selenium仅支持基于Web的应用程序的测试;
(2) 无法使用Selenium测试移动应用程序,可以选择Appium进行移动端功能测试;
(3) 验证码和条形码阅读器无法使用Selenium进行测试;
(4) Selenium本身不具有生成测试报告的功能,以JAVA为例,需要结合第三方框架如TestNG或JUnit来生成测试报告。
自动化测试框架相关知识点技能
Q:自动化测试框架的优势有哪些?
A:优势主要包括:
(1) 代码的可重用性;
(2) 尽可能确保最大测试覆盖率;
(3) 场景可恢复性;
(4) 低廉的后期维护成本;
(5) 尽可能减少人工干预;
(6) 自动生成测试报告。
Q:你了解哪些不同类型的测试框架?
A:比较常见的测试框架种类如下:
(1) 基于模块(module)的测试框架:这类框架将整个“被测应用程序”按逻辑性划分为若干个独立模块。对于每个模块,我们创建一个独立的测试脚本。因此,当这些测试脚本合在一起时,就构建成一个更大的测试脚本,对应了更大范围内的逻辑独立性模块;
(2) 库级别(library)的测试框架:基本原理是先确定通用步骤,然后将它们按组进行封装,封装成库函数,任何时候,如有需要,可以在测试脚本中随时调用这些库函数;
(3) 数据驱动(DDT)测试框架:DDT框架旨在将测试数据从业务逻辑脚本中独立出来,从而使用户可以将测试数据存储到外部数据库/配置文件中,测试数据一般按“键值”对存储居多,在测试脚本中可以通过测试数据的key, 来获取实际的value;
(4) 关键字驱动(Key)测试框架:是对数据驱动的测试框架的扩展,从某种意义上说,它不仅将测试数据与脚本分离,还将测试脚本按业务拆分,单独封装,即每一个关键字,就是一个业务,关键字驱动下的业务拆分粒度的精细程度可按实际项目需求来确定, 例如一个简单的登录业务可以封装成一个login关键字,一个完整的购物流程同杨也能封装成一个purchase关键字。
Q:常见的Junit注释?
A:Junit注释主要包含如下几种:
(1) @Test:告知系统被注释为“@Test”的方法是一种测试方法。一个测试脚本中可以有多个测试方法;
(2) @Before:该方法应在每个测试方法被执行之前执行;
(3) @After:该方法应在每个测试方法之后再被执行;
(4) @BeforeClass:此方法在当前测试类中所有测试方法执行之前,先被执行一次;
(5) @AfterClass:此方法在当前测试类中所有测试方法都执行完毕后,最后被执行一次;
(6) @Ignore:告知系统不执行此测试方法。
Q:TestNG比Junit更好吗?
A:TestNG是一个开源代码框架,对比Junit主要优势如下:
(1) 大大扩展了注释范围和类别;
(2) 可以设置执行模式;
(3) 支持并发执行测试脚本;
(4) 可以设置测试用例依赖性。
Q:如何在TestNG中设置测试用例优先级?
A:以如下代码为例,进行优先级的设置:
import org.testng.annotations.*;public class SettingPriority {(priority=1)public void method1() {}(priority=2)public void method2() {}(priority=0)public void method3() {}}
测试执行顺序为:method3 ——》method1 ——》method2
Q:断言(assert)和验证(verify)之间有什么区别?
A:断言(assert)用于检查给定条件是否满足,即True or False;假设我们断言某给定元素是否存在于页面上。如果条件为真True,则程序将执行下一个测试步骤,但如果条件为假False,则程序将停止执行,并且不再往下执行后续的测试步骤。
验证(verify) 同样是检查给定条件是对还是错,即True or False;不同的是,不管条件是否满足,程序的执行都不会停止,即验证过程中的任何失败都不会停止当前的程序执行,并且所有测试步骤都将被执行到。