通過junit/TestNG+java簡單實現接口的自動化測試


轉自:https://blog.csdn.net/qq_15945247/article/details/78791017

JUnit是一個開發源代碼的Java測試框架,用於編寫和運行可重復的測試。它是用於單元測試框架體系xUnit的一個實例(用於java語言)。主要用於白盒測試,回歸測試。

個人理解:每次軟件做版本迭代,為防止引入新的問題,需要對重要功能的接口進行基本功能測試。此時可以考慮做成自動化(在版本迭代較快,主要功能基本不變化的接口適用)

eclipse中使用JUnit(JUnit3)

之前本人測試使用JUnit3,目前JUnit4已經普及。JUnit 4是與JUnit3完全不同的API,它基於Java 5.0中的注解、靜態導入等構建而成。JUnit 4更簡單、更豐富、更易於使用,並引入了更為靈活的初始化和清理工作,還有限時的和參數化測試用例

JUnit3下載地址:https://pan.baidu.com/s/1jH9Kv90 
JUnit4下載地址:https://pan.baidu.com/s/1qYLZC7a

在eclipse中新建工程,然后在configure build path中導入junit jar包,在eclipse的工程中引入Junit lib庫,然后可以創建Junit Test Case或者Junit Test Suite

這里寫圖片描述

接口測試用例

這里展示測試用例的編寫過程

  • 測試要求

    某數據平台提供接口給第三方使用,第三方根據接口托管自己的數據。需要測試平台提供的所有對外接口的功能,確保正常

  • 准備工作

    獲取提供給第三方的Api(jar包形式),在eclipse中新建工程,導入該jar包,導入JUnit包,新建package,針對每個方法創建對應的測試類等,如下圖所示 
    這里寫圖片描述

  • 目錄結構及類說明 
    在cn.cstor.wwy.test存放測試類,每個方法對應一個測試類,比如平台提供AddDevice接口,所以要新建一個TestAddDevice類,在TestAddDevice類中存在多個測試方法

package cn.cstor.wwy.test; import cn.cstor.wwy.test.util.Count; import java.io.UnsupportedEncodingException; import org.apache.thrift.TException; import cn.cstor.wwy.test.util.Const; import cn.cstor.wwy.test.util.CustomString; import cproc.datacube.client.api.ClientBaseApi; import cproc.datacube.client.api.ClientBaseApiService; import cproc.datacube.client.api.ClientDevelopApi; import cproc.datacube.client.api.ClientDevelopApiService; import cproc.datacube.client.entity.AppInfo; import cproc.datacube.client.entity.DeviceConditionInfo; import cproc.datacube.client.entity.ReObject; import cproc.datacube.client.entity.UserInfo; import junit.framework.TestCase; import java.lang.Math; //addDevice public class TestAddDevice extends TestCase{ CustomString cString = new CustomString(); AppInfo app = new AppInfo(); UserInfo user = new UserInfo(); ClientDevelopApi deveApi = new ClientDevelopApiService(); ClientBaseApi baseApi = new ClientBaseApiService(); Count ct = new Count(); int startct = 0; int endct = 0; protected void setUp() throws UnsupportedEncodingException, TException { user.setUserName(Const.USERNAME); user.setAccessId(Const.CERTIFICATE); app.setAppId(Const.APPID); app.setUserInfo(user); } protected void tearDown() throws TException { } //正常用例 public void testAddDevice() throws TException { //設置設備信息 startct = ct.getPoint(); DeviceConditionInfo deviceCon = new DeviceConditionInfo(); int x = (int)(Math.random()*Math.random()*Math.random()*1000000); deviceCon.setDeviceid("device" + x); deviceCon.setDip("192.168.10.1"); deviceCon.setServicecode("1"); deviceCon.setVrs("v0.1"); ReObject reObject = deveApi.addDevice(app,deviceCon); endct = ct.getPoint(); System.out.println(startct); System.out.println(endct); assertEquals(true,reObject.isSuccess()); assertEquals(startct - 1,endct); } //設備名為空 public void testAddDeviceNullDevId() throws TException { startct = ct.getPoint(); DeviceConditionInfo deviceCon = new DeviceConditionInfo(); deviceCon.setDeviceid(""); deviceCon.setDip("192.168.10.1"); deviceCon.setServicecode("1"); deviceCon.setVrs("v0.1"); ReObject robj = deveApi.addDevice(app,deviceCon); endct = ct.getPoint(); assertEquals(false,robj.isSuccess()); assertEquals("查詢條件不足",robj.getMsg()); assertEquals(startct,endct); } //設備名稱太長 public void testAddDeviceLongDevName() throws TException { startct = ct.getPoint(); DeviceConditionInfo deviceCon = new DeviceConditionInfo(); String devid = cString.generateString(200); deviceCon.setDeviceid(devid); deviceCon.setDip("192.168.10.1"); deviceCon.setServicecode("1"); deviceCon.setVrs("v0.1"); ReObject reObject = deveApi.addDevice(app,deviceCon); endct = ct.getPoint(); assertEquals(false,reObject.isSuccess()); assertEquals("插入數據失敗!",reObject.getMsg()); assertEquals(startct,endct); } //ip地址為空 public void testAddDeviceNullIP() throws TException { //設置設備信息 startct = ct.getPoint(); DeviceConditionInfo deviceCon = new DeviceConditionInfo(); int x = (int)(Math.random()*Math.random()*Math.random()*1000000); deviceCon.setDeviceid("device" + x); deviceCon.setDip(""); deviceCon.setServicecode("1"); deviceCon.setVrs("v0.1"); ReObject reObject = deveApi.addDevice(app,deviceCon); endct = ct.getPoint(); assertEquals(true,reObject.isSuccess()); assertEquals(startct - 1,endct); } //ip格式不正確 public void testAddDeviceWrongIP() throws TException { //設置設備信息 startct = ct.getPoint(); DeviceConditionInfo deviceCon = new DeviceConditionInfo(); int x = (int)(Math.random()*Math.random()*Math.random()*1000000); deviceCon.setDeviceid("device" + x); deviceCon.setDip("123.12.25.23.212"); deviceCon.setServicecode("1"); deviceCon.setVrs("v0.1"); ReObject reObject = deveApi.addDevice(app,deviceCon); endct = ct.getPoint(); assertEquals(true,reObject.isSuccess()); assertEquals(startct - 1,endct); } }

