如果你正在HTTP上使用安全套接字層(SSL)來加密用戶數據
並且想通過編程來測試你的Web應用
你會發現此技術並非廣為人知
在本月的欄目中
我將示范如何建立一個 SSL 測試服務器
然後編寫測試自動化代碼
並通過一個簡單而又具有代表性的 Web 應用來驗證
Microsoft
NET環境提供了強有力的測試工具來測試采用SSL安全機制的ASP
NET Web應用程序
為了說明它們的使用方法
我將建立一個SSL服務器
並通過一個短小精悍的程序來示范如何自動測試基於HTTPS的Web例子應用程序
雖然 在這方面已有個別技術非常經典並且有很好的文章介紹
但在與我的許多同事交流中
我發現對測試 SSL Web 應用的整體過程的把握相對來說並不是很到位
用兩幅屏幕截圖最能說明問題
Figure
展示了一個簡單但是很有代表性的ASP
NET的Web應用
Figure 一個 ASPNET Web 應用 注意我使用的是 SSL 連接
因為我要在 Internet 上傳送敏感的信用卡信息(注意是
https://
協議
並且在狀態欄有一個小鎖 圖標)
現在
讓我們想象一下用手工方式是如何測試這個應用程序的
我們必須在Web頁上輸入成百甚至上千的用戶名
數量以及信用卡號碼
檢查每一個確認碼
針對預期的結果檢查每行代碼以確定結果是否正確
然後將這些結果記錄在一些表格中
比如 Excel 電子表格或者文本文件中
整個過程耗時
低效
繁瑣並且容易出錯
一個更好的方法是利用
NET框架的強大能力編寫自動化測試例程
在程序中用 SSL 發送測試數據
然後針對預期的確認碼來檢查響應流
Figure
是一個控制台應用程序
它演示了上述的思路
正像你看到的
自動化測試案例的基本做法與 Figure
中所示的手動測試是一樣的
用戶名稱是
Smith
物品數量是
信用卡號是
通過基於 SSL 的 HTTP 加密後被提交到Web應用
測試程序獲取 HTTP 響應流
並搜索響應流中的
C
ED
DA
B
這時
在該響應流中找到期望的確認碼
所以測試 自動化程序記錄下
PASS
結果
在本欄目後面的三個章節中
我將講解產生如 Figure
所示輸出的測試程序
演示如何建立一個接受 SSL 請求的測試服務器
並討論如何擴展本文呈現的技術來滿足你自己的需要
在我講解如何編寫測試自動化程序之前
讓我們首先快速回顧一下本文的例子Web應用程序
正如你在 Figure
看到的一樣
有三個 TextBox 控件
我使用 Visual Studio
NET 缺省的ID
TextBox
TextBox
TextBox
來命名它們
它們分別對應著用戶名稱
物品數量以及信用卡帳號
Label
控件 用於顯示應用程序信息
當我編寫測試自動化程序時
我必須要知道這些信息
此外還需要知道訂單確認碼的產生方式
以便我能確定我的測試案例期望的結果
以下是用於測試此Web應用程序的核心代碼
if (TextBox
Text
Length ==
)
Label
Text =
Please enter credit card number
;
else
{
byte[] input = Encoding
Unicode
GetBytes(TextBox
Text);
byte[] hashed;
using(MD
m = new MD
CryptoServiceProvider())
{
hashed = m
ComputeHash(input);
}
Label
Text =
Thank you
Your confirmation code is
+
BitConverter
ToString(hashed)
Substring(
);
}
為了模擬確認碼的生成
我只利用了用戶輸入的信用卡號
用它產生一個MD
散列
然後截取散列值最左邊的
個字符
在實際的生產系統中
你可能會用更為復雜的方式來產生確認碼
在這種情況下確定預期的結果可能會更具技巧性
不過有一點要特別注意
你不能通過調用被測試的程序來確定預期結果
因為這將破壞測試的有效性
因為你本來就是要檢查 測試自動化程序返回的結果和被測程序返回的結果是否一致
測試自動化程序 這個測試自動化程序出奇的短小
其全部代碼如 Figure
所示
盡管通過編程將數據提交給某個ASP
NET Web 應用程序的技術在 MSDN 庫中已有文檔描述
但是其中有幾個技巧需要特別關注
我決定編寫一個C#控制台程序作為我的測試程序
使用和被測程序一樣的語言開發測試自動化程序通常是個好主意
不管怎麼說
規劃良好的設計並與
NET環境集成意味著你能安全地使用Visual Basic
NET或其它任何與
NET兼容的語言
一般來說
控制台程序類型最適合作為 測試自動化程序
雖然測試程序具備漂亮的用戶界面能給用戶留下深刻印象
但自動化測試程序是一個工具
而不是個人秀
此外
控制台程序也比GUI程序更容易集成到構建系統中
測試自動化程序的整個結構相當簡單
我將測試案例的數據保存在一個簡單的文本文件中
每一行數據表示單個測試案例
以下是該測試案例文件的內容
:Smith:
:
:C
ED
DA
B
:Baker:
:
:CE
C
F
:Gates:
:
:
D
A
信息之間使用冒號(:)進行分隔
我也可以使用任何字符作為分隔符
但在實際的測試案例中避免出現含義模糊的字符很重要
第一個字段是測試案例編號
第二個字 是用戶名稱
第三個字段是數量
第四個字段是信用卡號碼
第五個字段是預期的確認碼
如果你不想使用文本文件
那麼XML文件或 SQL 表 都是很好的可選方案
我的測試自動化程序的基本結構與我的測試案例數據文件是相關在一起的
使用偽代碼表示如下
loop
read a test case line
parse out test case data
build up data to post to application
convert post data to a byte array
post the data
retrieve the response stream
if response stream contains expected confirmation code
log
pass
result
else
log
fail
result
end loop
我首先聲明要用到的命名空間
這樣可以避免用到每個
NET類和對象時都得寫全稱限定名
同時測試自動化程序將要涉及哪些類庫功能也一目了然
using System;
using System
Web;
using System
Text;
using System
Net;
using System
IO;
System
Web 命名空間包含了 HttpUtility 類
這個類可以將一些特殊字符轉換為轉義字符序列
因為缺省的控制台程序並不引用它的所在程序集
即 System
Web
dll
我們必須手動地添加對它的引用
System
Text 命名空間包含了一個Encoding 類
我要用它來處理字節數組 (Byte Array)
System
Net 命名空間包含了 HttpWebRequest類
它是將數據提交到 ASP
NET Web 應用 的基礎類
使用 System
IO 命名空間 是因為我要用數據流處理基於 SSL 的 HTTP 的響應
此外我還需要用它從文本文件中讀取測試案例數據
注意
using 指令字 允許你在使用某個命名空間中的類型時
不必用長長的限定名
接下來
在命令外殼中顯示一段簡單的啟動信息後
聲明測試自動化 程序要用到的一些關鍵變量
string url =
x
;
string viewstate = HttpUtility
UrlEncode(
dDw
MDIxOTUwNDQ
Oz
E/
ailqx
X
zCUfpbWTPybfS
MA==
);
string line;
string[] tokens;
StringBuilder data = new StringBuidler();
byte[] buffer;
string proxy = null;
上面大多數變量的目的從其命名一目了然
只有 viewstate 是個新變量
所以我會對之作簡要解釋
現在我打開測試案例文件
並且一行一行地讀取
using(FileStream fs = new FileStream(args[
]
FileMode
Open))
{
StreamReader tc = new StreamReader(fs);
while ((line = tc
ReadLine()) != null)
{
// parse line
post data
get response
// determine pass or fail
log result
}
}
雖然有很多可選方法來設計此自動化過程
但是 上述這個簡單的結構已經在幾個大型項目中被證明是健壯的
下一步是解析測試案例中數據的每個字段
並且構建一個包含
名稱
值
對 的字符串
tokens = line
Split(
:
);
data
Length =
;
data
Append(
TextBox
=
+ tokens[
]); // Last name
data
Append(
&TextBox
=
+ tokens[
]); // Quantity
data
Append(
&TextBox
=
+ tokens[
]); // Credit card number
data
Append(
&Button
=clicked
);
data
Append(
&__VIEWSTATE=
+ viewstate);
我使用String
Split方法將測試 案例數據行分開
並且將每個字段保存到tokens數組中
測試案例的ID保存到tokens[
]中
用戶名稱保存到tokens[
]中
物品數量保存到tokens[
]中
信用卡號保存到tokens[
]中
為了清晰起見
也可以將這些數值復制到額外的 具有描述性的字符串變量中
如
caseID
lastName
等
如下所示
caseID = tokens[
];
lastName = tokens[
];
// etc
但是我想讓所使用的變量數為最少
傳統的Web服務器 一般都用
名稱
值
對來 提交(POST)數據
多個數據之間用
&
符號分開
如下
lastName=Smith&quantity=
&creditCardNo=
但是
ASP
NET擴展了這種做法
在這個例子中
有五個
名稱
值
對
第一對
你可能希望是
TextBox
=tokens[
]
它將當前測試 案例的用戶名稱(保存在tokens[
From:http://tw.wingwit.com/Article/program/ASP/201311/21874.html