關於接口測試, 我們之前介紹過很多方法了, 有postman, soapUI, Jmeter等, 他們各有優勢和劣勢, 今天和大家分享的是如何用java TestNG來實現接口測試.
開始測試之前需要如下准備工作:
1. IDE環境, Intellij 或者eclipse, 個人推薦使用Intellij.
2. JKD1.8 以上
3. Maven 環境 Maven環境配置
4. 被測接口(京東web版登錄API)
首先來看下jd 登錄接口,chrome瀏覽器打開www.jd.com, 使用chrome開發者工具, Windows用戶按鍵盤F12, 將tab切換到Network, 使用密碼登錄方式, 登錄成功后, 我們就可以獲取到登錄接口了,如果無法獲取,使用charles第三方工具也是妥妥的.
看下我登錄后開發者工具:
接着在ide中創建項目, 我們選擇maven來創建項目是不是非常的簡單, 一步步都是next下去即可, Intellij就會幫你把maven項目創建好.
如果你的IDE里沒有maven,也不用着急, 在菜單的Preference->plugs里可以添加所需插件
在創建好的項目中, 我們首先進入pom.xml文件, 這是maven的配置文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.api.test</groupId> <artifactId>test</artifactId> <version>1.0-SNAPSHOT</version> </project >
這邊需要添加相應的項目管理依賴包, 如testng等, 適個人情況添加所需的依賴包.
<properties>
<!-- 指明編譯源代碼時使用的字符編碼,maven編譯的時候默認使用的GBK編碼,
通過project.build.sourceEncoding屬性設置字符編碼,告訴maven這個項目使用UTF-8來編譯 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--這里可以設置需要運行group-->
<groupsTest>execShell</groupsTest>
</properties>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.10-FINAL</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.54</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>net.sf.ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
如果需要maven來幫你build項目也是可以的, 方法也是非常簡單
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>8</source> <target>8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.19.1</version> <configuration> <!--<suiteXmlFiles>--> <!--<suiteXmlFile>./src/test/testng.xml</suiteXmlFile>--> <!--</suiteXmlFiles>--> <threadCount>1</threadCount> <forkCount>1</forkCount> <reuseForks>true</reuseForks> <forkMode>once</forkMode> <argLine>-Dfile.encoding=UTF-8</argLine> <groups>${groupsTest}</groups> <includes> <include>**/*Test.java</include> </includes> </configuration> </plugin> </plugins> </build>
測試思路:
以下示例中參數都來自於chrome開發者工具中捕獲的信息, 因為被測接口是post方法,且在接口中聲明了提交方式:
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
所以在接口測試過程中, form data里的信息都要作為參數添加.
完成以上內容就可以開始創建一個測試的java類, 在你的項目的/test/java下面創建 NewApiTest.java
import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.testng.annotations.Test; import java.io.IOException; import java.util.ArrayList; import java.util.List; /* * @auth:louiezhou * @return: 測試數據 * @parame: * */ public class NewApiTest { CloseableHttpResponse response=null; String entityStr = null; //登錄url String url ="https://passport.jd.com/uc/loginService?uuid=a25f6873-4dd9-4334-ad4c-b8e3f&ReturnUrl=https%3A%2F%2Fwww.jd.com%2F&r=0.8097302259069017&version=2015"; @Test(invocationCount = 1, threadPoolSize = 0) public void JdLoginTest() throws IOException { // 獲取連接客戶端工具 CloseableHttpClient httpClient=HttpClients.createDefault(); // 創建POST請求對象 HttpPost httpPost=new HttpPost(url); // httpPost.addHeader post請求 header httpPost.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"); httpPost.addHeader("User-Agent:","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"); // List<Header> headerList= Lists.newArrayList(); // headerList.add(new BasicHeader(HttpHeaders.CONTENT_TYPE,"application/x-www-form-urlencoded; charset=UTF-8")); // headerList.add(new BasicHeader(HttpHeaders.USER_AGENT,"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36")); //參數封裝對象 List<NameValuePair> params=new ArrayList<NameValuePair>(); try{ params.add(new BasicNameValuePair("uuid","a25f6873-4dd9-4334-ad4c-e6f8992b8e3f")); params.add(new BasicNameValuePair("eid","BHM2GM3F6FVMTA3YNGT4JRDJBHAWFK7MSHDPF3SU4FHFSOLMBUP77TDQE5EB43BZPDT5J6PAQ6CFI")); params.add(new BasicNameValuePair("fp","f0aef80fec848c0a78c823bd234")); params.add(new BasicNameValuePair("loginType","c")); params.add(new BasicNameValuePair("loginname","zhangsan")); params.add(new BasicNameValuePair("nloginpwd","Y2nHBYQrhMS1/YvBs+cW8rrvbW1CYlmX61xfoLx7tgSpbgxZ8+/HCgefeAXphJVmefDdN/3d3UQLnFiyl7GSkGjZQNU4pw+9+202NovcR6q9G/haGpNKp/5h+Xs+J7BrUfKXvkmdmKS0fIs7ly0K+OY/BHKcYg=")); params.add(new BasicNameValuePair("authcode","107fdb562e32406cab356c3ff97")); params.add(new BasicNameValuePair("pubKey","MIGfMA0GCSqGSIb3DQEgQDC7kw8r6tq43pwApYvkJ5laljaN9BZb21TAIfT/vexbobzH7Q8SUdP5uDPXEBKzOjx2L28y7Xs1d9v3tdPfKI2LR7PAzWBmDMn8riHrDDNpUpJnlAGUqJG9ooPn8j7YNpcxCa1iybOlc2kEhmJn5uwoanQq+CA6agNkqly2H4j6wIDAQAB")); params.add(new BasicNameValuePair("sa_token", "B68C442BEF615E156C81EFA53D580517BB9357FB9516A01E25761124AE9AF7B3CFA3C38D38484A734CB58C286401C2DEC2A5DFF3C9E856280AF80D4851C9B0239587771E8DC06B46454644D4908F4DC165CB70D86EAC7276BFBE489FFE2324EDDC5F71043BFB99B3D6E238B1AE9E67C3F297E0993B8497B1287640777CF4FFBA52FF032510AD19D7F371541C798742CB4378E5DD2119BADE9078310468AF8436A2B88593A92EEAF16FCFD55CD7F121B58D7A9A833D74068FACC5A6D6D8C3D1A850245F0742DEEC12BACF0FF9D5853FFDF1B37AC6A5E676DC635896AFD884D0BBB8A490E57234DF65A76AF189908F4AB80AEA36E56F6DD110EF7D36D119BB77F0B65774780348FFE859A68D2E0B3A3CDDAFD1BEFCD401530D536C8EF68B618969FC2FFD658FE0BA7BC2E7250F9CCDBB8F9AF360FC293F294A7279EA70043E860784C2E2CF11181C44561794A32AADDB2AC37B1294C08E7B63C85E6561F138195ECCF28EA0F08FB5A16DB7A20814DD914FC0C8A12BF29FFC4F73DD39361EBA1A849BB25B9F5957589347E205573754EA468D809CCCA698BFAB16373516DC8F5FEE8A24C2306850D601D6827C161F1A83057E0F93A97A0C034E")); params.add(new BasicNameValuePair("seqSid","31251240")); params.add(new BasicNameValuePair("useSlideAuthCode","1")); params.add(new BasicNameValuePair("_t","_t")); // 使用URL實體轉換工具 UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(params, "UTF-8"); httpPost.setEntity(entityParam); // 執行請求 response=httpClient.execute(httpPost); // 獲得響應的實體對象 HttpEntity entity=response.getEntity(); // 使用Apache提供的工具類進行轉換成字符串 int code =response.getStatusLine().getStatusCode(); System.out.println("StatusCode: " + code); Assert.assertEquals(200,code); entityStr=EntityUtils.toString(entity,"UTF-8"); System.out.println("接口返回結果是:="+entityStr); }catch(Exception e){ e.printStackTrace(); }finally { //釋放資源 if(httpClient!=null) { httpClient.close(); } if (response!=null){ response.close(); } } } }
聲明:
1.示例使用testng, 因此必須在方法上添加@Test符號,便於被識別到是測試代碼塊
2.使用了java的httpclient, 它是一個客戶端的http通訊實現庫.
HttpClient的目標是發送和接收HTTP 報文,不緩存內容, 重新格式化請求/重定向URI,或者其它和 HTTP 運輸無關的功能。
3.使用了List 的實現類ArrayList來封裝對象, ArrayList的優點是查詢速度比較快.
右鍵java文件, 選擇run 即可執行, 讓我們來看下執行結果:
思考:
這樣一個接口測試就實現了, 但作為一名嚴格要求自我的資深測試工程師來說, 這樣的設計合理嗎? 是否滿足數據和測試業務分離, 斷言是否充足, 代碼是否可以重用, 怎么去管理N多個測試用例, 怎么降低代碼耦合度, 怎么進行多線程測試, 測試報告如何展示,如何自動構建, 諸多問題等待解決.
請持續關注我, 和你分享更多精彩內容.
Story:
人要有一個奮斗目標,這樣活起來才有精神,有奔頭。整天無所事事、無聊至極的,就是因為沒有目標。從小就要為自己的人生制定一個目標,然后不斷地向它靠近,終有一天你會達到這個目標。如果從小就糊里糊塗,對自己的人生不負責任,沒有目標沒有方向,那這一生也難有作為。每個人出門,都會有自己的目的地,如果不知道自己要去哪里,漫無目的地閑逛,那速度就會很慢;但當你清楚你自己要去的地方,你的步履就會情不自禁地加快。如果你分辨不清自己所在的方位,你會茫然若失;一旦你弄清了自己要去的方向,你會精神抖擻。這就是目標的力