在cn.cstor.wwy.test.util中存放一些常量信息 
Const.java:存放用戶認證信息,應用信息,測試創建表名

package cn.cstor.wwy.test.util; public interface Const { // user info String USERNAME = "shenpp"; String CERTIFICATE = "C2HLBNBWMTUWMDI1NDCXNTI2MQ=="; String APPID = "0542051559"; String TABLENAME="CREATEBYINTERFACE"; }

 

Count.java:獲取積分方法 //測試需要對比積分,但是沒有借口查詢,只能通過web頁面查詢,故增加該方法

package cn.cstor.wwy.test.util;

public class Count { public int getPoint() { int count = 0; String url = "http://192.168.10.105:8080/queryPointsForTest?uid=3450&accessid=C2HLBNBWMTUWMDI1NDCXNTI2MQ=="; try { String result = HttpUtil.getHttpContent(url,""); String[] res1 = result.split(":"); String[] res2 = res1[1].split("}"); count = Integer.valueOf(res2[0]).intValue(); } catch (Exception e) { e.printStackTrace(); } return count; } }

 

CustomString.java :生成一段隨機字符串,測試使用

package cn.cstor.wwy.test.util;

import java.util.Random;

public class CustomString { public String generateString(int clength) { String base = "abcdefghijklmnopqrstuvwxyz"; Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < clength; i++) { int number = random.nextInt(base.length()); sb.append(base.charAt(number)); } return sb.toString(); } }

 

HttpUtil.java :設置http訪問的參數

