Url接口测试:HttpClient模拟登录效果
来源:互联网 发布:mkv播放器 for mac 编辑:程序博客网 时间:2024/05/17 22:29
最近做的一个需求,用JUnit做业务测试,需要模拟用户登录,尝试了几种方法,总结一下。
HttpUrlConnection(不可行)
SpringFramework.test(部分可行)
HttpClient(可行)
(一)HttpUrlConnection
一开始很自然想到用HttpUrlConnection模拟登录。
public class RequestTest{ private String SessionId; @Test public void test1() throws Exception{ login(user, psw); // login. String result = post(url, [{...},{...}]) // do test. } public void longin(String user, String psw) throws Exception{ String strUrl = "..."; Url url = new Url(strUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); ... // set other params; conn.setDoInput(true); conn.setDoOutput(true); conn.connect(); String cookie = conn.getHeaderField("Set-Cookie"); SessionId = ((cookie.split(";"))[0].split("="))[1]; System.out.println("SessionId = " + SessionId); } public String post(String strUrl, String jsonParams) throws Exception{ String result = ""; BufferedReader in = null; PrintWriter out = null; try{ URL url = new Url(strUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); ... // set other params; conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestProperty("Cookie", "SessionId=" + SessionId); // set cookie. conn.connect(); out = new PrintWriter(conn.getOutputStream()); out.print(jsonParams); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = null; while((line = in.readLine()) != null){ result = result + line; } }catch(Exception e){ throw e; }finally{ ... // close stream. retrun result; } } }
这里的关键在于登录时通过“Set-Cookie”响应头获取SessionId,然后在后续测试时发送该SessionId到服务器以验证登录权限。但是,实际操作之后发现没有效果,原因在于登录通过之后,由于实际上是没有浏览器在连接的,所以服务器的安全系统认为“浏览器已经关闭”了,所以立即将Session销毁,SessionId失效。于是尝试第二种方法:SpringFramework的测试包。
(二)SpringFramework.test
这实际上是一个偷懒的做法,绕开url请求,通过注解技术直接调用Controller里面相应url所映射的方法。
@ContextConfiguration(locations = {"classpath:mvc-dispatcher-servlet.xml"}) @RunWith(SpringJUnit4ClassRunner.class) public class RequestTest{ @Autowired public TestController controller; @Test public void test1(){ controller.test()... // do test. } }
这种方法逻辑比较简单,代码也少,需要注意的是相关的controller、dao等对象需要通过@Autowired注解创建,不能new。
这种方法在大部分情况下是可行的,包括部分需要登录权限的地方也可以通过验证。但是,当测试到一个方法需要从Session中获取当前登录user的时候,由于没有实际登录,所以获取的user为null,产生了NullPointerException。于是乎,再尝试第三种方法:Apache的HttpClient。
(三)HttpClient
Apache的HttpClient包,测试url接口的神器,经测试可以完美模拟浏览器登录效果。
public class RequestTest{ private static CloseableHttpClient client; @Autowired public TestController controller; @BeforeClass public static void beforeClass(){ login(user, psw, loginUrl); } @AfterClass public static void beforeClass(){ logout(logoutUrl); } @Test public void test1(){ post(url1); get(url2); ... // do test. } private static boolean login(String user, String psw, String loginUrl){ client = HttpClientBuilder.create().build(); HttpPost post = new HttpPost(loginUrl); HttpEntity loginEntity; try{ loginEntity = new UrlEncodedFormEntity(Arrays.asList(new NameValuePair[]{ new BasicNameValuePair("user", user), new BasicNameValuePair("psw", psw), })); post.setEntity(loginEntity); CloseableHttpResponse response = client.execute(post); StatusLine status = response.getStatusLine(); if(status.getStatusCode() == 200){ return true; } }catch(Exception e){ return false; } return false; } private static void logout(String logoutUrl){ HttpGet get = new HttpGet(logoutUrl); try{ CloseableHttpResponse response = client.execute(get); }catch{ } } private String post(String url, Map<String, Object> params) throw ClientProtocolException, IOException{ HttpPost post = new HttpPost(url); post.setHeadr("Content-type", "application/json"); // send json message to server. post.setHeadr("Accept", "application/json"); // receive json message from server. ... // set headers and params. String strParams = new ObjectMapper().writeValueAsString(params); post.setEntity(new StringEntity(strParams)); CloseableHttpResponse response = client.execute(post); if(200 == response.getStatusLine().getStatusCode()){ InputStream in = response.getEntity().getContent(); String result = toString(in) // use other API to get String from the input stream. return result; } return null; } private String get(String url) throw ClientProtocolException, IOException{ HttpGet get = new HttpGet(url); ... // set headers and params. CloseableHttpResponse response = client.execute(get); if(200 == response.getStatusLine().getStatusCode()){ InputStream in = response.getEntity().getContent(); String result = toString(in) // use other API to get String from the input stream. return result; } return null; } }
模拟过程:创建一个CloseableHttpClient类型的成员变量client,用client给服务器发送登录请求,登录通过后就模拟了一个“保持连接状态的浏览器”,然后就可以通过client给服务器发送各种请求,效果和通过浏览器发送请求相同。
还有一点需要注意:由于“浏览器”是一直“连着”的,意味着用户一直处于登录状态(直至Session失效),在服务器安全系统拒绝重复登录的情况下,同一用户不能再次登录。有时候我们可能需要短时间内重复跑多次测试,在这种情况下,最好完成测试后主动退出。
- Url接口测试:HttpClient模拟登录效果
- 【自动化测试】HttpClient 模拟用户登录与请求接口完成自动化测试
- Apache HttpClient模拟登录
- java httpclient 模拟登录
- httpClient模拟新浪登录
- httpclient模拟登录
- Apache HttpClient模拟登录
- Apache HttpClient模拟登录
- httpclient模拟登录
- 使用httpclient模拟登录
- 使用httpclient模拟登录
- testNG+httpclient接口测试
- 接口测试 - httpClient
- 接口测试之HttpClient
- HttpClient天气接口测试
- HttpClient之接口测试
- HttpClient测试接口Test
- httpclient 模拟登录发贴
- jquery-animateNumber数字动画插件
- C语言实现简单的冒泡排序
- hdu2516—取石子游戏(斐波拉契博弈)
- Java基础知识
- java-day01-reflect-Constructor
- Url接口测试:HttpClient模拟登录效果
- Java Socket实现简单的即时通信
- C ~ 指针的运算
- Android BroadcastReceiver实现自定义静态广播和动态广播(黏性广播)
- KMP算法(各种模板)
- leetcode之Find All Duplicates in an Array 问题
- psr 命名空间的规范
- 【Python】【并行计算】Python 多核并行计算
- POJ3734 矩阵快速幂