自動化測試--testNG


該文章主要介紹 testNG(testing next generation,下一代測試技術)框架的使用。

1.首先安裝testNG

2.安裝完成后,創建maven項目,導入TESTNG和selenium依賴。

 

3.此時就可以直接創建testNG的測試類了

4.下面通過 百度頁面打開、輸入關鍵字、進行搜索,來簡單演示一下testNG的使用

 1 package testNGSelenium.testNGDemo;
 2 
 3 import org.testng.annotations.Test;
 4 import org.testng.annotations.BeforeTest;
 5 import org.testng.annotations.DataProvider;
 6 import org.testng.annotations.Parameters;
 7 
 8 import java.util.Date;
 9 import java.util.concurrent.TimeUnit;
10 
11 import org.apache.bcel.generic.NEW;
12 import org.apache.commons.collections.map.StaticBucketMap;
13 import org.openqa.selenium.By;
14 import org.openqa.selenium.WebDriver;
15 import org.openqa.selenium.WebElement;
16 import org.openqa.selenium.chrome.ChromeDriver;
17 import org.openqa.selenium.support.ui.ExpectedCondition;
18 import org.openqa.selenium.support.ui.WebDriverWait;
19 import org.testng.annotations.AfterTest;
20 
21 public class NewTest {
22     //聲明一個全局變量
23     private WebDriver driver;
24     
25     
26     
27   @Test
28   @Parameters({"keyWord"})
29   public void f(String keywords) {
30       final By input1 = By.id("kw");
31       final By button1 = By.id("su");
32       
33       //智能等待頁面的輸入框加載出來
34       try {
35         
36           (new WebDriverWait(driver, 3)).until(new ExpectedCondition<Boolean>() {
37 
38             public Boolean apply(WebDriver input) {
39                 WebElement element = input.findElement(input1);
40                 System.out.println(new Date());
41                 return element!= null;
42             }
43         });
44         
45     } catch (Exception e) {
46         System.out.println("輸入框3S還沒加載出來!!!");
47         e.printStackTrace();
48     }
49     
50       
51       //智能等待頁面的搜索按鈕加載出來
52       try {
53           (new WebDriverWait(driver, 3)).until(new ExpectedCondition<Boolean>() {
54 
55                 public Boolean apply(WebDriver input) {
56                     WebElement element = input.findElement(button1);
57                     System.out.println(new Date());
58                     return element!= null;
59                 }
60             });
61     } catch (Exception e) {
62         System.out.println("搜索按鈕等待了3秒還未加載出來");
63         e.printStackTrace();
64     }
65       
66       
67       driver.findElement(input1).sendKeys(keywords);
68       driver.findElement(button1).click();
69       
70       //等待10S,便於觀察結果
71       try {
72         Thread.sleep(10000);
73     } catch (InterruptedException e) {
74         
75         e.printStackTrace();
76     }
77       
78       
79   }
80   @BeforeTest
81   public void beforeTest()  {
82       driver = new ChromeDriver();
83       //窗口最大化
84       driver.manage().window().maximize();
85       
86       //加載頁面
87       driver.get("http://www.baidu.com");
88 
89       //設置頁面完全加載時間為3秒,第二個參數TimeUnit.SECONDS是指定時間單位
90         driver.manage().timeouts().pageLoadTimeout(3, TimeUnit.SECONDS);
91     
92   }
93 
94   @AfterTest
95   public void afterTest() {
96       driver.quit();
97   }
98 
99 }
View Code

上面代碼中用到了參數化,是需要在xml文件中設置的:

 

注意:

1.如果使用了參數化,則必須在XML文件上run as TestNG,否則會提示得不到參數的。

2.運行完成后,我們可以在項目目錄中看到多了一個test-output

 

對其中的emailable-report.html右鍵---open with---web browser,就可以打開如下的測試報告:

 

關於配置文件的簡單介紹:

通過上面的配置文件介紹,你可能會問,如果parallelism設置為true,是不是就可以跑多線程了??

是的!!!激不激動,開不開心!這個多線程可以支持我們做兩件事:

1.多個線程來跑同一套件中的不同方法、不同類、不同組件---------------------這樣,當我們的測試代碼很龐大的時候,會非常節省運行時間

2.用來測試多線程同步問題。舉個栗子-----------當有段代碼涉及到:不同線程訪問同一對象,並且會對該對象作出修改的時候,我們就可以針對這段代碼來設計:多個線程同時跑這段代碼,來測試下開發的線程同步是不是已經處理好啦。

下面來介紹下TestNG提供的多線程測試的不同使用方法,為了便於理解,這里使用的都是筆者寫的最簡單的demo:

一:並行的執行某方法

package testNGSelenium.testMethodParallelism;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;

public class MethodParallelismTest {
  @Test
  public void f1() {
      System.out.println("這里是方法1,執行該方法的當前線程ID為"+ Thread.currentThread().getId());
      
  }
  
  @Test
  public void f2() {
      System.out.println("這里是方法2,執行該方法的當前線程ID為"+ Thread.currentThread().getId());
  }
  
