200210413TestNG

前言

​ 我反思了一下如何学习TestNG,可以在实践上探索,所以这次博客我首先上一个TestNG的实战,然后代码中对应着TestNG的知识点;

​ 不见庐山真面目,只缘身在此山中,如果庐山看过,再入庐山,不懂的地方到下面找详解

​ 首先第一部分就是庐山的全景图:三个.java文件 BaseDriver(用于驱动浏览器)

可以用创建父类的方法来增加代码的复用性 BaseDriver

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;

public class BaseDriver {
	String baseUrl="http://localhost:8032/mymovie";
	WebDriver driver;
	
	@BeforeClass
	public void initDriver() {
		System.setProperty("webdriver.gecko.driver", 
				"D:\\demo\\geckodriver.exe");
		driver=new FirefoxDriver();
	
	}
	
	@AfterClass
	public void quiteDriver() {
		if(driver !=null) {
			driver.quit();
		}
		
	}
	
}

​ 第二部分:数据驱动

import org.testng.annotations.DataProvider;

public class UserData {
	@DataProvider(name = "user")
	public Object[][] getUser() {
		return new Object[][] {
			{"qingdao01","123456","这是第一个用户的评价!!"},
			{"qingdao02","123456","这是第二个用户的评价!!"}
		};
		
	}

}

