自動化測試 (一) 12306火車票網站自動登入工具
還記得2011年春運,12306火車票預訂網站經常崩潰無法登入嗎。 今天我們就開發一個12306網站自動登入軟體。 幫助您輕鬆訂票
Web的原理就是,瀏覽器傳送一個Request給Web伺服器,Web伺服器處理完這個請求之後傳送一個HTTP Response給瀏覽器。
如果我們用自己寫的程式來發送Request給Web伺服器,然後再捕獲Web伺服器發回來的Response. 檢查它與期望值值是否一致。 這不就是Web自動化測試嗎? 這樣的自動化測試叫做請求響應測試, 別小看這樣的自動化測試。 什麼開心農場助手,自動投票機。 網路爬蟲都是用這個做的。
.NET中提供的類來發送HTTP Request
在System.Net命名工具下, .NET提供了5種方法 可以傳送HTTP Request和取回HTTP Response. 它們分別是
WebClient:
WebRequent-WebResponse:
HttpWebRequest-HttpWebResponse:
TcpClient:
Socket:
這5個類中,最適合的就是HttpWebRequest-HttpWebResponse了, 這個才能滿足我們需要的功能。 順便說下WebClient類的用法
WebClient類的用法
WebClient的用法極其簡單, 主要用於下載檔案,或者單純獲取Response. 這個類不能模擬“POST” 的Http Request, 功能很少。
例項如下:
static void Main(string[] args) { // 部落格園首頁地址 string uri = "http://www.cnblogs.com"; WebClient MyWebClient = new WebClient(); Stream st = MyWebClient.OpenRead(uri); StreamReader sr = new StreamReader(st); stringhtml = sr.ReadToEnd(); sr.Close(); st.Close(); Console.Write(html); }
模擬“GET” 方法
我們主要是使用HttpWebRequest-HttpWebResponse 這兩個類來做自動化測試.
先看看如何模擬“GET”方法,來開啟部落格園首頁, 在下面的例子中,設定了一些 HttpWebRequest的一些屬性
static void Main(string[] args) { // 部落格園首頁地址 string uri = "http://www.cnblogs.com"; HttpWebRequest Req = (HttpWebRequest)WebRequest.Create(uri); // 瀏覽器和伺服器互動的方法 Req.Method = "GET"; // 瀏覽器的型別,IE或者Firefox Req.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1;)"; // 是否允許自動重定向(自動跳轉) Req.AllowAutoRedirect = true; // 自動跳轉的次數 Req.MaximumAutomaticRedirections = 3; // 超時時間50000=50秒 Req.Timeout = 50000; // 是否建立TCP持久連線 Req.KeepAlive = true; HttpWebResponse response = (HttpWebResponse)Req.GetResponse(); Stream stream = response.GetResponseStream(); Encoding myEncoding = Encoding.GetEncoding("UTF-8"); StreamReader streamReader = new StreamReader(stream, myEncoding); string html = streamReader.ReadToEnd(); Console.Write(html); }
Cookie 的處理
還有一個很重要的問題是,我們如何處理Cookie? 程式和Web伺服器的互動中, 程式需要把Cookie傳送給Web伺服器, Web伺服器也會給程式傳送新的Cookie. 我們怎麼模擬這個呢?
C#提供了 CookieContainer 物件。 HttpWebRequest傳送Request時會使用CookieContainer 中的Cookie. HttpWebResponse返回Response後,會自動修改CookieContainer 物件的Cookie. 這樣的話,Cookie就不用我們操心了。 用法非常簡單
CookieContainer MyCookieContainer = new CookieContainer();
HttpWebRequest Req = (HttpWebRequest)WebRequest.Create(uri);
Req.CookieContainer = MyCookieContainer;
如何跟HTTPS的網站互動
我們用瀏覽器開啟HTTPS的網站,如果我們沒有安裝證書,通常頁面會顯示 "此網站的安全證書有問題",我們必須再次點"繼續瀏覽此網站(不推薦)"才能檢視頁面資訊. 如下圖所示
那麼我們的程式,如何忽略HTTPS證書錯誤呢?
只要在程式中加入下面這段程式碼,就可以忽略HTTPS證書錯誤,讓我們的程式能和HTTPS網站正確的互動了.
System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => { return true; };
模擬"POST" 方法
POST和GET的區別在於, POST會把資料放在Body裡面傳送給Web伺服器. 程式碼如下
View Code客戶端傳送給服務端的資料進行UrlEncode處理
需要注意的是Web客戶端發給Web服務端的資料如果包含空格和特殊字元(比如:漢字) 就要進行UrlEncode處理。
解決這個問題很簡單。
在C#中Add reference 新增System.Web 元件
新增System.Web名稱空間, 然後呼叫HttpUtility.UrlEncode()方法就可以進行編碼了
例項:12306火車票網站登入工具
2011年鐵道部推出了12306火車票預訂網站, 可是因為訪問者太多,經常崩潰。根本登入不了。網站訪問高峰的時候,根本沒辦法登入成功, 一直會報錯(如下圖)
下面我們就運用上面的知識,來開發一個自動登入的工具
首先我們用瀏覽器去開啟12306網站去登入, 同時開啟Fiddler去抓包分析,看看瀏覽器是如何和Web伺服器互動的。
通過抓包分析,我們發現登入其實很簡單。就是把使用者名稱,密碼和驗證碼通過"POST"方法提交給伺服器。如下圖所示
在Fiddler中我們點選Inspectors tab->TextView Tab下, 能看到提交給Web伺服器的資料是
string data="loginUser.user_name=thisisuserName&nameErrorFocus=&user.password=thispassword&passwordErrorFocus=&randCode=CF99&randErrorFocus=";
我們把使用者名稱,密碼,驗證碼換成變數,然後Post給Web伺服器就可以了。
登入的時候需要輸入驗證碼。 很幸運的是12306網站在這裡有個bug, 當驗證碼圖片沒有主動重新整理的時候,老的驗證碼一直可以用。 這樣的話我們的工具用老的驗證碼不停地給伺服器傳送登入的HttpRequest,直到登入成功。
登入的核心程式碼如下, 實際的程式碼比這個複雜,要寫成迴圈呼叫,還要寫成多執行緒,完整的請參考原始碼
具體程式碼為
string data = "loginUser.user_name=" + userName + "&nameErrorFocus=&user.password=" + password + "&passwordErrorFocus=&randCode=" + code + "&randErrorFocus=focus"; string loginUrl = "https://dynamic.12306.cn/otsweb/loginAction.do?method=login"; string afterLogin = HttpHelper.GetResponse(loginUrl, "POST", data);
原始碼下載
執行後效果如下
過段時間再寫篇部落格, 我將介紹12306火車票自動預訂工具的開發過程。 此工具可以自動登入,自動下單。 買火車票就是小case了。
http://www.cnblogs.com/TankXiao/archive/2012/02/20/2350421.html