DataProvideTool類:利用testng@DataProvider的注解功能獲取數據源,通過為注解命名來區分不同的數據源,詳見下面代碼:
package loginjdtest;
import org.testng.annotations.DataProvider;
import utl.ExcelReader;
/**
* Created by jiangcui on 2018/5/25.
*/
public class DataProvideTool {
@DataProvider(name = "LoginData")
public Object[][] login() {
System.out.println("開始測試");
// 測試數據准備
String file = "C:\\Users\\jiangcui\\IdeaProjects\\httpclient\\src\\main\\TestData\\LoginTest.xlsx";
//String file = "." + File.separator + "TestData" + File.separator + "LoginTest.xlsx";
Object[][] records ;
records = ExcelReader.getExpectationData(file, "login");
return records ;
}
@DataProvider(name = "data1")
public Object[][] createdata() {
return new Object[][] {
{"lilei", 20, "football"},
{"hanmeimei", 18, "music"},
{"wangnima", 25, "baozoumanhua"}
};
}
}
FirstTest類:具體實現類,httpclient具體應用,詳見下方代碼:
package loginjdtest;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
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.json.JSONObject;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import utl.ExcelReader;
import utl.JsonFormatTool;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by jiangcui on 2018/5/24.
*/
public class FirstTest {
private CloseableHttpClient closeableHttpClient = HttpClients.createDefault();
private HttpPost httpPost;
private HttpResponse httpResponse;
private HttpEntity httpEntity;
private String postResult = "";
@Test(dataProvider = "LoginData",dataProviderClass = DataProvideTool.class)
public void loginJDTest(String CaseDescription
,String loginUrl,String uuid,String eid,String fp,String _t,String loginType,String loginname,
String nloginpwd,String authcode,String pubKey,String sa_token)
{
System.out.println(loginname +"------"+ uuid +"------" +eid);
//配置超時時間
/*RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setSocketTimeout(5000)
.setRedirectsEnabled(true)
.build();*/
//String loginUrl = "https://passport.jd.com/uc/loginService?uuid=c88ccf63-be69-46e3-b803-e19502401d17&ReturnUrl=https%3A%2F%2Fwww.jd.com%2F%3Fcu%3Dtrue%26utm_source%3Dbaidu-pinzhuan%26utm_medium%3Dcpc%26utm_campaign%3Dt_288551095_baidupinzhuan%26utm_term%3D0f3d30c8dba7459bb52f2eb5eba8ac7d_0_a2d6f99128474550bf46e59a0379a5fa&r=0.8389904492228604&version=2015";
httpPost = new HttpPost(loginUrl);
//設置超時時間
// httpPost.setConfig(requestConfig);
//創建post參數
List<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("uuid",uuid));
list.add(new BasicNameValuePair("eid",eid));
list.add(new BasicNameValuePair("fp",fp));
list.add(new BasicNameValuePair("_t",_t));
list.add(new BasicNameValuePair("loginType",loginType));
list.add(new BasicNameValuePair("loginname",loginname));
list.add(new BasicNameValuePair("nloginpwd",nloginpwd));
list.add(new BasicNameValuePair("authcode",authcode));
list.add(new BasicNameValuePair("pubKey",pubKey));
list.add(new BasicNameValuePair("sa_token",sa_token));
try{
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list,"utf-8");
httpPost.setEntity(urlEncodedFormEntity);
//執行post方法
httpResponse = closeableHttpClient.execute(httpPost);
if(null!=httpResponse && !"".equals(httpResponse)){
if(httpResponse.getStatusLine().getStatusCode() == 200){
postResult= EntityUtils.toString(httpResponse.getEntity(),"utf-8");
//System.out.println("查看登錄接口請求返回的結果:"+postResult);
if (postResult.startsWith("(")){
postResult = postResult.substring(1,postResult.length());
}
if(postResult.endsWith(")")){
postResult = postResult.substring(0,postResult.length()-1);
}
//將String 轉換為json格式
JSONObject jsonObject = new JSONObject(postResult);//該結果可用來提取任何想要的值
// System.out.println(jsonObject.get("username"));
// Assert.assertEquals(jsonObject.get("eid"),"eid"); assert驗證結果
JsonFormatTool jsonFormatTool = new JsonFormatTool();
String Result = jsonFormatTool.formatJson(jsonObject.toString());
System.out.println("請求返回的結果是:"+Result);
}
}else{
System.out.println("null");}
}catch (Exception e) {
e.printStackTrace();
}
/*catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (closeableHttpClient != null) {
closeableHttpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}*/
httpPost.releaseConnection();
}
@Test(dataProvider = "LoginData",dataProviderClass = DataProvideTool.class)
public void dayin(String CaseDescription
,String loginUrl,String uuid,String eid,String fp,String _t,String loginType,String loginname,
String nloginpwd,String authcode,String pubKey,String sa_token)
{
System.out.println(loginname +"------"+ uuid +"------" +eid);
}
@Test(dataProvider= "data1",dataProviderClass = DataProvideTool.class)
public void test2(String name, int age, String hobby) {
System.out.println(name + " is " + age + " years old and likes " + hobby);
}
}
utl包下面的工具類:ExcelReader類,讀取excel數據並對讀取的各個單元格格式進行判斷和轉換
package utl;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import java.io.File;
import java.io.FileInputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
/**
* Created by jiangcui on 2018/5/24.
*/
public class ExcelReader {
/**
* 讀取excel文件,excel中不含合並單元格
* @param path
* @param sheetname
* excel表格要注意每行的最后一格不能為空
* 如果要為空,則需要手動隨便填寫字符,然后再按del鍵刪除才可以
* 目前沒找到這個解決辦法,后續會繼續查找解決辦法
* @return
*/
public static String[][] getExpectationData(String path,String sheetname){
try{
File file = new File(path);
FileInputStream fis = new FileInputStream(file);
// System.out.println("創建工作表對象");
//POIFSFileSystem poifsFileSystem = new POIFSFileSystem(fis);
XSSFWorkbook workBook = new XSSFWorkbook(fis);
//System.out.println("創建工作表對象01");
//得到工作表
XSSFSheet sheet1 = workBook.getSheet(sheetname);
//得到總行數
int rowNum = sheet1.getLastRowNum();
List<String[]> results = new ArrayList<String[]>();
for (int i=1;i<=rowNum;i++){
//當前行
XSSFRow row = sheet1.getRow(i);
int colNum = row.getLastCellNum();
String[] data = new String[colNum];
//當前行所有列
for (int j = 0; j < colNum; j++) {
try {
data[j] = getCellValue(row.getCell(j));
}catch (NullPointerException e){ //如果單元格為空的時候,則用這個來處理
data[j] = "";
}
}
//把data[]數組的數據存在list<[]>中
results.add(data);
// for(String[] str:results){
// for(int n =0;n<str.length;n++){
// System.out.println(str[n]);
// }
// }
}
fis.close();
//將列表轉化為二維數組
String[][] returnArray = new String[results.size()][];
for (int i = 0; i < returnArray.length; i++) {
returnArray[i] = (String[]) results.get(i);
// for(int j = 0;j < returnArray[i].length;j++){
// System.out.println(returnArray[i][j]);
// }
}
return returnArray;
}catch (Exception e){
return null;
}
}
/**
* 對Excel的各個單元格的格式進行判斷並轉換
*/
public static String getCellValue(XSSFCell cell) {
String cellValue = "";
DecimalFormat df = new DecimalFormat("#");
switch (cell.getCellType()) {
case XSSFCell.CELL_TYPE_STRING:
cellValue =cell.getRichStringCellValue().getString().trim();
break;
case XSSFCell.CELL_TYPE_NUMERIC:
cellValue =df.format(cell.getNumericCellValue()).toString();
break;
case XSSFCell.CELL_TYPE_BOOLEAN:
cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
break;
case XSSFCell.CELL_TYPE_FORMULA:
cellValue =cell.getCellFormula();
break;
default:
cellValue = "";
}
return cellValue;
}
}
JsonFormatTool 類 是將json數據轉化為可格式化輸出的數據
package utl;
/**
* Created by jiangcui on 2018/5/25.
*/
public class JsonFormatTool {
/**
* 單位縮進字符串。
*/
private static String SPACE = " ";
/**
* 返回格式化JSON字符串。
*
* @param json 未格式化的JSON字符串。
* @return 格式化的JSON字符串。
*/
public String formatJson(String json)
{
StringBuffer result = new StringBuffer();
int length = json.length();
int number = 0;
char key = 0;
//遍歷輸入字符串。
for (int i = 0; i < length; i++)
{
//1、獲取當前字符。
key = json.charAt(i);
//2、如果當前字符是前方括號、前花括號做如下處理:
if((key == '[') || (key == '{') )
{
//(1)如果前面還有字符,並且字符為“:”,打印:換行和縮進字符字符串。
if((i - 1 > 0) && (json.charAt(i - 1) == ':'))
{
result.append('\n');
result.append(indent(number));
}
//(2)打印:當前字符。
result.append(key);
//(3)前方括號、前花括號,的后面必須換行。打印:換行。
result.append('\n');
//(4)每出現一次前方括號、前花括號;縮進次數增加一次。打印:新行縮進。
number++;
result.append(indent(number));
//(5)進行下一次循環。
continue;
}
//3、如果當前字符是后方括號、后花括號做如下處理:
if((key == ']') || (key == '}') )
{
//(1)后方括號、后花括號,的前面必須換行。打印:換行。
result.append('\n');
//(2)每出現一次后方括號、后花括號;縮進次數減少一次。打印:縮進。
number--;
result.append(indent(number));
//(3)打印:當前字符。
result.append(key);
//(4)如果當前字符后面還有字符,並且字符不為“,”,打印:換行。
if(((i + 1) < length) && (json.charAt(i + 1) != ','))
{
result.append('\n');
}
//(5)繼續下一次循環。
continue;
}
//4、如果當前字符是逗號。逗號后面換行,並縮進,不改變縮進次數。
if((key == ','))
{
result.append(key);
result.append('\n');
result.append(indent(number));
continue;
}
//5、打印:當前字符。
result.append(key);
}
return result.toString();
}
/**
* 返回指定次數的縮進字符串。每一次縮進三個空格,即SPACE。
*
* @param number 縮進次數。
* @return 指定縮進次數的字符串。
*/
private String indent(int number)
{
StringBuffer result = new StringBuffer();
for(int i = 0; i < number; i++)
{
result.append(SPACE);
}
return result.toString();
}
}
TestData包下面存放需要讀取的excel文件,路徑為:"C:\\Users\\jiangcui\\IdeaProjects\\httpclient\\src\\main\\TestData\\LoginTest.xlsx"
以下為此實例需要說明:
1)如果excel文件為.xls文件,則需要使用apache.poi的HSSF(針對excel2003及以前的版本),如果是.xlsx文件,則需要使用apache.poi的XSSF
2)由於testng版本問題,有時候會導致org.testng.internal.reflect.MethodMatcherException異常(這個待確定,初步估計是與testng版本相關)
此實例pom 文檔內容如下:
<?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>httpclient</groupId>
<artifactId>httpclient</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<!-- 指明編譯源代碼時使用的字符編碼,maven編譯的時候默認使用的GBK編碼,
通過project.build.sourceEncoding屬性設置字符編碼,告訴maven這個項目使用UTF-8來編譯 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--這里可以設置需要運行group-->
<groupsTest>execShell</groupsTest>
</properties>
<dependencies>
<!--tesgng依賴包-->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.13</version>
</dependency>
<!--poi創建和讀取office文檔-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<!--Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容-->
<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>httpclient-cache</artifactId>
<version>4.5.2</version>
</dependency>
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId>
<version>4.5.2</version>
</dependency>
<!--java中建立sftp服務連接所需的jar包-->
<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.8.0</version>
<scope>system</scope>
<systemPath>${basedir}/json/commons-beanutils-1.8.0.jar</systemPath>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
<scope>system</scope>
<systemPath>${basedir}/json/commons-collections-3.2.1.jar</systemPath>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
<scope>system</scope>
<systemPath>${basedir}/json/commons-lang-2.5.jar</systemPath>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<scope>system</scope>
<systemPath>${basedir}/json/commons-logging-1.1.1.jar</systemPath>
</dependency>
<dependency>
<groupId>ezmorph</groupId>
<artifactId>ezmorph</artifactId>
<version>1.0.6</version>
<scope>system</scope>
<systemPath>${basedir}/json/ezmorph-1.0.6.jar</systemPath>
</dependency>
<dependency>
<groupId>json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<scope>system</scope>
<systemPath>${basedir}/json/json-lib-2.4-jdk15.jar</systemPath>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<threadCount>1</threadCount>
<forkCount>1</forkCount>
<reuseForks>true</reuseForks>
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
<forkMode>once</forkMode>
<argLine>-Dfile.encoding=UTF-8</argLine>
<groups>${groupsTest}</groups>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
testng.xml 內容如下:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1">
<test name="Test1">
<classes>
<class name="loginjdtest.FirstTest"/> //指定包名及包名下的java文件
</classes>
</test>
</suite>
參考資料:
1)https://www.cnblogs.com/haigege/p/5450742.html
2)https://www.cnblogs.com/meitian/p/5199079.html