1. 程式人生 > >自動化測試 (一) 12306火車票網站自動登入工具

自動化測試 (一) 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);
            string
html = 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