​ 第三部分:demo继承了浏览器驱动 使用了数据驱动

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class Demo7  extends BaseDriver{
	
	
	@Test(dataProviderClass = UserData.class, dataProvider = "user")
	public void addCommand(String u_name,String u_pwd,String msg) throws InterruptedException {
		driver.get(this.baseUrl);
		Thread.sleep(3000);
		driver.findElement(By.linkText("登录")).click();
		Thread.sleep(3000);
		driver.findElement(By.name("username")).
		sendKeys(u_name);
		driver.findElement(By.name("password")).
		sendKeys(u_pwd);
		
//		driver.findElement(By.name("password")).
//		submit();
		driver.findElement(By.xpath("//input[@value='马上登录']")).click();
		Thread.sleep(3000);
		driver.get(this.baseUrl+"/index.php/Detail/index/id/38");
		driver.findElement(By.id("js_message_textarea")).sendKeys(msg);
		driver.findElement(By.id("message_button")).click();
		
		driver.findElement(By.linkText("退出")).click();
		
		
		
	}
	

复习

TestNG是基于注解的;

把@BeforeClass换为@BeforeSuit为什么会报错???

	@BeforeClass  //在类之前会执行
	public void initDriver() {
		//打开浏览器
		String url = "http://localhost:8032/mymovie/";
		System.setProperty("webdriver.gecko.driver","D:\\demo\\geckodriver.exe");
		System.setProperty("webdriver.firefox.bin","D:\\app\\firefox.exe");
		WebDriver driver = new FirefoxDriver();
		driver.get(url);
	}

Suit 再class之前

Beforemethod在每个test之前

//与BeforeSuit相结合

别忘了配置文件!

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
  
<suite name="Suite1" verbose="1" >
  <test name="Nopackage" >
    <classes>
       <class name="NoPackageTest" />
    </classes>
  </test>
 
  <test name="Regression1">
    <classes>
      <class name="test.sample.ParameterSample"/>
      <class name="test.sample.ParameterTest"/>
    </classes>
  </test>
</suite>

如果前端登录和后端登录一起运行,BeforeClass运行了几次? 执行了两次;执行了两个子类

每次实例化一次浏览器,那可以只实例化一次呢?

用@BeforeSuit 如果运行的时候报错去看TestNG报错的问题。比如driver没有实例化

但是为什么不行呢?

  <test name="Regression1">
    <classes>
      <class name="test.sample.ParameterSample"/>  先执行比如这个是前端
      <class name="test.sample.ParameterTest"/>
    </classes>
  </test>

每次执行都会实例化一个对象,也会实例化父类的构造方法,记住把构造方法加上!

为什么BeforeSuit不行?

先执行构造方法,执行父类的构造方法,第二次执行

@BeforeSuit只进行一次,第一次执行了,第二次就不会执行,为空,会报错:空指针异常

如果子类是继承父类 先跑父类的BeforeClass再跑子类的BeforeClass;

<suite name="Suite1" verbose="1" parallel="classes">

parallel这个属性可以实现多线程

一个suit可以有多个test

BaseDriver

设置basedriver的目的是为了省事儿!!!

不用每一次都去实例化driver,让其他类继承BaseDriver

@BeforeClass
public void initDriver() {
	System.setProperty("webdriver.gecko.driver", "D:\\demo\\geckodriver.exe");
	driver=new FirefoxDriver();

}

@AfterClass
public void quiteDriver() {
	if(driver !=null) {
		driver.quit();
	}
	
}

###数据驱动,@DataProvider

import org.testng.annotations.DataProvider;

public class UserData {
	@DataProvider(name = "user")
	public Object[][] getUser() {
		return new Object[][] {
			{"qingdao01","123456","这是第一个用户的评价!!"},
			{"qingdao02","123456","这是第二个用户的评价!!"}
		};
		
	}

}
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class Demo7  extends BaseDriver{
    //"user" 对应上面的(name = "user")
	@Test(dataProviderClass = UserData.class, dataProvider = "user")
	public void addCommand(String u_name,String u_pwd,String msg) throws InterruptedException {
		driver.get(this.baseUrl);
		Thread.sleep(3000);
		driver.findElement(By.linkText("登录")).click();
		Thread.sleep(3000);
		driver.findElement(By.name("username")).sendKeys(u_name);
		driver.findElement(By.name("password")).sendKeys(u_pwd);
		
//		driver.findElement(By.name("password")).
//		submit();
		driver.findElement(By.xpath("//input[@value='马上登录']")).click();
		Thread.sleep(3000);
		driver.get(this.baseUrl+"/index.php/Detail/index/id/38");
		driver.findElement(By.id("js_message_textarea")).sendKeys(msg);
		driver.findElement(By.id("message_button")).click();
		
		driver.findElement(By.linkText("退出")).click();		
	}
}

断言

汇总

assertEquals(a,b)测试a是否等于b
assertNotEquals(a, b)测试a是否不等于b
assertFalse(a)测试a是否为false
assertTrue(a)测试a是否为true
assertNull(a)测试Object类型数据是否为null
assertNotNull(a)测试Object类型数据是否非空
assertSame(a, b)测试a和b是否都引用同一个对象
assertNotSame(a, b)测试a和b是否没有都引用同一个对象
assertEqualsNoOrder测试两个数组是否包含相同元素,并且忽略数据元素的排列顺序

1.硬断言

boolean flag1=
assertTrue(flag1);//全部是静态方法	,不需要实例化,不用创建
//硬断言
//这个用的最多
//失败了不会继续进行
assertTrue(flag2,"页面不存在退出");

2.软断言

@Test
public void test1(){
    SoftAssert soft = new SoftAssert();
    soft.asssertEquals(1,2);			//失败了,还会继续执行
    System.out.println("程序继续运行");
    soft.assertAll();					//最后加上assertAll
}

选中右键可以只跑这一个方法

SoftAssert的特点
1) 如果一个断言失败,会继续执行这个断言下的其他语句或者断言
3) 调用assertAll()在该用例的最后一个断言后面
4) 软断言的类,叫SoftAssert.java,这个类是需要创建实例对象,才能调用相关实例方法进行软断言



1、assertEquals方法可对java中所有数据类型进行断言比较
2、基本数据类型直接进行值比较进行断言
3、包装类及自定义继承Object的数据类型则使用equals方法进行比较
4、Set类型使用equals方法进行比较
5、数组类型,遍历元素,通过equals方法进行比较,如果数组元素为基本数据类型则使用值进行比较

6.6编写测试用例的步骤

1.编写测试代码逻辑

2.插入TestNG注解标签  --思考什么放在@BeforeClass,什么放在@BeforeSuit里面。

3.配置TestNG.xml文件,设定测试类、测试方法、测试分组的执行信息。
4.执行TestNG查看测试报告

ITestContext content

与ServletContent类似可以实现在不同方法中的***数据共享*** 。

ITestResult

ITestResult方法可以实现对@Test方法的监听 用@AfterMethod 方法参数为ITestResult result即可

