分享

Java接口自动化测试框架设计

 huowufenghuang 2019-01-07

       前面一篇,我们介绍了Get方法的设计过程和测试结果,现在我们需要对前面代码进行重构和修改,本篇需要完成以下目标。

1)重构Get方法

2)如何进行JSON解析

3)使用TestNG方法进行测试断言

 

1.重构Get方法

 

      在前面文章,说过,之前写的Get方法比较繁琐,不光写了如何进行Get请求,还写了获取http响应状态码和JSON转换。现在我们需要抽取出来,设计Get请求方法,就只干一件事情,那就是如何发送get请求,其他的不要管。

      我们知道,请求之后会返回一个HTTP的响应对象,所以,我们把get方法的返回值类型改成了响应对象,并带上返回语句,重构代码之后,get方法代码如下。

  1. package com.qa.restclient;
  2. import java.io.IOException;
  3. import org.apache.http.client.ClientProtocolException;
  4. import org.apache.http.client.methods.CloseableHttpResponse;
  5. import org.apache.http.client.methods.HttpGet;
  6. import org.apache.http.impl.client.CloseableHttpClient;
  7. import org.apache.http.impl.client.HttpClients;
  8. public class RestClient {
  9. //1. Get 请求方法
  10. public CloseableHttpResponse get(String url) throwsClientProtocolException, IOException {
  11. //创建一个可关闭的HttpClient对象
  12. CloseableHttpClienthttpclient = HttpClients.createDefault();
  13. //创建一个HttpGet的请求对象
  14. HttpGethttpget = newHttpGet(url);
  15. //执行请求,相当于postman上点击发送按钮,然后赋值给HttpResponse对象接收
  16. CloseableHttpResponsehttpResponse = httpclient.execute(httpget);
  17. return httpResponse;
  18. }
  19. }

       由于我们不想在代码里写死例如像HTTP响应状态码200这样的硬编码,所以,这里我们在TestBase.java里把状态码给用常量写出来,方便每一个TestNG测试用例去调用去断言。

  1. package com.qa.base;
  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.IOException;
  5. import java.util.Properties;
  6. public class TestBase {
  7. public Properties prop;
  8. public int RESPNSE_STATUS_CODE_200 = 200;
  9. public int RESPNSE_STATUS_CODE_201 = 201;
  10. public int RESPNSE_STATUS_CODE_404 = 404;
  11. public int RESPNSE_STATUS_CODE_500 = 500;
  12. //写一个构造函数
  13. public TestBase() {
  14. try{
  15. prop= new Properties();
  16. FileInputStreamfis = new FileInputStream(System.getProperty("user.dir")+
  17. "/src/main/java/com/qa/config/config.properties");
  18. prop.load(fis);
  19. }catch (FileNotFoundException e) {
  20. e.printStackTrace();
  21. }catch (IOException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. }

现在我们的测试类代码修改之后如下。

  1. package com.qa.tests;
  2. import java.io.IOException;
  3. importorg.apache.http.client.ClientProtocolException;
  4. importorg.apache.http.client.methods.CloseableHttpResponse;
  5. import org.testng.Assert;
  6. import org.testng.annotations.BeforeClass;
  7. import org.testng.annotations.Test;
  8. import com.qa.base.TestBase;
  9. import com.qa.restclient.RestClient;
  10. public class GetApiTest extends TestBase{
  11. TestBase testBase;
  12. String host;
  13. String url;
  14. RestClient restClient;
  15. CloseableHttpResponse closeableHttpResponse;
  16. @BeforeClass
  17. public void setUp() {
  18. testBase = new TestBase();
  19. host = prop.getProperty("HOST");
  20. url = host + "/api/users";
  21. }
  22. @Test
  23. public void getAPITest() throws ClientProtocolException, IOException {
  24. restClient = new RestClient();
  25. closeableHttpResponse= restClient.get(url);
  26. //断言状态码是不是200
  27. int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
  28. Assert.assertEquals(statusCode,RESPNSE_STATUS_CODE_200, "response status code is not 200");
  29. }
  30. }
测试运行通过,没毛病。

2.写一个JSON解析的工具类

      在上面部分,我们只是写了执行Get请求和状态码是否200的断言。接下来,我们需要写有一个JSON解析工具类,这样就方便我们去json内容的断言。

下面这个JSON数据截图


      上面是一个标准的json的响应内容截图,第一个红圈”per_page”是一个json对象,我们可以根据”per_page”来找到对应值是3,而第二个红圈“data”是一个JSON数组,而不是对象,不能直接去拿到里面值,需要遍历数组。

      下面,我们写一个JSON解析的工具方法类,如果是像第一个红圈的JSON对象,我们直接返回对应的值,如果是需要解析类似data数组里面的json对象的值,这里我们构造方法默认解析数组第一个元素的内容。

在src/main/java下新建一个包:com.qa.util,然后在新包下创建一个TestUtil.java类。

  1. package com.qa.util;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. public class TestUtil {
  5. /**
  6. *
  7. * @param responseJson ,这个变量是拿到响应字符串通过json转换成json对象
  8. * @param jpath,这个jpath指的是用户想要查询json对象的值的路径写法
  9. * jpath写法举例:1) per_page 2)data[1]/first_name ,data是一个json数组,[1]表示索引
  10. * /first_name 表示data数组下某一个元素下的json对象的名称为first_name
  11. * @return,返回first_name这个json对象名称对应的值
  12. */
  13. //1 json解析方法
  14. public static String getValueByJPath(JSONObject responseJson, String jpath){
  15. Objectobj = responseJson;
  16. for(String s : jpath.split("/")) {
  17. if(!s.isEmpty()) {
  18. if(!(s.contains("[") || s.contains("]"))) {
  19. obj = ((JSONObject) obj).get(s);
  20. }else if(s.contains("[") || s.contains("]")) {
  21. obj =((JSONArray)((JSONObject)obj).get(s.split("\\[")[0])).get(Integer.parseInt(s.split("\\[")[1].replaceAll("]", "")));
  22. }
  23. }
  24. }
  25. return obj.toString();
  26. }
  27. }

       简单解释下上面的代码,主要是查询两种json对象的的值,第一种最简单的,这个json对象在整个json串的第一层,例如上面截图中的per_page,这个per_page就是通过jpath这个参数传入,返回的结果就是3. 第二种jpath的查询,例如我想查询data下第一个用户信息里面的first_name的值,这个时候jpath的写法就是data[0]/first_name,查询结果应该是Eve。


3.TestNG测试用例

下面,我们TestNG测试用例代码如下

 

  1. package com.qa.tests;
  2. import java.io.IOException;
  3. import org.apache.http.client.ClientProtocolException;
  4. import org.apache.http.client.methods.CloseableHttpResponse;
  5. import org.apache.http.util.EntityUtils;
  6. import org.testng.Assert;
  7. import org.testng.annotations.BeforeClass;
  8. import org.testng.annotations.Test;
  9. import com.alibaba.fastjson.JSON;
  10. import com.alibaba.fastjson.JSONObject;
  11. import com.qa.base.TestBase;
  12. import com.qa.restclient.RestClient;
  13. import com.qa.util.TestUtil;
  14. public class GetApiTest extends TestBase{
  15. TestBase testBase;
  16. String host;
  17. String url;
  18. RestClient restClient;
  19. CloseableHttpResponse closeableHttpResponse;
  20. @BeforeClass
  21. public void setUp() {
  22. testBase = new TestBase();
  23. host = prop.getProperty("HOST");
  24. url = host + "/api/users?page=2";
  25. }
  26. @Test
  27. public void getAPITest() throws ClientProtocolException, IOException {
  28. restClient = new RestClient();
  29. closeableHttpResponse = restClient.get(url);
  30. //断言状态码是不是200
  31. int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
  32. Assert.assertEquals(statusCode, RESPNSE_STATUS_CODE_200, "response status code is not 200");
  33. //把响应内容存储在字符串对象
  34. String responseString = EntityUtils.toString(closeableHttpResponse.getEntity(),"UTF-8");
  35. //创建Json对象,把上面字符串序列化成Json对象
  36. JSONObject responseJson = JSON.parseObject(responseString);
  37. //System.out.println("respon json from API-->" + responseJson);
  38. //json内容解析
  39. String s = TestUtil.getValueByJPath(responseJson,"data[0]/first_name");
  40. System.out.println(s);
  41. }
  42. }

运行测试结果:

[RemoteTestNG] detected TestNGversion 6.14.3

Eve

PASSED: getAPITest

你还可以多写几个jpath来测试这个json解析工具类。

  1. String s = TestUtil.getValueByJPath(responseJson,"data[1]/id");
  2. String s = TestUtil.getValueByJPath(responseJson,"per_page");

4.TestNG自带的测试断言方法

        这里简单提一下TestNG的断言方法,我们一般测试都需要写断言的代码,否则这样的单元测试代码就没有意义。下面,我在statusCode和json解析的first_name进行断言。

  1. package com.qa.tests;
  2. import java.io.IOException;
  3. import org.apache.http.client.ClientProtocolException;
  4. import org.apache.http.client.methods.CloseableHttpResponse;
  5. import org.apache.http.util.EntityUtils;
  6. import org.testng.Assert;
  7. import org.testng.annotations.BeforeClass;
  8. import org.testng.annotations.Test;
  9. import com.alibaba.fastjson.JSON;
  10. import com.alibaba.fastjson.JSONObject;
  11. import com.qa.base.TestBase;
  12. import com.qa.restclient.RestClient;
  13. import com.qa.util.TestUtil;
  14. public class GetApiTest extends TestBase{
  15. TestBase testBase;
  16. String host;
  17. String url;
  18. RestClient restClient;
  19. CloseableHttpResponse closeableHttpResponse;
  20. @BeforeClass
  21. public void setUp() {
  22. testBase = new TestBase();
  23. host = prop.getProperty("HOST");
  24. url = host + "/api/users?page=2";
  25. }
  26. @Test
  27. public void getAPITest() throws ClientProtocolException, IOException {
  28. restClient = new RestClient();
  29. closeableHttpResponse = restClient.get(url);
  30. //断言状态码是不是200
  31. int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
  32. Assert.assertEquals(statusCode, RESPNSE_STATUS_CODE_200, "response status code is not 200");
  33. //把响应内容存储在字符串对象
  34. String responseString = EntityUtils.toString(closeableHttpResponse.getEntity(),"UTF-8");
  35. //创建Json对象,把上面字符串序列化成Json对象
  36. JSONObject responseJson = JSON.parseObject(responseString);
  37. //System.out.println("respon json from API-->" + responseJson);
  38. //json内容解析
  39. String s = TestUtil.getValueByJPath(responseJson,"data[0]/first_name");
  40. System.out.println(s);
  41. Assert.assertEquals(s, "Eve","first name is not Eve");
  42. }
  43. }

经常使用的测试断言:

Assert.assertEquals(“现实结果”, "期待结果","断言失败时候打印日志消息");

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多