春节回老家休息了半个月, 所以文章也没更新, 后面会继续完成这个系列
痛点
我们先来说一个大家做接口测试或 UI 自动化测试的痛点, 很多时候要进入应用或接口都需要登录验证, 这是我们展开测试的一个很头疼的问题, 在前面的文章中好像也留下了这个坑, 也有童鞋留言在问这方面的问题, 另外刚好年前在写爬虫的时候也遇到这样的问题, 所以今天我们就来分析下这个主题, 把这个坑给填满
分析
对于如何跳过登录, 我就开门见山直接说吧, 我了解到的跳过登录的方式无外乎有下面几种:
1 模拟用户输入登录;
2 利用 Cookie 跳过登录;
3 利用非正常手段绕过登录;
4 白名单;
5 其它(未知或待发掘)
对于第 1 种方式, 做过 UI 自动化测试的童鞋都不会陌生, 简单粗暴没毛病, 可是不太适合接口测试, 目前基本上都是通过第 2 种利用 Cookie 的方式跳过, 在某些情况下 Cookie 的方式也行不通时, 可以考虑第 3 种, 第 4 种白名单业界都是靠商业合作来实现, 没有什么好说的了所以今天的重点是第 2 种方式, 稍微讲一下第 3 种方式
实现
1 利用 Cookie 跳过登录
利用 Cookie 跳过登录原理就是登录一次, 查看登录后的 header 和 cookie 信息, 将可关键信息拿下来, 然后将这些信息加入你的接口请求头信息中, 听起来是不是还是挺抽象? 没关系, 马上举例说明以简书获取当前用户信息接口为例:
在没登录的时候, 去请求这个接口肯定是拿不到数据的, 下面我们做个试验:
1> 在已登录的情况下: 我们看下获取当前用户信息接口: http://www.jianshu.com/author/current_user, 在 Chrome 的控制台中是可以看到数据的, 如下:
2> 在未登录的情况下, 换个浏览器请求: http://www.jianshu.com/author/current_user, 页面跳转到登录界面了
现在需求出来了, 我想要跳过这个登录去拿到用户信息, 所以这肯定需要在接口请求中加入 Cookie 了, 如何做?
首先, 我们回到前面登录状态下, 使用 Chrome 的调试工具或 Firefox 的 FireDebug(按下 F12 可以打开)或者其他抓包工具如 FiddlerCharles 等 (浏览器调试工具有时可能重定向导致界面被强制刷新了而抓不到之前的请求记录, 所以建议用抓包工具) 抓取当前界面的请求信息; 然后找到对应的接口记录, 选中查看它的相关请求和响应信息, 如下图:
上图红框部分就是这个接口的请求 headers 信息, 其中就包含 Cookie, 现在问题来了, headers 和 cookie 这么多, 都要放进去吗? 先都放进去看下效果, 然后再逐步排除掉无用的 headers(熟练了之后其实可以一眼看出来哪些 headers 信息是需要的, 下面代码中我直接给出了需要的 headers 信息)HTTP 请求的测试代码如下:
- @Test
- public void testSkipLoginByCookies() throws ParseException, IOException {
- String url = "http://www.jianshu.com/author/current_user";
- Map<String, Object> headers = new HashMap<String, Object>();
- headers.put("Accept", "application/json");
- headers.put("Cookie", "remember_user_token=W1syOTUxMjMzXSwiJDJhJDEwJDFBM29ab1h5RDJMQ2xaN2kzUzFpRXUiLCIx" +
- "NTE5Mzc3NjI3LjEzNTU3ODIiXQ==--1ad08bd92af5892df4e996e50e75ddee1bad35ef;");
- //headers.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) ApplewebKit/537.36 (Khtml, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
- HttpResponse response = new HttpRequest(url)
- .setHeaders(headers)
- .setParams(null)
- .doGet();
- // 输出响应
- System.out.println(EntityUtils.toString(response.getEntity()));
- // 验证响应码
- int code = response.getStatusLine().getStatusCode();
- Assert.assertEquals(200, code);
- }
测试结果:
就在这样跳过了登录, 所以不管你登录界面有多复杂, 有没有各种验证码和极限验证, we don't care
2 利用非正常手段绕过登录
上面利用 Cookie 跳过登录有时也有不管用的时候, 比如上面简书接口使用的 cookie 是一个 token, 这个会有一个有效期, 比如几个小时几天内有效(具体过期时间由系统设置的), 那么我们不可能每次失效了都来重新人工 copy 一遍 cookie 更新到代码中吧, 这不符合自动化测试的原则, 所以有时候我们得用一些非正常手段来动态获得 cookie, 常用的手段和方法有:
1 利用 WebDriver 的 HtmlUnitDriver 来模拟无界面登录, 从而获得 cookie;
为什么用 HtmlUnitDriver 而不是用 FirefoxDriver 或 ChromeDriver? 因为 HtmlUnitDriver 无操作界面, 是在后台静默进行的, 无干扰且速度快
2 在代码中模拟用户登录的 Form 表单提交;
用抓包工具仔细分析用户登录过程, 你会发现前端就是一个 Form 提交, 只不过这不是一个请求完成的, 而是中间跳转了好多次, 需要好几个请求去完成, 那么我们也就可以将这些请求都抓出来, 依次请求而从实现登录
具体的实现就不贴了, 有兴趣的童鞋可以去尝试下~
来源: http://www.jianshu.com/p/86f66f997c3d