在手机应用开发过程中,有以下单元测试的需求:
- 服务器用PHP代码写,自身没有好的单元测试框架;
- 服务器有:本地服务器,测试服务器,UAT服务器,正式服务器等不同环境;
- 测试脚本,利用qunit,写在js代码中;login脚本会设置cookie,某些api调用的时候,需要将cookie带回;
如何搭建各种不同的测试环境:
本地服务器、测试服务器、UAT服务器、正式服务器,都配置了vhost,将域名对应到各自本地的php目录。
正式的域名www.xxxxxx.com,指向正式服务器的IP,其他的开发服务器,通过指定代理IP来测试。
js代码访问服务器的时候,利用ajax访问,其自身没有指定代理的功能,为了简化测试客户端的配置,制作proxy.php,
在其上利用curl库,设置代理来访问不同的环境;
在测试的过程中,有几个地方可以诊断信息:
- network显示的http请求数据;
- console显示的调试信息;
- qunit界面打印出来的字符串;
执行效果如下:
主要代码文件如下:
proxy.php
1 <?php 2 /* 3 parameters: 4 url ==> call url; ex:http://a.xxxxxx.com/login.php 5 data ==> post data; ex:{"u":"abcd", "p":"password"} 6 cookie ==> cookie, can empty; ex:PHPSESSID=oh965kppina5fjdi6gv1c2mls5 7 proxy ==> proxy info, can empty; ex:test.xxxxxx.com:8001 8 */ 9 10 // phpinfo(); 11 // die(); 12 13 /*模拟浏览器*/ 14 $user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)"; 15 16 $t = isset($_REQUEST['_t'])?$_REQUEST['_t']:null; 17 $url = isset($_REQUEST['_url'])?$_REQUEST['_url']:""; 18 // $data = isset($_REQUEST['data'])?$_REQUEST['data']:""; 19 $proxy = isset($_REQUEST['_proxy'])?$_REQUEST['_proxy']:""; 20 $cookie = isset($_REQUEST['_cookie'])?$_REQUEST['_cookie']:""; 21 22 $data = array(); 23 // 将非特殊参数全部视为post数据 24 foreach ($_REQUEST as $key => $value) { 25 if(!in_array($key, array('_url', '_t', '_proxy', '_cookie'))) 26 $data[$key] = $value; 27 } 28 29 // 测试数据 30 if($t) { 31 $url = "http://a.ajmide.com/login.php"; 32 $data = array("u"=>"aabbcc", "p"=>"123456"); 33 $proxy = "test.xxxxxx.com:8001"; 34 $cookie = ""; 35 } else { 36 // $data = json_decode($data); 37 } 38 // 修改agent 39 $user_agent = "ajmd/test (".$proxy.")"; 40 $content = vcurl($url, $data, $cookie, $proxy); 41 // print_r($content); 42 echo($content); 43 // // $content = $content . "test"; 44 45 // $content = json_decode($content); 46 // print_r($content); 47 // echo("test"); 48 // print_r(json_encode($content, JSON_UNESCAPED_UNICODE)); 49 50 function vcurl($url, $data, $cookie, $proxy) { // 模拟登录获取Cookie函数 51 $curl = curl_init (); // 启动一个CURL会话 52 if ($proxy && $proxy!="") { 53 //以下代码设置代理服务器 54 curl_setopt ( $curl, CURLOPT_PROXY, $proxy); 55 } 56 curl_setopt ( $curl, CURLOPT_URL, $url ); // 要访问的地址 57 if($cookie && $cookie!="") { 58 curl_setopt($curl, CURLOPT_COOKIE, $cookie); 59 } 60 // curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, 0 ); // 对认证证书来源的检查 61 // curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, 1 ); // 从证书中检查SSL加密算法是否存在 62 curl_setopt ( $curl, CURLOPT_USERAGENT, $GLOBALS ['user_agent'] ); // 模拟用户使用的浏览器 63 // @curl_setopt ( $curl, CURLOPT_FOLLOWLOCATION, 1 ); // 使用自动跳转 64 // curl_setopt ( $curl, CURLOPT_AUTOREFERER, 1 ); // 自动设置Referer 65 curl_setopt ( $curl, CURLOPT_POST, 1 ); // 发送一个常规的Post请求 66 curl_setopt ( $curl, CURLOPT_POSTFIELDS, $data ); // Post提交的数据包 67 // curl_setopt ( $curl, CURLOPT_COOKIEJAR, $GLOBALS ['cookie_file'] ); // 存放Cookie信息的文件名称 68 // curl_setopt ( $curl, CURLOPT_COOKIEFILE, $GLOBALS ['cookie_file'] ); // 读取上面所储存的Cookie信息 69 curl_setopt ( $curl, CURLOPT_TIMEOUT, 30 ); // 设置超时限制防止死循环 70 curl_setopt ( $curl, CURLOPT_HEADER, 1); // 显示返回的Header区域内容 71 curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 ); // 获取的信息以文件流的形式返回 72 $tmpInfo = curl_exec ( $curl ); // 执行操作 73 if (curl_errno ( $curl )) { 74 echo 'call curl error. ' . curl_error ( $curl ); 75 } 76 $info = curl_getinfo($curl); 77 $httpHeaderSize = $info['header_size']; 78 $pHeader = substr($tmpInfo, 0, $httpHeaderSize); 79 $pContent = substr($tmpInfo, $httpHeaderSize); 80 // echo "<pre>"; 81 // // print_r(curl_getinfo($curl)); 82 // print_r($pHeader); 83 // echo "</pre>"; 84 curl_close ( $curl ); // 关闭CURL会话 85 // 如果有cookie,则将cookie放入到返回数据的sess字段中 86 if(preg_match("/Set-Cookie: (.*);/iU", $pHeader, $arr)) { 87 $json = json_decode($pContent); 88 if($json!=NULL) { 89 $json->cookie = $arr[1]; 90 $pContent = json_encode($json, JSON_UNESCAPED_UNICODE); 91 } 92 } 93 94 // return $tmpInfo; // 返回数据 95 return $pContent; 96 } 97 ?>
test-core.js
1 var proxy = ""; 2 3 function login(user, password, proxy, success) { 4 post('http://a.xxxxxx.com/login.php', {u:user, p:password}, null, proxy, success); 5 } 6 7 function post(_url, data, cookie, proxy, success) { 8 var url = 'proxy.php?_url='+_url; 9 if(proxy) 10 url = url + "&_proxy=" + proxy; 11 if (cookie) 12 url = url + "&_cookie=" + encodeURI(cookie); 13 console.log("====>", _url, proxy, data); 14 $.ajax({ 15 type: 'POST', 16 url: url, 17 data: data, 18 dataType: 'json' 19 }) 20 .done(function(d, status, xhr){ 21 console.log("<====", _url, d); 22 success(d); 23 }) 24 .fail(function(xhr, status){ 25 console.log('post error.', status, _url, proxy) 26 }); 27 } 28 29 function parseUriP(key) { 30 var parts = document.location.search.slice( 1 ).split( "&" ), 31 length = parts.length, 32 i = 0, 33 current, 34 value = ""; 35 36 for ( ; i < length; i++ ) { 37 current = parts[ i ].split( "=" ); 38 if ( current[ 0 ] === key ) { 39 value = current[ 1 ]; 40 break; 41 } 42 } 43 return value; 44 } 45 46 (function() { 47 var p = parseUriP("proxy"); 48 if(p!="") 49 proxy = p; 50 })();
test-msg.html
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <link rel="stylesheet" href="lib/qunit.css" type="text/css" media="screen" /> 5 <script src="lib/qunit.js"></script> 6 <script src="lib/jquery-1.11.1.js"></script> 7 <script src="lib/json2.js"></script> 8 <script type="text/javascript" src="test-core.js"></script> 9 <script src="test-msg.js"></script> 10 <title>Tests - xxxxxx messge</title> 11 </head> 12 <body> 13 <div id="header"> 14 <a href="?proxy=localhost:80">本地服务器</a> | 15 <a href="?proxy=test.xxxxxx.com:8001">测试服务器</a> | 16 <a href="?proxy=test.xxxxxx.com:8002">UAT服务器</a> | 17 <a href="?">正式服务器,无代理</a> | 18 </div> 19 <div id="qunit"></div> 20 </body> 21 </html>
test-msg.js
1 module("消息系统"); 2 asyncTest("登录获取消息", function(){ 3 login('aabbcc', '123456', proxy, function(data){ 4 // var d = JSON.parse(data); 5 equal(data.code, 0, '登录成功:'+data.cookie); 6 this.cookie = data.cookie; 7 console.log('login sess:', data); 8 post('http://a.xxxxxx.com/msg_get_grouplist.php', {i:0, c:20}, this.cookie, proxy, function(data){ 9 equal(data.code, 0, JSON.stringify(data)); 10 start(); 11 }); 12 }); 13 }); 14 15 16 asyncTest("登录发送消息", function(){ 17 login('aabbccdd', '123456', proxy, function(data){ 18 // var d = JSON.parse(data); 19 equal(data.code, 0, '登录成功:'+data.cookie); 20 this.cookie = data.cookie; 21 console.log('login sess:', data); 22 post('http://a.xxxxxx.com/msg_get_grouplist.php', {i:0, c:20}, this.cookie, proxy, function(data){ 23 equal(data.code, 0, JSON.stringify(data)); 24 start(); 25 }); 26 }); 27 });