HtmlUnit测试工具的推出,创意非常好。是一款给java开发用的browser。说它是browser,其实它是对html建模并且提供API来访问页面,点击链接等等的java类库。

    这样的测试工具有这样几个优点:
运行起来没有界面,速度非常快。
由于是java类库,有无限扩展的可能,可以构造各种功能强大的工具。包括本地化测试,多种数据源输入数据。
跨平台,跨浏览器。java本身就有跨平台的特性,浏览器,只要简单的设定一个参数就可以轻易模仿想要的浏览器了。
转化为性能测试,非常简单,可以共享同一脚本。
 
官网:http://htmlunit.sourceforge.net/
 
代码示例:
 
  1. import java.io.IOException; 
  2. import java.net.MalformedURLException; 
  3. import java.net.URL; 
  4. import java.util.Arrays; 
  5. import java.util.regex.Matcher; 
  6. import java.util.regex.Pattern; 
  7. import com.gargoylesoftware.htmlunit.BrowserVersion; 
  8. import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; 
  9. import com.gargoylesoftware.htmlunit.HttpMethod; 
  10. import com.gargoylesoftware.htmlunit.WebClient; 
  11. import com.gargoylesoftware.htmlunit.WebRequest; 
  12. import com.gargoylesoftware.htmlunit.html.HtmlForm; 
  13. import com.gargoylesoftware.htmlunit.html.HtmlInput; 
  14. import com.gargoylesoftware.htmlunit.html.HtmlPage; 
  15. import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput; 
  16. import com.gargoylesoftware.htmlunit.util.NameValuePair; 
  17.  
  18. public class MySina { 
  19.  
  20.     private WebClient  client; 
  21.     private WebRequest request; 
  22.     private String     sinaLoginUrl = " http://mail.sina.com.cn/cgi-bin/login.php"
  23.     private String     hostSinaUrl  = ""
  24.  
  25.     public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException { 
  26.         String username = "***"
  27.         String password = "***"
  28.         String newpassword = "***"
  29.         String nickname = "***"
  30.  
  31.         MySina mySina = new MySina(); 
  32.         if (mySina.mailLoginBySina(username, password)) { // 登录 
  33.             mySina.updatePwdBySina(password, newpassword); // 修改密码 
  34.             mySina.updateNickName(nickname); // 修改帐户昵称 
  35.         } else { 
  36.             System.out.println("登录失败!请检查用户名和密码是否正确!"); 
  37.         } 
  38.     } 
  39.  
  40.     public MySina(){ 
  41.         client = new WebClient(BrowserVersion.INTERNET_EXPLORER_8); 
  42.         client.setJavaScriptEnabled(false); 
  43.     } 
  44.  
  45.     /** 
  46.      * 更改帐户昵称 
  47.      *  
  48.      * @param nickname 昵称 
  49.      * @return boolean 
  50.      * @throws FailingHttpStatusCodeException 
  51.      * @throws IOException 
  52.      */ 
  53.  
  54.     public boolean updateNickName(String nickname) throws FailingHttpStatusCodeException, IOException { 
  55.         String sinaSetUrl = hostSinaUrl + "basic/setting_account"
  56.         request = new WebRequest(new URL(sinaSetUrl), HttpMethod.POST); 
  57.         request.setCharset("utf-8"); 
  58.         request.setRequestParameters(Arrays.asList(new NameValuePair("nickname", nickname), new NameValuePair("pop3"
  59.                                                                                                               "on"), 
  60.                                                    new NameValuePair("imap""on"))); 
  61.         client.getPage(request); 
  62.         HtmlPage p = client.getPage(hostSinaUrl + "classic/index.php"); 
  63.  
  64.         if (p.getBody().getTextContent().indexOf("\"NickName\":\"" + nickname + "\"") > 0) { 
  65.             return true
  66.         } else { 
  67.             return false
  68.         } 
  69.  
  70.     } 
  71.  
  72.     /** 
  73.      * 修改密码 
  74.      *  
  75.      * @param oldpassword 旧密码 
  76.      * @param newpassword 新密码 
  77.      * @return boolean 
  78.      * @throws FailingHttpStatusCodeException 
  79.      * @throws IOException 
  80.      */ 
  81.  
  82.     public boolean updatePwdBySina(String oldpassword, String newpassword) throws FailingHttpStatusCodeException, 
  83.                                                                           IOException { 
  84.         String sinaSetUrl = " http://login.sina.com.cn/member/security/password.php"
  85.         request = new WebRequest(new URL(sinaSetUrl), HttpMethod.POST); 
  86.         request.setCharset("gbk"); 
  87.         request.setRequestParameters(Arrays.asList(new NameValuePair("pass", oldpassword), 
  88.                                                    new NameValuePair("pass1", newpassword), 
  89.                                                    new NameValuePair("pass2", newpassword))); 
  90.         HtmlPage p = client.getPage(request); 
  91.  
  92.         if (p.getBody().getTextContent().indexOf("您的密码修改成功") > 0) { 
  93.             return true
  94.         } else { 
  95.             return false
  96.         } 
  97.     } 
  98.  
  99.     /** 
  100.      * 登录 
  101.      *  
  102.      * @param username 用户名 
  103.      * @param password 密码 
  104.      * @return boolean 
  105.      * @throws FailingHttpStatusCodeException 
  106.      * @throws MalformedURLException 
  107.      * @throws IOException 
  108.      */ 
  109.  
  110.     public boolean mailLoginBySina(String username, String password) throws FailingHttpStatusCodeException, 
  111.                                                                     MalformedURLException, IOException { 
  112.  
  113.         HtmlPage loginPage = client.getPage(sinaLoginUrl); 
  114.         HtmlForm loginForm = loginPage.getFormByName("free"); 
  115.         HtmlInput u = loginForm.getInputByName("u"); 
  116.         HtmlInput psw = loginForm.getInputByName("psw"); 
  117.         HtmlSubmitInput loginButton = loginForm.getInputByName("登录"); 
  118.         u.setValueAttribute(username); 
  119.         psw.setValueAttribute(password); 
  120.         HtmlPage result = loginButton.click(); 
  121.         String resultUrl = result.getUrl().toString(); 
  122.  
  123.         if (resultUrl.indexOf("classic/index.php") > 0) { 
  124.             String regex = "http://(.*?)/"
  125.             hostSinaUrl = myRegex(resultUrl, regex, null); 
  126.             if (hostSinaUrl.length() > 0) { 
  127.                 return true
  128.             } else { 
  129.                 return false
  130.             } 
  131.         } else { 
  132.             return false
  133.         } 
  134.  
  135.     } 
  136.  
  137.     /** 
  138.      * 正则匹配替换 
  139.      *  
  140.      * @param str 
  141.      * @param reg 
  142.      * @param replace 
  143.      * @return 
  144.      */ 
  145.  
  146.     public String myRegex(String str, String reg, String[] replace) { 
  147.         String result = null
  148.         Matcher m = Pattern.compile(reg).matcher(str); 
  149.         while (m.find()) { 
  150.             result = m.group(); 
  151.             if (replace != null && replace.length > 0) { 
  152.                 for (String s : replace) { 
  153.                     result = result.replace(s, ""); 
  154.                 } 
  155.             } 
  156.         } 
  157.         return result; 
  158.     }