  @BeforeMethod
  public void beforeMethod() {
      System.out.println("這里是before,執行該方法的當前線程ID為"+ Thread.currentThread().getId());
    
  }

  @AfterMethod
  public void afterMethod() {
      System.out.println("這里是after,執行該方法的當前線程ID為"+ Thread.currentThread().getId());
  }

}

對應修改XML文件為:

該代碼的執行結果為:

 

二:並行的執行同一套間下同一組件中的不同class

package testNGSelenium.testClassesParallelism;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;

public class ClassesParallelism1 {

    
    @Test
    public void f() {
        System.out.println("test1" + Thread.currentThread().getId());
    }


    @BeforeClass
    public void beforeClass() {
        System.out.println("beforeClass1" + Thread.currentThread().getId());
    }

    @AfterClass
    public void afterClass() {
        System.out.println("afterClass2" + Thread.currentThread().getId());
    }

}
package testNGSelenium.testClassesParallelism;

import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class ClassesParallelism2 {
      @Test
      public void f() {
          System.out.println("test2" + Thread.currentThread().getId());
      }
      
      @BeforeClass
      public void beforeClass() {
          System.out.println("beforeClass2" + Thread.currentThread().getId());
      }

      @AfterClass
      public void afterClass() {
          System.out.println("afterClass2" + Thread.currentThread().getId());
      }

}

對應XML的設置:

該代碼的執行結果為:

三:同一套間中的不同組件並行

package testOneSuitTwoTest;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Parameters;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;

public class OneSuitTwoModuleTest {

    
    @Test
    @Parameters({"location"})
    public void f(String p) {
        System.out.println(p);
        System.out.println("Test---thread" + Thread.currentThread().getId());
    }

    @BeforeMethod
    public void beforeMethod() {
        System.out.println("beforeMethod---thread" + Thread.currentThread().getId());
    }

    @AfterMethod
    public void afterMethod() {
        System.out.println("afterMethod---thread" + Thread.currentThread().getId());
    }

/*    @DataProvider
    public Object[][] dp() {
        return new Object[][] { new Object[] { 1, "a" }, new Object[] { 2, "b" }, };
    }*/

    @BeforeClass
    public void beforeClass() {
        System.out.println("beforeClass---thread" + Thread.currentThread().getId());
    }

    @AfterClass
    public void afterClass() {
        System.out.println("afterClass---thread" + Thread.currentThread().getId());
    }

    @BeforeTest
    public void beforeTest() {
        System.out.println("beforeTest---thread" + Thread.currentThread().getId());
    }

    @AfterTest
    public void afterTest() {
        System.out.println("afterTest---thread" + Thread.currentThread().getId());
    }

    @BeforeSuite
    public void beforeSuite() {
        System.out.println("beforeSuite---thread" + Thread.currentThread().getId());
    }

    @AfterSuite
    public void afterSuite() {
        System.out.println("afterSuite---thread" + Thread.currentThread().getId());
    }

}

對應的XML設置為:

上面代碼的執行結果為;

 

四:多線程執行某方法

package testNGSelenium.moreThreadTest;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;

public class MoreThreadTest {
    //這里代表 啟動三個線程,該方法總共執行9遍,設置整個測試方法的超時時間為2S
  @Test(threadPoolSize=3,invocationCount=9,timeOut=2000)
  public void f() {
      System.out.println("Test---threadId:"+Thread.currentThread().getId());
  }
  
  @BeforeTest
  public void beforeTest() {
  }

  @AfterTest
  public void afterTest() {
  }

}

對應的XML文件並沒有特別設置啥參數。

 

執行結果為:

 

 

注意點:

1.如果有童鞋在運行TESTNG套件的時候,遇到了ElementTravelsal找不到的問題,則在自己的pom.xml文件中引入依賴包:xml-apis

<!-- https://mvnrepository.com/artifact/xml-apis/xml-apis -->
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>

 

2.如果遇到運行程序之后,在console窗口遇到了亂碼:

請打開eclipse.ini文件,並添加: -Dfile.encoding=UTF-8

 

3.一個xml中間,只能有一個suite標簽;

一個suite可以有多個test,test名稱必須不同(否則報錯:Two tests in the same suite cannot have the same name);

一個test中間可以包含多個class,

一個class里面可以包含多個方法

 

4.在testNg的 suite file中,添加上

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

相當於標簽控制,只有合法標簽才能輸入。否則報錯。

 

5.如果讀者使用的開發工具是IDEA,那么久不需要安裝testNG的插件了。IDEA是自帶了testNG的插件的。只要在maven中添加testNg的包就可以了。

 

6.老的版本中 

<suite name="suitname1" parallel="true" thread-count="2">
parallel的值是沒有“true”的。
分為tests,classes,methods級別
tests:不同test tag下的用例可以在不同的線程執行,相同test tag下的用例只能在同一個線程中執行
classes:不同class tag下的用例可以在不同的線程執行,相同class tag下的用例只能在同一個線程中執行。
methods:所有用例都可以在不同的線程去執行。


7.關於dataprovider的並發

https://www.cnblogs.com/znicy/p/6534893.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM