軟件測試攻略(二十四):界面自動化之testNG&Java封裝

一、testNG

TestNG是Java中的一個測試框架。Java中已經(jīng)有一個JUnit的測試框架了。 TestNG比JUnit功能強大的多冀膝。 測試人員一般用TestNG來寫自動化測試噪漾。 開發(fā)人員一般用JUnit寫單元測試驻啤。
上一篇已經(jīng)提過框产,我們在pom.xml里面添加了testNG的依賴


image.png

二贰逾、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**

image.png

但是執(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)如下:
image.png

image.png

將testNG.xml拖到包下面。


image.png

testNG.xml右鍵靠汁,run as -> testNG Suit


image.png

觀察執(zhí)行結(jié)果:
image.png

三蜂大、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ù)化方式

  1. Parameters
  • 在testNG.xml里面配置參數(shù)化數(shù)據(jù)
<parameter name="userName" value="guoya"></parameter> 
<parameter name="password" value="Aa123!"></parameter> 
image.png

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);
    }
}
  1. 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ù)


image.png

保存為csv文件冒窍,

    @DataProvider(name="dataLogin")
    public static Object[ ][ ] dataLogin() {
        Object[ ][ ] obData = CSVReader.readCSV("E:/softwareData/dataLogin.csv");
        return obData;
    
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市豺鼻,隨后出現(xiàn)的幾起案子综液,更是在濱河造成了極大的恐慌,老刑警劉巖儒飒,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谬莹,死亡現(xiàn)場離奇詭異,居然都是意外死亡桩了,警方通過查閱死者的電腦和手機附帽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來圣猎,“玉大人士葫,你說我怎么就攤上這事∷突冢” “怎么了慢显?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵爪模,是天一觀的道長。 經(jīng)常有香客問我荚藻,道長屋灌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任应狱,我火速辦了婚禮共郭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘疾呻。我一直安慰自己除嘹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布岸蜗。 她就那樣靜靜地躺著尉咕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪璃岳。 梳的紋絲不亂的頭發(fā)上年缎,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音铃慷,去河邊找鬼单芜。 笑死,一個胖子當(dāng)著我的面吹牛犁柜,可吹牛的內(nèi)容都是我干的洲鸠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼赁温,長吁一口氣:“原來是場噩夢啊……” “哼坛怪!你這毒婦竟也來了淤齐?” 一聲冷哼從身側(cè)響起股囊,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎更啄,沒想到半個月后稚疹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡祭务,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年内狗,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片义锥。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡柳沙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拌倍,到底是詐尸還是另有隱情赂鲤,我是刑警寧澤噪径,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站数初,受9級特大地震影響找爱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泡孩,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一车摄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧仑鸥,春花似錦吮播、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泵琳,卻和暖如春摄职,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背获列。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工谷市, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人击孩。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓迫悠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巩梢。 傳聞我的和親對象是個殘疾皇子创泄,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 感謝原作者的奉獻,原作者博客地址:http://blog.csdn.net/zhu_ai_xin_520/arti...
    狼孩閱讀 14,012評論 1 35
  • 本文首發(fā)于 https://jaychen.cc作者 jaychen 寫一篇小文括蝠,介紹一下 Java 下單元測試工...
    jaychenIsUsed閱讀 1,879評論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理鞠抑,服務(wù)發(fā)現(xiàn),斷路器忌警,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 文/十二月墨 一座陌生的城市法绵,不知該往哪走箕速! 一顆千瘡百孔的心,只是想找個陌生的環(huán)境讓它安靜而已朋譬! 愛情盐茎,曾經(jīng)讓我...
    十二月墨閱讀 396評論 0 3
  • 清晨六點,像冬眠的小獸感知到春之溫煦般徙赢,沉睡的意識自然覺醒字柠,像黑夜里悄然亮起的一盞燈滑进;緊接著,像是暫停的音樂重新播...
    M夢兮閱讀 418評論 2 7