一、testNG
TestNG是Java中的一個測試框架。Java中已經(jīng)有一個JUnit的測試框架了。 TestNG比JUnit功能強大的多冀膝。 測試人員一般用TestNG來寫自動化測試噪漾。 開發(fā)人員一般用JUnit寫單元測試驻啤。
上一篇已經(jīng)提過框产,我們在pom.xml里面添加了testNG的依賴
二贰逾、testNG注解:
@BeforeSuite
被@BeforeSuite注解的方法悬荣,將會在testng定義的xml根元素里面的所有執(zhí)行之前運行
@AfterSuite
被@AfterSuite注解的方法,將會在testng定義的xml根元素里面的所有執(zhí)行之后運行疙剑。
@BeforeTest
被@BeforeTest注解的方法氯迂,將會在一個元素定義的所有里面所有測試方法執(zhí)行之前運行。
@AfterTest
被@AfterTest注解的方法言缤,將會在一個元素定義的所有里面所有的測試方法執(zhí)行之后運行嚼蚀。
@BeforeClass
被@BeforeClass注解的方法,將會在當(dāng)前測試類的第一個測試方法執(zhí)行之前運行管挟。
@AfterClass
被@AfterClass注解的方法驰坊,將會在當(dāng)前測試類的最后一個測試方法執(zhí)行之后運行。
@BeforeMethod
被@BeforeMethod注解的方法,將會在當(dāng)前測試類的每一個測試方法執(zhí)行之前運行拳芙。
@AfterMethod
被@AfterMethod注解的方法察藐,將會在當(dāng)前測試類的每一個測試方法執(zhí)行之后運行
@Test 注解
@Test 注解是TestNG的核心注解,被打上該注解的方法舟扎,表示為一個測試方法
暫時我們先主要記追址伞:
- @BeforeClass
被@BeforeClass注解的方法,將會在當(dāng)前測試類的第一個測試方法執(zhí)行之前運行睹限。 - @AfterClass
被@AfterClass注解的方法譬猫,將會在當(dāng)前測試類的最后一個測試方法執(zhí)行之后運行。 - @Test 注解
@Test 注解是TestNG的核心注解羡疗,被打上該注解的方法染服,表示為一個測試方法
二、如何使用testNG
我們給設(shè)置環(huán)境變量叨恨、打開瀏覽器這個方法柳刮,添加注解@BeforeClass,表示在第一個測試方法執(zhí)行之前運行痒钝。給關(guān)閉瀏覽器這個方法添加注解@AfterClass秉颗,表示在最后一個測試方法執(zhí)行之后運行。
@BeforeClass
public void startUp() {
//設(shè)置環(huán)境變量送矩,指定chromedriver的路徑
System.setProperty("webdriver.chrome.driver",
"src/main/resources/driver_2_38_v65-67/chromedriver.exe");
//設(shè)置瀏覽器的參數(shù)
ChromeOptions options = new ChromeOptions();
//最大化瀏覽器
options.addArguments("--test-type", "--start-maximized");
//打開瀏覽器
driver = new ChromeDriver();
}
@AfterClass
public void shutDown(){
//關(guān)閉瀏覽器
driver.close();
//關(guān)閉瀏覽器驅(qū)動
driver.quit();
}
@Test
public void openUrl(){
//打開要測的登錄頁面
driver.get("http://www.guoyasoft.com:8080/guoya-client");
}
@Test
//登錄
public void login() {
//定位用戶名框
WebElement userName= driver.findElement(By.id("userName"));
userName.clear();
//輸入用戶名
userName.sendKeys("wuling");
//定位密碼框
WebElement password= driver.findElement(By.id("password"));
password.clear();
//輸入密碼
password.sendKeys("0000");
//定位并點擊登錄
driver.findElement(By.id("loginBtn")).click();
}
給我們要測試的方法添加@test注解蚕甥,上述代碼給打開網(wǎng)頁方法和登錄方法添加@test注解
如何使用:
在給方法添加testNG注解后,直接右鍵類run as -> testNG test**
但是執(zhí)行@test的順序是怎樣的呢栋荸?
1菇怀、按照字母表順序執(zhí)行測試方法
如果需要測試的方法只有@Test,那么它將通過方法名的首字母按照字母表順序執(zhí)行
2晌块、給方法添加priority屬性
根據(jù)業(yè)務(wù)邏輯爱沟,給各個方法添加priority屬性,按照@Test(priority = 0)——>@Test(priority = 1)——>……@Test(priority = N)執(zhí)行摸袁。
3钥顽、在testNG.xml配置順序(推薦)
testNG.xml的基本結(jié)構(gòu)如下:
將testNG.xml拖到包下面。
testNG.xml右鍵靠汁,run as -> testNG Suit
觀察執(zhí)行結(jié)果:
三蜂大、Java封裝
實際的工作中,我們避免在業(yè)務(wù)流有過多的代碼干擾蝶怔,我們的業(yè)務(wù)操作奶浦,基本是定位元素-操作元素,比如輸入用戶名踢星、密碼澳叉、校驗碼的基本套路都是,定位文本框-清除文本框-向輸入文本內(nèi)容,那我們是否可以把這個套路封裝成一個方法成洗,需要用時五督,只用填幾個參數(shù),而節(jié)省空間去寫幾行代碼瓶殃。
//定位用戶名框
WebElement userName= driver.findElement(By.id("userName"));
//清除
userName.clear();
//輸入用戶名
userName.sendKeys("wuling");
將他封裝成一個方法充包,
public void textInput(String xp,String texts) {
WebElement textInp= driver.findElement(By.xpath(xp));
textInp.clear();
textInp.sendKeys(texts);
}
當(dāng)我們需要操作文本框時,只要調(diào)用這個方法遥椿,并且寫入文本框的地址基矮,和要輸入的內(nèi)容作為參數(shù)即可。
textInput("http://input[@id=userName]","wuling");
原本的三行代碼冠场,寫成一行即可家浇。
我們新建一個class文件來專門寫工具流,用一個專門寫業(yè)務(wù)流碴裙,這樣代碼更清晰明了钢悲。而且,工具流以后可以重復(fù)使用青团。業(yè)務(wù)邏輯更改譬巫,直接更改業(yè)務(wù)流即可咖楣,提高效率督笆。
我們將工具流新建為AutoBasic.class,
public class AutoBasic {
public WebDriver driver; //將driver設(shè)置為全局變量
//啟動瀏覽器
public void startUp() {
//設(shè)置環(huán)境變量诱贿,指定chromedriver的路徑
System.setProperty("webdriver.chrome.driver",
"src/main/resources/driver_2_38_v65-67/chromedriver.exe");
//設(shè)置瀏覽器的參數(shù)
ChromeOptions options = new ChromeOptions();
//最大化瀏覽器
options.addArguments("--test-type", "--start-maximized");
//打開瀏覽器
driver = new ChromeDriver(options);
sleep() ;
}
//關(guān)閉瀏覽器
public void shutDown(){
//關(guān)閉瀏覽器
sleep() ;
driver.close();
//關(guān)閉瀏覽器驅(qū)動
driver.quit();
}
public void sleep() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void openUrl(String url){
//打開要測的登錄頁面
driver.get(url);
sleep();
}
//input文本
public void textInput(String xp,String texts) {
WebElement textInp= driver.findElement(By.xpath(xp));
textInp.clear();
textInp.sendKeys(texts);
sleep();
}
//點擊按鈕
public void buttonInput(String xp) {
WebElement buttonInp= driver.findElement(By.xpath(xp));
buttonInp.click();
}
//下拉框
public void selectFunction(String xp, int i) {
Select select =new Select(driver.findElement(By.xpath(xp)));
select.selectByIndex(i);
}
//刷新
public void navRefresh() {
driver.navigate().refresh();
sleep();
}
新建一個class文件是業(yè)務(wù)流娃肿,SearchAuto.java
public class SearchAuto {
AutoBasic fz =new AutoBasic();//要使用AutoBasic.class的方法,先要實例化
//打開瀏覽器
@BeforeClass
public void startUp() {
fz.startUp();
}
@AfterClass
public void shutDown() {
fz.shutDown();
}
//打開網(wǎng)頁
@Test
public void openUrl() {
fz.openUrl("http://47.98.226.232:8080/guoya-medium/jsp/user/login.jsp");
}
@Test
//登錄
public void login() {
//輸入用戶名
fz.textInput("http://input[@id=\"userName\"]","guoya");
//輸入密碼
fz.textInput("http://input[@id=\"password\"]","Aa123!");
//輸入驗證碼
fz.textInput("http://input[@id=\"checkCode\"]","12345");
// 點擊登錄
fz.buttonInput("http://input[@id=\"loginBtn\"]");
}
@Test
//查詢
public void searchUN() {
fz.textInput("http://input[@name=\"userName\"]","guoya");
//點擊查詢
fz.buttonInput("http://tr[2]/td[8]/input");
}
@Test
public void navRefresh() {
fz.navRefresh();
}
@Test
public void searchEdu() {
fz.selectFunction("http://tr[1]/td[6]/select", 2);
fz.buttonInput("http://tr[2]/td[8]/input");
}
可以看到珠十,按照業(yè)務(wù)邏輯料扰,使用工具流里的方法,簡單清晰不迷糊焙蹭。
四晒杈、java封裝_參數(shù)化
public void login() {
fz.textInput("http://input[@id=\"userName\"]","guoya");
fz.textInput("http://input[@id=\"password\"]","Aa123!");
fz.textInput("http://input[@id=\"checkCode\"]","12345");
fz.buttonInput("http://input[@id=\"loginBtn\"]");
}
我們可以進一步講這套代碼封裝,將可能需要更改的數(shù)據(jù)寫成參數(shù)
public void login(String um,String pwd) {
fz.textInput("http://input[@id=\"userName\"]",um);
fz.textInput("http://input[@id=\"password\"]",pwd);
fz.textInput("http://input[@id=\"checkCode\"]","12345");
fz.buttonInput("http://input[@id=\"loginBtn\"]");
}
這樣我們完成整個登錄,就只需要寫:
login("guoya","Aa123!");
五孔厉、testNG參數(shù)化及斷言
(一)斷言
在Jmeter里我們已經(jīng)了解過斷言拯钻,它相當(dāng)于預(yù)期結(jié)果,一條測試用例撰豺,除了測試步驟粪般,測試數(shù)據(jù),必須要有斷言污桦,與Jmeter相同的亩歹,如果不設(shè)置斷言,如果不設(shè)置判斷,那自動化沒有意義小作。
語句:
Assert.assertEquals(result, true);
result是實際結(jié)果和true為預(yù)期結(jié)果亭姥,實際結(jié)果與預(yù)期結(jié)果做比較,一般用Boolean值做斷言數(shù)據(jù)顾稀。
在工具流AutoBasic.java寫入一個新的方法,得到實際的結(jié)果致份,返回一個boolean值。
public boolean assertPage(String s) {
boolean result=driver.getPageSource().contains(s);
return result;
}
@test
//登錄成功測試用例
public void loginSuccess(String um, String pwd){
//打開網(wǎng)頁
openUrl();
//登錄
login("guoya","Aa123!");
//實際結(jié)果础拨,如果登錄成功跳轉(zhuǎn)到查詢頁面氮块,故以“查詢”來做斷言,
//如果登錄成功诡宗,應(yīng)該返回true滔蝉,如果登錄不成功,應(yīng)該返回false
boolean result1=fz.assertPage("查詢");
//實際結(jié)果與預(yù)期結(jié)果比較
Assert.assertEquals(result1, true);
}
(二)參數(shù)化
testNG有兩種參數(shù)化方式
- Parameters
- 在testNG.xml里面配置參數(shù)化數(shù)據(jù)
<parameter name="userName" value="guoya"></parameter>
<parameter name="password" value="Aa123!"></parameter>
name后面是變量名塔沃,value后面是變量值蝠引,成對,即
userName="guoya"
password="Aa123!"
- 那如何使用呢
@Parameters({"userName","password"})
public void loginSuccess( String um, String pwd){
openUrl();
login(um,pwd);
boolean result1=fz.assertPage("查詢");
Assert.assertEquals(result1, true);
將原本的@test改為@Parameters({"userName","password"})即可蛀柴。
代碼進一步可以修改為
@Parameters({"userName","password"})
public void loginSuccess( String um, String pwd, String exp1){
//exp1就是斷言螃概,用斷言結(jié)果與true做比較,
//如果斷言結(jié)果為true鸽疾,exp結(jié)果為true吊洼,如果斷言結(jié)果為false,exp結(jié)果為false
boolean exp=exp1.equals("true");
openUrl();
login(um,pwd);
boolean result1=fz.assertPage("查詢");
if(result1){
Assert.assertEquals(result1, exp);
}else{
Assert.assertEquals(result1, exp);
}
}
- dataprovider
步驟
(1)使用@Test(dataProvider="sdata")給測試方法添加注解使用參數(shù)化的數(shù)據(jù)制肮;
(2)需要自己寫一個方法來存儲數(shù)據(jù)
方法1:二維數(shù)組存數(shù)據(jù)
@DataProvider(name="dataLogin")
public Object[][] dataLogin() {
Object[][] ob = new Object[4][3];//一組數(shù)據(jù)組成一條測試用例
//一條測試用例
//測試數(shù)據(jù)
ob[0][0]="wuling";
ob[0][1]="0000";
//斷言
ob[0][2]="true";
//一條測試用例
ob[1][0]="wuling1";
ob[1][1]="0000";
ob[1][2]="false";
//一條測試用例
ob[2][0]="wuling";
ob[2][1]="0001";
ob[2][2]="false";
//一條測試用例
ob[3][0]="wuling12";
ob[3][1]="0022";
ob[3][2]="false";
return ob;
}
方法2:csv文件存數(shù)據(jù)
保存為csv文件冒窍,
@DataProvider(name="dataLogin")
public static Object[ ][ ] dataLogin() {
Object[ ][ ] obData = CSVReader.readCSV("E:/softwareData/dataLogin.csv");
return obData;
}