《软件测试和质量管理》实验报告四
一、目的和要求
- 学习使用了解 Selenium自动化功能测试工具,了解 Selenium 测试工具的测试模式和过程;
- 掌握使用 Selenium 录制测试脚本、执行并分析测试脚本。
二、实验设备
主流 PC 机一套,要求安装 windows 操作系统、Selenium 最新版本、OFFICE工具;
三、实验内容
- 使用 Selenium 对 MercuryTours 网站进行功能测试。要求录制预订机票的完整过程,然后执行测试脚本并分析结果。
- 设置至少三个检验点,观测检测结果。
四、实验过程
4.1 录制测试脚本前的准备
(1)Selenium及MercuryTours航空网站安装
(2)Mtours航空网站本地服务启动
(3)Chrome浏览器打开项目
使用Chrome浏览器,并在URL地址栏中输入http://localhost:8080/Mtours,点击导航栏中的Register按钮,并按提示输入表单,注册一个用户的信息,具体信息如下图所示。
4.2 Selenium脚本录制
点击安装好的浏览器插件Selenium,并在URL地址栏中输入http://local host:8080/Mtours,Selenium会录制用户的一系列操作,并将这些操作转换为指令集存储下来。现按实验要求录制预订机票的完整过程,如下图所示。其中主要测试的功能点包括:open、set window size、click、type、select等。
4.3 加强测试脚本
设置至少三个检验点,assert、verify以及waitfor,其区别如下:
- Assert:失败时,该测试将终止;
- Verify:失败时,该测试继续执行,并将错误日志记录在日显示屏;
- Waitfor:等待某些条件变为真,一般使用在Ajax应用程序的测试。
这里添加了三个检查点,其类型为assert value、assert selected value(verify selected value)、assert text。
(1)检查点1
assert value断言检查输入的用户名是否为Rql,若并非Rql则立即结束此次测试。
(2)检查点2
assert selected value检查选中的起始地址是否为Lundon,若并非Lundon则立即结束此次测试。
此外,我还尝试使用了verify selected value检查选中的起始地址是否为Lundon,若并非Lundon则提示机票购错,测试继续进行(这里继续进行是因为不会影响模拟测试的业务流程)。
(3)检查点3
assert text检查指定元素的文本是否为“LastName:”,若不是则立即结束本次测试。
4.4 调试测试脚本
录制完脚本并作加强测试脚本后,还需要检查和微调测试脚本,以确保脚本能够流畅进行,没有额外人为的Bug,即检查、对Selenium脚本进行除错行为。
4.5 执行脚本
点击执行测试按钮后,Selenium将执行脚本中的指令集,包括用户添加的验证类指令集(即在上面增加的assert value、assert selected label、assert text)。
4.6 导出Junit测试用例
// Generated by Selenium IDE
import org.junit.Test;
import org.junit.Before;
import org.junit.After;
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.core.IsNot.not;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Alert;
import org.openqa.selenium.Keys;
import java.util.*;
import java.net.MalformedURLException;
import java.net.URL;
public class Test1Test {
private WebDriver driver;
private Map<String, Object> vars;
JavascriptExecutor js;
@Before
public void setUp() {
driver = new ChromeDriver();
js = (JavascriptExecutor) driver;
vars = new HashMap<String, Object>();
}
@After
public void tearDown() {
driver.quit();
}
@Test
public void test1() {
driver.get("http://localhost:8080/mtours/servlet/com.mercurytours.servlet.WelcomeServlet");
driver.manage().window().setSize(new Dimension(1136, 680));
{
String value = driver.findElement(By.name("userName")).getAttribute("value");
assertThat(value, is("Rql"));
}
driver.findElement(By.name("userName")).sendKeys("Rql");
driver.findElement(By.name("password")).sendKeys("rql020701@30");
driver.findElement(By.name("login")).click();
driver.findElement(By.name("passCount")).click();
driver.findElement(By.name("fromPort")).click();
{
WebElement dropdown = driver.findElement(By.name("fromPort"));
dropdown.findElement(By.xpath("//option[. = 'London']")).click();
}
{
String value = driver.findElement(By.name("fromPort")).getAttribute("value");
assertThat(value, is("London"));
}
driver.findElement(By.name("findFlights")).click();
driver.findElement(By.cssSelector("table:nth-child(2) tr:nth-child(5) input")).click();
driver.findElement(By.name("reserveFlights")).click();
driver.findElement(By.name("passFirst0")).click();
driver.findElement(By.name("passFirst0")).sendKeys("Ruan");
driver.findElement(By.name("passLast0")).click();
driver.findElement(By.name("passLast0")).sendKeys("Qionglu");
assertThat(driver.findElement(By.cssSelector("tr:nth-child(4) > td > table > tbody > tr > td:nth-child(2) > font")).getText(), is("Last Name:"));
driver.findElement(By.name("creditnumber")).click();
driver.findElement(By.name("creditnumber")).sendKeys("3");
driver.findElement(By.name("buyFlights")).click();
driver.findElement(By.cssSelector("tr:nth-child(7) td:nth-child(3) img")).click();
driver.findElement(By.name("userName")).sendKeys("Rql");
driver.findElement(By.name("password")).sendKeys("rql020701@30");
driver.findElement(By.name("login")).click();
}
}
五、实验结果分析
最终测试的所有脚本点均通过。主要测试的功能点open、set window size、click、type、select等,以及设计的3个加强检查点均通过,没有异常信息或者报错。
但是在实验过程中,我中途故意检测出发地为New York(实际选择了London),assert selected value检测出并非Lundon立即结束此次测试;verify selected value检测出非Lundon,报错但测试继续进行。表面功能测试能够看到针对表单的操作,发现测试错误。同时,也表现出验证verify和断言assert的区别:验证失败后不影响脚本的继续执行,但断言失败后将停止脚本的执行。
六、心得与体会
本次实验,我们以Mtours航空飞行公司订票为背景、以Web页面为对象进行了功能测试,主要是学习和掌握Selenium自动化功能测试工具,并利用它录制测试脚本、调试测试脚本并分析测试脚本中的问题。
Selenium是一个功能强大的自动化测试工具,操作十分简单,易于上手。只需开启录制,然后正常在页面中操作,它就会录制下一系列操作,并将这些操作转换为指令集存储下来。后续对测试脚本设置检查点并进行调试,它会通过创建真实的浏览器会话来模拟用户行为,如:验证表单、点击按钮、输入数据,从而自动测试Web应用程序的各种功能。大大提高了测试人员的效率,减少了测试的出错率,在大规模测试中可以提供高质量的结果。
同时,还学习到了selenium的三种模式的断言(assert 、verify、waitfor),其中Assert测试失败时会使测试终止,Verify测试失败时虽然测试继续执行但会将错误日志记录;Waitfor等待某些条件变为真,一般使用在Ajax应用程序的测试。
理想的功能测试是:针对每一类Element元素都能测试全面,并且覆盖完一整个业务流程而没有太多的冗余测试点。所以,测试时可以注意减少一些同类型的操作,即如果一个表单都是input输入框,可以测试少一些,删减求精,避免重复的测试结果内容都是一类的输入操作,显得冗余而没有必要。
这几个实验下来,我们会发觉从白盒测试、黑盒测试出来,越往高层进入功能测试,对工具的使用要求逐渐变高,对代码的可见度逐渐降低。功能测试对应需求分析,所以主要是针对一个业务流程测试某一业务的功能模块是否错误。