package cn.cstor.wwy.test.util; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; public class HttpUtil { public static String getHttpContent(String url,String parameterData ) throws Exception { HttpURLConnection connection = null; // String content = ""; OutputStream outputStream = null; OutputStreamWriter outputStreamWriter = null; InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader reader = null; StringBuffer resultBuffer = new StringBuffer(); String tempLine = null; try { URL address_url = new URL(url); connection = (HttpURLConnection) address_url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setDoInput(true); connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("Accept-Charset", "utf-8"); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); connection.setRequestProperty("Content-Length", String.valueOf(parameterData.length())); //設置訪問超時時間及讀取網頁流的超市時間,毫秒值 System.setProperty("sun.net.client.defaultConnectTimeout","3000"); System.setProperty("sun.net.client.defaultReadTimeout", "3000"); outputStream = connection.getOutputStream(); outputStreamWriter = new OutputStreamWriter(outputStream); outputStreamWriter.write(parameterData); outputStreamWriter.flush(); if (connection.getResponseCode() >= 300) { throw new Exception("HTTP Request is not success, Response code is " + connection.getResponseCode()); } inputStream = connection.getInputStream(); inputStreamReader = new InputStreamReader(inputStream); reader = new BufferedReader(inputStreamReader); while ((tempLine = reader.readLine()) != null) { resultBuffer.append(tempLine); } }finally { if(connection !=null){ connection.disconnect(); } } return resultBuffer.toString(); } }

自動化測試

我所理解的接口自動化測試就是能一次性執行上述編寫的所有測試類的測試方法,如此可以通過如下方法實現:

在cn.cstor.wwy.test包中新建JUnit Test Suite,名稱為TestAll

import junit.framework.Test; import junit.framework.TestSuite; public class TestAll { public static Test suite() { TestSuite suite = new TestSuite(AllTests.class.getName()); //$JUnit-BEGIN$ //$JUnit-END$ return suite; } }

 

在中間加入所有的測試類,這樣執行TestAll.java就能執行所有接口的測試用例

package cn.cstor.wwy.test; import junit.framework.Test; import junit.framework.TestSuite; public class TestAll { public static Test suite() { TestSuite suite = new TestSuite(TestAll.class.getName()); suite.addTestSuite(TestGetAllAppDevices.class); suite.addTestSuite(TestCreateTable.class); suite.addTestSuite(TestGetTableInfo.class); suite.addTestSuite(TestAddTableColumns.class); suite.addTestSuite(TestAddTableRows.class); suite.addTestSuite(TestDeleteTableRows.class); suite.addTestSuite(TestGetTableRowsByDeveApi.class); suite.addTestSuite(TestGetTableRowsByBaseApi.class); suite.addTestSuite(TestGetAllTableInfo.class); suite.addTestSuite(TestGetTopOneResult.class); suite.addTestSuite(TestGetTableRowsByRange.class); suite.addTestSuite(TestGetTableRowsByPKRange.class); suite.addTestSuite(TestGetTableRowsByNewPageCondition.class); suite.addTestSuite(TestDeleteTable.class); suite.addTestSuite(TestAddDevice.class); suite.addTestSuite(TestGetDeviceTopOneResult.class); suite.addTestSuite(TestGetDevsStatisticWithTimeDivision.class); suite.addTestSuite(TestGetHardWareStatisticWithTimeDivision.class); // suite.addTestSuite(TestGetQueryResult.class); suite.addTestSuite(TestGetServerCurrentTime.class); suite.addTestSuite(TestGetStatisticByColumn.class); suite.addTestSuite(TestGetTableRowsByPage.class); suite.addTestSuite(TestQueryDeviceDataAvgValues.class); suite.addTestSuite(TestQueryLongitudeLatitude.class); return suite; } }

 

常用的測試注解和方法(JUnit4)

@BeforeClass 在測試類被調用前執行,一個測試類中聲明一次,執行一次 
@AfterClass 在測試類調用結束后執行,一個測試類中聲明一次,執行一次 
@Before 在每個@Test(測試方法)調用前執行 //Junit3中的setup方法 
@After 在每個@Test調用后執行 //Junit3中的teardown方法 
@Test 使用此注解的方法是一個單元測試用例 
@Ignore 暫時不執行的測試方法

@Test(timeout = 2000) //用例執行時間不能超過2s 
@Test(expected = ArithmeticException.class) //此方法執行后,必須拋出ArithmeticException才能認為測試執行成功

assert //包含此關鍵字的為斷言方法

使用TestNG

使用TestNG需要在eclipse中安裝TestNG插件

  1. 在eclipse界面選擇“Help”–“install New Software”,選擇【Add】,在location中輸入http://beust.com/eclipse,選擇TestNG,點擊【Next】,開始下載安裝。安裝完成后,選擇“Build Path”“Configure Build Path”,在“Task Repository”下有“TestNG”標簽。安裝成功。(此方法如果eclipse版本或者以前是否安裝卸載過的不同會造成此方法成功率很小);

  2. 在eclipse界面選擇“Help”–“Eclipse Marketplace”中進行查找TestNG 然后進“install” 。(此方法最簡便,力薦。);

TestNG需要使用testng.xml配置層級結構

1、TestSuite由一個或多個Test組成 
2、Test由一個或多個測試Class組成 
3、一個測試Class由一個或多個測試方法組成

<suite>
    <test>
        <classes>
            <method> </method> </classes> </test> ...... </suite>

 

TestNG常用注解

@BeforeSuite //在當前測試集合的任意測試用例開始前執行 
@AfterSuite //在當前測試集合的所以測試用例結束后執行 
@BeforeTest //…… 
@AfterTest 
@BeforeGroups 
@AfterGroups 
@BeforeClass 
@AfterClass 
@BeforeMethod 
@AfterMethod 
@Test

給測試方法分組 
@Test (groups = {“xx1”}) @Test (groups = {“xx2”})

調用單個分組testng.xml

<suite name="suitetest"> <test name="test"> <groups> <run> <include name="xx1"/> </run> </groups> <classes> <class name="pp.com.TestClass1"/> <class name="pp.com.TestClass2"/> </classes> </test> </suite>

 

調用多個分組testng.xml

<groups> <define name="All"> <include name="xx1"> <include name="xx2"> </define> <run> <include name="xx1"/> </run> </groups>

 

依賴測試

@Test (dependsOnMethods = {“testMethod2”}) //可以保證先執行testMethod2再執行該方法 
特定順序執行測試用例 
@Test (priority = 1) //priority從0開始,0優先級最高 
跳過摸個測試方法 
@Test (priority = 1,enabled=false)

測試報告中的自定義日志

方法中增加 Reporter.log(“打印日志”) 打印出來的日志會在TestNG測試報告中

@Parameters(“browser”) 定義browser參數,在測試執行過程中,此參數的具體值由testng.xml中的

<parameter name="browser" value="firefox"/>

配置來傳遞給測試程序

參考:https://blog.csdn.net/wanglha/article/details/50331577

https://testerhome.com/topics/10525

https://blog.csdn.net/do_your_self_thing/article/details/6247834

 


免責聲明!

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



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