这里写自定义目录标题
自动化测试
自动化测试就是指软件测试的自动化,通过提前预设的方式,让程序自动执行,完成测试。测试人员通过查看脚本运行的结果评估测试情况。通过使用自动化测试,可以有效的减少人力的消耗,提高测试的质量和效率。
自动化测试的分类
自动化测试包括UI自动化测试、接口自动化测试以及其他形式的自动化测试;
UI自动化测试即界面的自动化测试,它的用例维护量较大,页面的相关性也更强,更加适合界面变动较小的项目;
接口自动化测试即API测试,执行相对更加稳定,它的用例维护量较小,更加适合接口变动小但界面变动频繁的项目;
Web自动化测试的工具-selenium
selenium是web应用中基于UI的自动化测试框架,支持多平台、多浏览器、多语言;
选择selenium进行自动化测试的几个原因:
- 开源免费
- 支持多浏览器,如Chrome、Firefox、IE浏览器等;
- 支持多系统,如Linux、Windows、macOS等
- 支持多语言,如Java、Python、JavaScript等;
- selenium包提供了许多共测试使用的API;
环境部署
使用selenium进行web自动化测试,首先需要具备进行自动化测试的环境,包括浏览器和对应浏览器驱动的安装;
驱动就是用来打开浏览器的工具,主要就是将使用selenium编写的脚本发送过来的http请求接收然后进行解析然后发送给指定的浏览器,人工测试的情况下,驱动就是人;
由于近期谷歌浏览器版本与selenium不兼容的问题,这里使用的是edge浏览器,另外使用java语言编写测试脚本;
注意驱动要与浏览器相对应,即谷歌浏览器对应下载谷歌驱动,edge浏览器对应下载edge驱动;
- 下载完成后将解压得到的exe文件放到java系统的环境变量下;
项目准备
此处使用java来编写selenium脚本,需要创建一个Maven项目,在项目的pom.xml文件中导入selenium包;
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.0.0</version>
</dependency>
selenium常用方法
查找页面元素
- findElement();
参数:By类;
返回值:WebElement;
当查找的元素在页面存在时,程序正常退出;若元素在页面不存在,程序执行报错;
- findElement()s;
与findElement()方法类似,但返回值为List< WebElement >;
查找元素的方法:使用浏览器页面的前端开发者工具;
-
在页面的空白处->鼠标右键->选择“检查”;
-
在打开的界面,点击左上方的箭头->在网页页面点击选择元素->即有光标定位到元素对应的前端代码;
元素的定位
- By类
指定通过哪种方式来查找元素,常用的有selector和xpath;
selector:选择器方式;
xpath:路径方式;
层级:/ 表示子级、//表示跳级;
代码示例:
public void autoTest(){
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//3.查找搜索框元素(选择器的方式)
driver.findElement(By.cssSelector("#kw"));
//3.查找搜索框元素(xpath的方式)
driver.findElement(By.xpath("//*[@id=\"kw\"]"));
//4.释放驱动
driver.quit();
}
执行结果,正常退出;
By类实际提供了多种定位元素的方式,需要的话也可以使用;
在自动化测试中,元素的定位必须唯一,上面手动在页面复制元素的selector或xpath的方式得到的参数指向的元素可能是不唯一的,此时需要手动进行调整使其唯一;
常见的元素操作
对元素进行任何操作的前提都是可以在页面找到元素,查找元素以及定位元素的方式就是借助findElement()方法和By类完成的;
- 输入文本-sendKeys();
代码演示:
//找到搜索框,并且输入文本“自动化测试”
driver.findElement(By.cssSelector("#kw")).sendKeys("自动化测试");
输入文本操作仅适用于文本字段和可以进行编辑的元素,但如果对非文本字段和不可编辑的元素进行操作也不会报错;
- 点击-click();
代码演示:
//找到“百度一下”按钮进行点击
driver.findElement(By.cssSelector("#su")).click();
- 提交-submit();
提交即通过回车键进行提交,仅适用于表单元素,与click()的效果类似,但官方更推荐使用点击操作;
代码演示:使用百度搜索完成对“自动化测试”文本的搜索;
public void autoTest(){
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//3.查找搜索框元素(选择器的方式)并输入文本
driver.findElement(By.cssSelector("#kw")).sendKeys("自动化测试");
//4.找到“百度一下”按钮进行点击
driver.findElement(By.cssSelector("#su")).click();
//5.释放驱动
driver.quit();
}
执行成功,正常退出;
- 清除-clear();
主要是进行测试输入是否可以重复、频繁进行;
代码演示:输入文本后进行清除,重新输入;
public void autoTest(){
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//3.查找搜索框元素(选择器的方式)并输入文本
WebElement element=driver.findElement(By.cssSelector("#kw"));
element.sendKeys("自动化测试");
//清除第一次输入的文本
element.clear();
//再次输入
element.sendKeys("java");
//4.找到“百度一下”按钮进行点击
driver.findElement(By.cssSelector("#su")).click();
//5.释放驱动
driver.quit();
}
- 获取文本-getText()
获取文本即可获取到元素对应的文本;
public void autoTest() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//3.找到对应的元素获取文本值
Thread.sleep(3000);
//提交强制等待,防止由于页面渲染较慢而引起误报
String str=driver.findElement(By.cssSelector("#hotsearch-content-wrapper > li:nth-child(1) > a > span.title-content-title")).getText();
Thread.sleep(3000);
System.out.println("获取到的文本为:"+str);
//4.释放驱动
driver.quit();
}
执行结果:
与获取文本相似的是获取属性值,所以需要区分清楚文本与属性值的区别;
像上面,在标签外的是文本;
处于标签内部,并且前面有对应属性的就是属性值,获取属性值使用getAttribute()方法;
public void autoTest() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//3.找到“百度一下”按钮获取此处属性为value的属性值
Thread.sleep(3000);
String str=driver.findElement(By.cssSelector("#su")).getAttribute("value");
System.out.println("获取到的文本为:"+str);
//4.释放驱动
driver.quit();
}
执行结果:
- 获取页面的标题和URL;
public void autoTest() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
System.out.println(driver.getTitle());//获取当前页面的标题
System.out.println(driver.getCurrentUrl());//获取当前页面的URL
//.释放驱动
driver.quit();
}
执行结果:
窗口
- 窗口的切换:
窗口的切换包含窗口最大化、窗口最小化、全屏窗口、手动设置窗口大小;
public void autoTest() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//窗口最大化
driver.manage().window().maximize();
//窗口最小化
driver.manage().window().minimize();
//全屏窗口
driver.manage().window().fullscreen();
//手动设置窗口大小
driver.manage().window().setSize(new Dimension(1000,800));
//5.释放驱动
driver.quit();
}
- 窗口的切换
窗口切换的手动操作过程是:首先打开浏览器,输入网址,点击页面上的某条超链接,页面跳转到超链接对应的页面;
如果我们依据上面的流程编写自动化测试脚本,得到的代码以及执行结果如下:
显示元素不存在;
实际上,我们上面代码所演示的操作流程对于selenium来说需求是不明确的,即当我们通过点击超链接的方式进入到一个新的页面,在对新页面的元素进行查找时,对于自动化测试工具而言,我们到底是要在哪个页面寻找对应的元素是不清楚的;为了解决这个问题,就需要使用到句柄;
句柄实际就相当于是浏览器给当前页面的一个标识,不同页面的标识不同,每次通过方法查看到的句柄具体值不同;
我们对代码做出修改:
public void autoTest1() throws InterruptedException{
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//获取当前页面的句柄
String curHandle=driver.getWindowHandle();
System.out.println("当前页面的句柄:"+curHandle);
//3.找到百度首页的“新闻”元素并点击
driver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
//获取浏览器所有标签页的句柄
Set<String> handles=driver.getWindowHandles();
//通过for循环实现窗口的切换
for (String handle:handles) {
if (handle!=curHandle){
driver.switchTo().window(handle);//实现页面跳转
}
}
//4.来到百度新闻页面查找“百度新闻”元素
driver.findElement(By.cssSelector("#sbox > tbody > tr > td.logo > div.logo > a > img"));
driver.quit();
}
执行结果:
屏幕截图
通常情况下,代码的执行速度都是大于页面渲染的速度的,这就难免会出现测试执行的误报。因此我们需要保存测试过程中的一些情景,这些情景可以帮助我们进行复盘和发现问题,即保存当时的屏幕截图;
- 首先需要导入屏幕截图需要的依赖到pom.xml
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
- 使用代码演示
public void autoTest2() throws IOException, InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//3.找到百度搜索框,输入关键字,点击
driver.findElement(By.cssSelector("#kw")).sendKeys("白敬亭");
driver.findElement(By.cssSelector("#su")).click();
//屏幕截图
File srcFile=driver.getScreenshotAs(OutputType.FILE);
String fileName="jt.png";
FileUtils.copyFile(srcFile,new File(fileName));
//在新页面查找指定元素
driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > a > div > p > span > span"));
driver.quit();
}
执行结果:
代码编写是正确的,但是实际执行却出错,查看我们的屏幕截图:
通过截图信息,我们就可以推断出是由于代码执行速度大过页面渲染速度,当代码执行到查找新页面的元素时,页面还未渲染完成,从而出现上面的执行结果;
对于已经存在的重名的文件,程序多次执行会将之前生成的图片覆盖;
可以使用动态数据对文件命名,例如时间戳;
public void autoTest2() throws IOException, InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//3.找到百度搜索框,输入关键字,点击
driver.findElement(By.cssSelector("#kw")).sendKeys("白敬亭");
driver.findElement(By.cssSelector("#su")).click();
//屏幕截图
List<String> list=getTime();
String fileName="./src/test/java/com/autotest0411/"+list.get(0)+"/"+getClass().getName()+"_"+list.get(1)+"png";
File srcFile=driver.getScreenshotAs(OutputType.FILE);
//String fileName="jt.png";
FileUtils.copyFile(srcFile,new File(fileName));
//在新页面查找指定元素
driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > a > div > p > span > span"));
driver.quit();
}
/*
* 按照天的维度构成文件夹进行保存
* */
public List<String> getTime(){
SimpleDateFormat sim1=new SimpleDateFormat("yyyyMMdd-HHmmssSS");
SimpleDateFormat sim2=new SimpleDateFormat("yyyyMMdd");
String filename=sim1.format(System.currentTimeMillis());
String dirname=sim2.format(System.currentTimeMillis());
List<String> list=new ArrayList<>();
list.add(dirname);
list.add(filename);
return list;
}
得到的文件命名:
等待
前面已经提到,由于代码的执行速度要远大于页面的渲染速度,因此难免会出现测试执行中误报的问题;为了尽量避免这一问题,就需要通过一些方法来减慢代码的执行速度,即设置等待操作;
- 强制等待;
强制等待即阻塞程序的进行,具体方法就是上面代码中使用到的sleep();
- 隐式等待;
隐式等待是针对查找的元素不断轮询,如果元素不存在就在设置好的等待时间内不断进行轮询,直到元素被找到;
隐式等待一般在驱动创建之后设置,作用于驱动的整个生命周期;
- 显示等待;
显示等待是程序每隔一定的时间就去判断一下指定的元素是否存在(是否加载完成),如果存在就执行下一步,否则继续每隔一定时间去判断;
public void implicitlyWait(){
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//添加隐式等待
//driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//3.找到百度搜索框,输入关键字,点击
driver.findElement(By.cssSelector("#kw")).sendKeys("白敬亭");
driver.findElement(By.cssSelector("#su")).click();
//显示等待
new WebDriverWait(driver,Duration.ofSeconds(5)).until(driver1->driver1.findElement(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > a > div > p > span > span")));
driver.quit();
}
浏览器导航
浏览器导航包括浏览器的前进、后退、刷新操作;
public void navigateControl() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度网址
driver.get("https://www.baidu.com");
//回退
Thread.sleep(1000);
driver.navigate().back();
//前进
Thread.sleep(1000);
driver.navigate().forward();
//刷新
Thread.sleep(1000);
driver.navigate().refresh();
driver.quit();
}
弹窗
常见的弹窗类型主要有3种:
确认弹窗:
警告弹窗:
提示弹窗:
对弹窗的处理主要分为两步:
- 将驱动对象作用到弹窗;
- 根据不同类型的弹窗进行对应的操作;
使用代码进行演示(由于提示弹窗包含了警告弹窗和确认弹窗的操作,此处以提示弹窗为例):
public void alertControl() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//使用浏览器访问弹窗文件
driver.get("file:///C:/Users/%E6%99%A8%E6%9B%A6/AppData/Local/Temp/360zip$Temp/360$9/selenium-html/Prompt.html");
//打开弹窗
Thread.sleep(1000);
driver.findElement(By.cssSelector("body > input[type=button]")).click();
Thread.sleep(1000);
//切换操作对象为弹窗
Alert alert=driver.switchTo().alert();
//在弹窗中输入文本
Thread.sleep(1000);
alert.sendKeys("弹窗操作");
//点击确认
Thread.sleep(1000);
alert.accept();
//点击取消
//alert.dismiss();
driver.quit();
}
选择框
对选择框操作即常见的下拉框进行选择的操作:
选择框的选择方式一般有3种方式:
- 根据文本进行选择;
- 根据属性值进行选择;
- 根据序号进行选择;
使用代码演示:
public void selectCon() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.浏览器打开选择框文件
driver.get("file:///C:/Users/%E6%99%A8%E6%9B%A6/AppData/Local/Temp/360zip$Temp/360$11/selenium-html/select.html");
Thread.sleep(1000);
//3.找到要进行操作的元素
WebElement element=driver.findElement(By.cssSelector("#ShippingMethod"));
//4.创建选择框对象
Select select=new Select(element);
//根据文本进行选择
Thread.sleep(1000);
select.selectByVisibleText("UPS Ground ==> $8.34");
//根据属性值进行选择
Thread.sleep(1000);
select.selectByValue("12.51");
//根据序号进行选择
Thread.sleep(1000);
select.selectByIndex(2);
driver.quit();
}
执行脚本
使用一个简单的例子来演示:打开一个页面,通过执行脚本,使其滑动到页面的不同位置;
public void scriptCon() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度新闻网址
driver.get("https://news.baidu.com/");
//执行脚本
//滑动到页面最底部
Thread.sleep(1000);
driver.executeScript("document.documentElement.scrollTop=1000");
//滑动到页面顶部
Thread.sleep(1000);
driver.executeScript("document.documentElement.scrollTop=0");
driver.quit();
}
上面executeScript()方法的参数是js代码;执行脚本实际就是将一些简单的js代码直接作为方法的参数;
文件的上传
对这样一个简单页面进行操作:
public void fileUploadCon() throws InterruptedException {
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
Thread.sleep(1000);
//2.使用浏览器打开一个用来上传文件的简单html页面
driver.get("file:///C:/Users/%E6%99%A8%E6%9B%A6/AppData/Local/Temp/360zip$Temp/360$0/selenium-html/upload.html");
Thread.sleep(1000);
//3.找到指定的元素,上传指定的文件
driver.findElement(By.cssSelector("body > div > div > input[type=file]")).sendKeys("C:\\java\\dom4j-2.1.0.jar");
driver.quit();
}
此处文件的上传并非真的上传了文件,而是将要上传的文件的路径+文件名称进行显示;
浏览器的参数设置
实际工作中,更多地是将自动化部署到机器上自动执行,测试人员只需直接查看测试执行的结果,也就是无头模式的设置;
public void paramsControl(){
//先创建选项对象,然后再设置浏览器参数
//1.创建驱动
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
edgeOptions.addArguments("-headless");
EdgeDriver driver = new EdgeDriver(edgeOptions);
driver.get("https://www.baidu.com");
driver.findElement(By.cssSelector("#kw")).sendKeys("over");
driver.findElement(By.cssSelector("#su")).click();
driver.quit();
}
进行无头模式的设置之后,代码执行不会打开浏览器,测试人员通过执行结果来判断测试是否通过:
借用junit进行自动化测试
首先关于selenium与Junit,我们自动化脚本的编写一定是使用selenium来完成的;而Junit则是java用来自动化测试的工具,这里我们只是借用Junit库中的一些方法来帮助我们更好地进行测试;
使用Junit之前首先需要下载相关的依赖到pom.xml;
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-suite</artifactId>
<version>1.8.2</version>
<scope>test</scope>
</dependency>
注解
- @Test
使用该注解表示此方法为一个测试方法;不需要再其他类或方法中调用就可以直接执行;
@Test
public void testFun(){
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度新闻网址
driver.get("https://news.baidu.com/");
driver.quit();
}
此时下面的控制台会显示测试方法的运行情况:
- @BeforeEach
被该注解修饰的方法需要在每个用例执行之前都执行一次;
public class autoTest2 {
@Test
public void testFun1(){
System.out.println("测试方法testFun1()");
}
@BeforeEach
public void testFun2(){
System.out.println("测试方法testFun2()");
}
@Test
public void testFun3(){
System.out.println("测试方法testFun3()");
}
}
- @AfterEach
被该注解修饰的方法需要在每个用例执行之后都执行一次;
public class autoTest2 {
@Test
public void testFun1(){
System.out.println("测试方法testFun1()");
}
@Test
public void testFun2(){
System.out.println("测试方法testFun2()");
}
@AfterEach
public void testFun3(){
System.out.println("测试方法testFun3()");
}
}
- @BeforeAll
表示被该注解修饰的方法需要在当前类下的所有用例之前执行一次;
被该注解修饰的方法必须为静态方法;
public class autoTest2 {
@Test
public void testFun1(){
System.out.println("测试方法testFun1()");
}
//@BeforeEach
@Test
public void testFun2(){
System.out.println("测试方法testFun2()");
}
@BeforeAll
public static void testFun3(){
System.out.println("测试方法testFun3()");
}
}
- @AfterAll
表示被该注解修饰的方法需要在当前类下的所有用例之后执行一次;
被该注解修饰的方法必须为静态方法;
public class autoTest2 {
@Test
public void testFun1(){
System.out.println("测试方法testFun1()");
}
//@BeforeEach
@Test
public void testFun2(){
System.out.println("测试方法testFun2()");
}
@AfterAll
public static void testFun3(){
System.out.println("测试方法testFun3()");
}
}
断言
所谓断言,实际就是对预期结果与实际结果的判断;使用Assertions类中的方法;
- assertEquals();
断言是否匹配(或相等);
@Test
public void testFun1(){
//1.创建驱动,用来打开浏览器
EdgeOptions edgeOptions=new EdgeOptions();
edgeOptions.addArguments("--remote-allow-origins=*");
EdgeDriver driver = new EdgeDriver(edgeOptions);
//2.输入要访问的百度新闻网址
driver.get("https://baidu.com/");
//3.获取元素的属性值
String text=driver.findElement(By.cssSelector("#su")).getAttribute("value");
//断言属性值是否为“百度一下”
Assertions.assertEquals("百度一下",text);
driver.quit();
}
- assertNotEquals();
断言是否不匹配;
- assertTrue();
断言结果是否为真;
public void fun2(){
Assertions.assertTrue(1==1);
}
- assertFalse()
断言结果是否为假;
public void fun2(){
Assertions.assertFalse(1==0);
}
- assertNull()
断言结果是否为空;
public void fun2(){
String str=null;
Assertions.assertNull(str);
}
- assertNotNull()
断言结果是否不为空;
public void fun2(){
Assertions.assertNotNull("hello");
}
用例的执行顺序
当我们的程序中有多个用例,很多时候测试用例的执行并不一定会按照我们编写用例的顺序来执行,但存在一些场景确实需要我们控制用例的执行顺序的,就可以借助@Order注解来实现;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class autoTest2 {
@Test
@Order(2)
public void testFun2(){
System.out.println("测试方法testFun2()");
}
@Test
@Order(1)
public void testFun3(){
System.out.println("测试方法testFun3()");
}
@Test
@Order(3)
public void fun2(){
Assertions.assertNotNull("hello");
}
}
必须在类外首先使用注解@TestMethodOrder(MethodOrderer.OrderAnnotation.class)来说明当前类下所有的用例需要使用@Order注解进行排序;
参数化
参数化的主要目的实际就是尽可能地通过一个用例,多个参数来模拟用户的行为,通过注解来提供数据源,减少用例的冗余,高效地完成测试工作;
使用参数化的注解之前一律需要使用声明该方法为参数化方法;
- 单参数
@ParameterizedTest
@ValueSource(strings = {"zhangsan","lisi","wangwu"})
public void paramsTest(String name){
System.out.println(name);
}
- 多参数(在注解中手动编写数据源)
@ParameterizedTest
@CsvSource({"zhangsan,12","lisi,23","wangwu,34"})
public void muchParamsTest(String name,int age){
System.out.println("name:"+name+" "+"age:"+age);
}
使用注解手动编写数据源时,每个双引号代表一组参数;
- 多参数(从第三方CSV文件读取数据)
@ParameterizedTest
@CsvFileSource(files = "C:\\Users\\晨曦\\Documents\\Tencent Files\\mycsv.csv")
public void fileParamsTest(String name,int age){
System.out.println("name:"+name+" "+"age:"+age);
}
- 动态参数
@ParameterizedTest
@MethodSource("methodPramsTest")
public void dynamicPramsTest(String name,int age){
System.out.println("name:"+name+" "+"age:"+age);
}
static Stream<Arguments> methodPramsTest() throws InterruptedException {
//构造动态参数
String[] arr=new String[5];
for (int i=0;i<arr.length;i++){
Thread.sleep(1000);
arr[i]=System.currentTimeMillis()+" ";
}
return Stream.of(
Arguments.arguments(arr[0],12),
Arguments.arguments(arr[1],23),
Arguments.arguments(arr[2],34),
Arguments.arguments(arr[3],45),
Arguments.arguments(arr[4],56)
);
}
当注解@MethodSource没有在括号中指明构造动态参数的方法时,默认寻找与用例名同名的方法;
@ParameterizedTest
@MethodSource
public void dynamicPramsTest(String name,int age){
System.out.println("name:"+name+" "+"age:"+age);
}
static Stream<Arguments> dynamicPramsTest() throws InterruptedException {
//构造动态参数
String[] arr=new String[5];
for (int i=0;i<arr.length;i++){
Thread.sleep(1000);
arr[i]=System.currentTimeMillis()+" ";
}
return Stream.of(
Arguments.arguments(arr[0],2),
Arguments.arguments(arr[1],3),
Arguments.arguments(arr[2],4),
Arguments.arguments(arr[3],5),
Arguments.arguments(arr[4],6)
);
}
测试套件
在测试过程中,有时候会创建多个测试类,如果一一点击运行,势必会拖慢我们的测试效率,因此我们使用测试套件来解决该问题;
使用测试套件之前,首先需要创建一个类,并使用@Suite注解将此类标识为测试套件类:
- 指定类运行;
此时指定的三个类中的测试方法都会被运行到;
- 指定包名运行;
使用包名指定运行时,该包下的所有需要运行的测试类的命名必须遵守以Test/Tests结尾的规则;
同样执行的测试中的方法必须为测试方法(被@Test修饰)
over!!!