import static org.testng.Assert.assertEquals;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;

public class Demo1 {
	int result;//这里这个值是为了说明 全局变量 和 ITestContext 作用类似
	@Test
	public void test1(ITestContext content) {
		result=10;//给全局变量赋值
		content.setAttribute("u_name", "admin");//把“admin”存入U_name中。
		assertEquals(1, 0);
	}
	
	@Test
	public void test2(ITestContext content)  {
		System.out.println(result);//输出全局变量
		System.out.println(content.getAttribute("u_name"));//输出admin
		assertEquals(2, 2);
	}
	//相当于传递参数     把admin从一个方法中传到另外一个方法中
	@Test
	public void test3() {
		assertEquals(1, 1);
	}
	
    //用ITestResult 来监听每个方法
	@AfterMethod
	public void bm(ITestResult result) {

		System.out.println("正在运行的方法是:"+result.getInstanceName());
		//如果失败就把失败的方法和报错信息打印出来
		if(result.getStatus()==ITestResult.FAILURE) {
            
			System.out.println(result.getName());
            
			System.out.println(result.getThrowable());
            
		}
	}

}

监听器

要求:

1.测试失败要求截屏,截屏代码写在哪呢???? 所以需要一个监听器的功能

2.所有的测试方法完成需要发邮件告诉相关人员执行情况。 有现成的代码,监听

IAnnotationTransformer

这是TestNG监听器的一种,

IAnnotationTransformer监听器接口只有一个方法,该方法的第一个参数为ITestAnnotation

test_2()方法执行了2次


public class App {

    @Test
    public void test_1() {
        System.out.println("Just run once");
    }

    @Test
	public void test_2() {
        System.out.println("Run twice");
    }
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;

public class TransFormDemo1 implements IAnnotationTransformer{
	
	@Override
	public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
		annotation.setInvocationCount(3);//设置执行次数,执行三次
//		annotation.setEnabled(false);
		
	}

}
import java.util.List;

import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;

public class DemoTestListener extends TestListenerAdapter{
//	当所有的测试方法执行完毕,被触发
	@Override
	public void onFinish(ITestContext testContext) {
		List<ITestResult> passList = this.getPassedTests();
		List<ITestResult> faildList = this.getFailedTests();
		ITestNGMethod[] methods = this.getAllTestMethods();
		
	
	}
	@Override
		public void onTestSuccess(ITestResult tr) {
			// TODO Auto-generated method stub
			super.onTestSuccess(tr);
		}
//	当某个测试方法失败,执行
	@Override
	public void onTestFailure(ITestResult tr) {
		System.out.println("失败,截屏");
		System.out.println(tr.getInstanceName()+"."+tr.getName());
//		
//		this.getAllTestMethods();
//		this.getFailedTests()
//		this.getPassedTests()
	}

}

界面执行测试用例

上面说的是用代码执行@Test方法,那我们现在通过图形界面来执行

import java.util.ArrayList;
import java.util.List;

import org.testng.TestNG;

public class JavaRunTestNG {
	public static void main(String[] args) {
		TestNG testNG=new TestNG();
		List<String> s1=new ArrayList<String>();
		s1.add(".\\test-output\\testng-failed.xml");
		testNG.setTestSuites(s1);
		testNG.run();
	}
}
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >

<suite name="s1" >
    
    
	<listeners>
		<listener class-name="com.gx.www.DemoTestListener"/>
	</listeners>
    
    
	<test name="t1">
		<classes>
			<class name="com.gx.www.Demo2" ></class>
		</classes>
	</test>
</suite>

可以用创建父类的方法来增加代码的复用性 BaseDriver

TestNG();
List s1=new ArrayList();
s1.add(".\test-output\testng-failed.xml");
testNG.setTestSuites(s1);
testNG.run();
}
}




```xml
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >

<suite name="s1" >
    
    
	<listeners>
		<listener class-name="com.gx.www.DemoTestListener"/>
	</listeners>
    
    
	<test name="t1">
		<classes>
			<class name="com.gx.www.Demo2" ></class>
		</classes>
	</test>
</suite>

可以用创建父类的方法来增加代码的复用性 BaseDriver

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值