接着前面的顺序,本篇来介绍解析JSON中的接口请求url和参数json内容,以及期待结果中响应状态码。这篇学习完了,就可以考虑如何设计测试用例运行模式或者入口。
1.得到接口url
这个接口url是不包含接口服务器地址,接口服务器地址,前面我们看到,已经提取到配置文件中了。完整的接口请求地址是配置文件中服务器地址和这里获取的url。继续在com.testlink.tests包先新建一个GetApiUrl.java文件
package com.testlink.tests; import org.testng.annotations.Test; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qa.util.TestUtil; import com.qa.util.TestlinkUtil; import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI; import br.eti.kinoshita.testlinkjavaapi.model.TestCase; public class GetApiUrl { TestLinkAPI api = TestlinkUtil.connect(); @Test public void getApiUrl() { String ExternalID = "at-1"; TestCase tc = api.getTestCaseByExternalId(ExternalID, null); String action = TestlinkUtil.getTestCaseAction(api, tc); //把字符串转换成json对象 JSONObject actionJson = JSON.parseObject(action); //下面开始解析得到名称为method的json对象的值 String url = TestUtil.getValueByJPath(actionJson, "url"); System.out.println(url); } }
运行结果:
[RemoteTestNG] detected TestNG version 6.14.3 2018-06-03 14:11:28 587 INFO TestBase:28 - 正在读取配置文件... Hello! /api/users?page=2 PASSED: getApiUrl
下面写一个方法,抽取到TestlinkUtil.java类中。
public static String getApiUrl(String stepAction) { //先把string转换成json对象 JSONObject actionJson = JSON.parseObject(stepAction); String ApiUrl = TestUtil.getValueByJPath(actionJson, "url"); return ApiUrl; }暂时不写测试用例,下面获取post方法的json的时候一块来测试这个功能。
2.得到json参数内容
同样的步骤,找一个post的用例来获取json参数内容。先来看测试类。
package com.testlink.tests; import org.testng.annotations.Test; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qa.util.TestUtil; import com.qa.util.TestlinkUtil; import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI; import br.eti.kinoshita.testlinkjavaapi.model.TestCase; public class GetJsonParam { TestLinkAPI api = TestlinkUtil.connect(); @Test public void getJsonParam() { // at-2 在我这边是一个post类型测试用例 String ExternalID = "at-2"; TestCase tc = api.getTestCaseByExternalId(ExternalID, null); String action = TestlinkUtil.getTestCaseAction(api, tc); //把字符串转换成json对象 JSONObject actionJson = JSON.parseObject(action); //下面开始解析得到名称为method的json对象的值 String jsonString = TestUtil.getValueByJPath(actionJson, "param"); System.out.println(jsonString); } }
运行结果:
[RemoteTestNG] detected TestNG version 6.14.3 2018-06-03 14:24:56 012 INFO TestBase:28 - 正在读取配置文件... Hello! [{"name":"morpheus","job":"leader"}] PASSED: getJsonParam
和我们测试用例的param的值是一致的。把代码抽取成方法,丢在TestlinkUtil.java中。
public static String getJsonParam(String stepAction) { //先把string转换成json对象 JSONObject actionJson = JSON.parseObject(stepAction); String jsonParam = TestUtil.getValueByJPath(actionJson, "param"); return jsonParam; }
下面来写一个测试用例,来获取post用例的url和parma信息,把上面的测试代码给修改下。
package com.testlink.tests; import org.testng.annotations.Test; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qa.util.TestUtil; import com.qa.util.TestlinkUtil; import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI; import br.eti.kinoshita.testlinkjavaapi.model.TestCase; public class GetJsonParam { TestLinkAPI api = TestlinkUtil.connect(); @Test public void getJsonParam() { // at-2 在我这边是一个post类型测试用例 String ExternalID = "at-2"; TestCase tc = api.getTestCaseByExternalId(ExternalID, null); String action = TestlinkUtil.getTestCaseAction(api, tc); //得到url String url = TestlinkUtil.getApiUrl(action); System.out.println(url); //得到param参数,格式是json String jsonParam = TestlinkUtil.getJsonParam(action); System.out.println(jsonParam); } }
测试结果:
[RemoteTestNG] detected TestNG version 6.14.3 2018-06-03 14:31:45 795 INFO TestBase:28 - 正在读取配置文件... Hello! /api/users [{"name":"morpheus","job":"leader"}] PASSED: getJsonParam
3.得到期待结果中状态码
前面一篇,我们获取了测试action对应的result,有了这个那就很好获取期待结果中的响应状态码。先来看看测试代码
package com.testlink.tests; import org.testng.annotations.Test; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qa.util.TestUtil; import com.qa.util.TestlinkUtil; import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI; import br.eti.kinoshita.testlinkjavaapi.model.TestCase; public class GetStatusCode { TestLinkAPI api = TestlinkUtil.connect(); @Test public void getStatusCode() { String ExternalID = "at-2"; TestCase tc = api.getTestCaseByExternalId(ExternalID, null); String result = TestlinkUtil.getResult(api, tc); //先把result转换成json格式 JSONObject resultJson = JSON.parseObject(result); //获取状态码 String statusCode = TestUtil.getValueByJPath(resultJson,"code"); System.out.println(statusCode); } }
运行结果:
[RemoteTestNG] detected TestNG version 6.14.3 2018-06-03 14:47:29 653 INFO TestBase:28 - 正在读取配置文件... Hello! 201 PASSED: getStatusCode
先看看testlink中的状态码是不是201
下面把代码提取到TestlinkUtil.java中,直接看最后一个方法。
package com.qa.util; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import org.apache.commons.lang3.StringEscapeUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qa.base.TestBase; import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI; import br.eti.kinoshita.testlinkjavaapi.model.TestCase; import br.eti.kinoshita.testlinkjavaapi.model.TestCaseStep; import br.eti.kinoshita.testlinkjavaapi.model.TestPlan; import br.eti.kinoshita.testlinkjavaapi.model.TestProject; import br.eti.kinoshita.testlinkjavaapi.model.TestSuite; public class TestlinkUtil { /** * 连接testlink方法 */ public static TestLinkAPI connect() { TestBase base = new TestBase(); String url = base.prop.getProperty("TestLinkUrl"); String devKey = base.prop.getProperty("DEVKEY"); TestLinkAPI api = null; URL testlinkURL = null; try { testlinkURL = new URL(url); } catch ( MalformedURLException mue ) { mue.printStackTrace( System.err ); System.exit(-1); } try { api = new TestLinkAPI(testlinkURL, devKey); } catch( Exception te) { te.printStackTrace( System.err ); System.exit(-1); } System.out.println(api.ping()); return api; } /** * 根据项目名称字符串得到项目id,方便下一个方法(得到项目测试计划)调用 * @param api,连接对象,几乎这个类大部分方法都需要这个对象 * @param projectName * @return, 返回项目ID号 */ public static int getProjectIdByName(TestLinkAPI api, String projectName) { //根据项目名称得到这个项目 TestProject project = api.getTestProjectByName(projectName); int projectId = project.getId(); return projectId; } /** * 根据项目id得到项目下所有的测试计划 * @param api * @param ProjectId * @return,测试计划数组对象 */ public static TestPlan[] getAllPlanUnderProject(TestLinkAPI api, int ProjectId) { TestPlan[] plans = api.getProjectTestPlans(ProjectId); return plans; } /** * 根据项目名称获取项目下顶层的测试套件数组对象 * @param api * @param projectName * @return */ public static TestSuite[] getFirstLeverTestSuite(TestLinkAPI api, String projectName) { int projectId = TestlinkUtil.getProjectIdByName(api, projectName); TestSuite[] suites = api.getFirstLevelTestSuitesForTestProject(projectId); return suites; } /** * 得到测试用例集合 * @param api * @param projectName * @return */ public static TestCase[] getTestCasesForSuite(TestLinkAPI api, String projectName) { TestSuite[] suites = TestlinkUtil.getFirstLeverTestSuite(api, projectName); TestCase[] cases = null; //遍历数组,拿到每个测试套件下测试用例 for (TestSuite testSuite : suites) { //获取测试用例数组,注意参数写法 cases = api.getTestCasesForTestSuite(testSuite.getId(), true, null); } return cases; } /** * 根据测试用例对象,得到测试步骤中的action * @param api * @param tCase * @return */ public static String getTestCaseAction(TestLinkAPI api,TestCase tCase) { TestCase tc = api.getTestCaseByExternalId(tCase.getFullExternalId(), null); List<TestCaseStep> tcs = tc.getSteps(); String action = null; //遍历steps集合 for (TestCaseStep testCaseStep : tcs) { //开始数据清洗 String originalStr = testCaseStep.getActions(); //先切除<p>和</p>标记 String s1 = originalStr.split("<p>")[1].split("</p>")[0]; //System.out.println(s1); //debug用打印 //然后把<br />全部替换为空 String s2 = s1.replaceAll("<br />", ""); //System.out.println(s2); //debug用打印 //把&quto改成正常显示双引号 action = StringEscapeUtils.unescapeHtml4(s2); } return action; } /** * 根据测试用例对象去获取测试期待结果 * @param api * @param tCase * @return,一个字符串对象 */ public static String getResult(TestLinkAPI api,TestCase tCase) { TestCase tc = api.getTestCaseByExternalId(tCase.getFullExternalId(), null); List<TestCaseStep> tcs = tc.getSteps(); String result = null; //遍历steps集合 for (TestCaseStep testCaseStep : tcs) { String expectResult = testCaseStep.getExpectedResults(); //System.out.println(expectResult); //数据清洗 //去除最外层的<p> </p> String s1 = expectResult.split("<p>")[1].split("</p>")[0]; //把全部br换行符替换成空字符 String s2 = s1.replaceAll("<br />", ""); //为了双引号在控制台正常显示 result = StringEscapeUtils.unescapeHtml4(s2); } return result; } /** * 根据getResult方法得到的字符串去解析请求类型 * @param stepAction * @return,get,post,put等方法字符串 */ public static String getRequestType(String stepAction) { //先把string转换成json对象 JSONObject actionJson = JSON.parseObject(stepAction); //注意这里method是硬编码,和你testlink步骤中要求一致 String requestType = TestUtil.getValueByJPath(actionJson, "method"); return requestType; } /** * 根据actions字符串获取url * @param stepAction * @return */ public static String getApiUrl(String stepAction) { //先把string转换成json对象 JSONObject actionJson = JSON.parseObject(stepAction); String ApiUrl = TestUtil.getValueByJPath(actionJson, "url"); return ApiUrl; } /** * 根据actions字符串获取param,一般是post类型接口 * @param stepAction * @return */ public static String getJsonParam(String stepAction) { //先把string转换成json对象 JSONObject actionJson = JSON.parseObject(stepAction); String jsonParam = TestUtil.getValueByJPath(actionJson, "param"); return jsonParam; } public static String getStatusCode(String result) { //先把string转换成json对象 JSONObject resultJson = JSON.parseObject(result); String statusCode = TestUtil.getValueByJPath(resultJson, "code"); return statusCode; } }
继续在GetStatusCode.java新写一个@Test方法来测试下。
package com.testlink.tests; import org.testng.annotations.Test; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.qa.util.TestUtil; import com.qa.util.TestlinkUtil; import br.eti.kinoshita.testlinkjavaapi.TestLinkAPI; import br.eti.kinoshita.testlinkjavaapi.model.TestCase; public class GetStatusCode { TestLinkAPI api = TestlinkUtil.connect(); @Test public void getStatusCode() { String ExternalID = "at-2"; TestCase tc = api.getTestCaseByExternalId(ExternalID, null); String result = TestlinkUtil.getResult(api, tc); //先把result转换成json格式 JSONObject resultJson = JSON.parseObject(result); //获取状态码 String statusCode = TestUtil.getValueByJPath(resultJson,"code"); System.out.println(statusCode); } @Test public void getStatusCode2() { String ExternalID = "at-2"; TestCase tc = api.getTestCaseByExternalId(ExternalID, null); String result = TestlinkUtil.getResult(api, tc); String statusCode = TestlinkUtil.getStatusCode(result); System.out.println(statusCode); } }
运行结果:
[RemoteTestNG] detected TestNG version 6.14.3 2018-06-03 14:54:15 363 INFO TestBase:28 - 正在读取配置文件... Hello! 201 201 PASSED: getStatusCode PASSED: getStatusCode2
总结:
到目前,我们掌握了和接口测试相关的所有的方法的测试和封装过程。一个接口测试,首先需要知道是什么请求类型,也就是说是get还是post,如果是post,我们就需要拿到接口url,然后拿到json传参,最后调用post方法去执行请求,然后拿到结果和testlink中的响应状态码去对比。这个过程,我们前面都实现了,下一篇,介绍写一个执行全部用来的方式,其实就是一个main方法。
ps:添加目前为止最新项目源码,点击这里。