View 測試的核心難題
- View 引擎依賴
HttpContext、ControllerContext 等運行時上下文
- 傳統做法構造測試上下文極其繁瑣,且屬於測試 ViewEngine 而非 View 邏輯
- Stephen Walther 方案:字符串斷言 HTML,脆弱且維護成本高
正確策略:ViewData 隔離 + LTAF 瀏覽器自動化
1. 代碼規範:View 僅依賴 ViewData
<!-- 錯誤:直接用 HttpContext -->
<% if (User.Identity.IsAuthenticated) { %>...<% } %>
<!-- 正確:Controller 注入 ViewData -->
<% if ((bool)ViewData["IsAuthenticated"]) { %>...<% } %>
2. 單元測試代碼 (NUnit + LTAF)
[TestFixture]
public class ProductViewTests {
private LTAF.WebTest _test;
[SetUp]
public void Setup() {
_test = new LTAF.WebTest("https://localhost/testapp");
}
[Test]
public void ProductList_ShowsCorrectData() {
// 1. 直接調用 Controller Action 獲取 ViewResult
var controller = new ProductController(_mockRepo.Object);
var result = controller.List(1) as ViewResult;
// 2. 驗證 ViewData/Model
Assert.AreEqual("產品列表", result.ViewData["Title"]);
var products = result.ViewData.Model as List;
Assert.AreEqual(3, products.Count);
// 3. LTAF 瀏覽器級測試 (可選,針對 JS/CSS 交互)
_test.Navigate("/Product/List?page=1");
_test.AssertElementText("h1", "產品列表");
_test.AssertElementCount(".product-row", 3);
}
}
3. LTAF 核心優勢
- 同進程運行:測試代碼與網站共享 AppDomain,直接傳遞對象引用
- 真實瀏覽器:支持 JS 執行、CSS 渲染、DOM 操作驗證
- 跨瀏覽器:IE/Chrome/Firefox 同套測試碼
避坑指南
- Frame 中
window.top 異常 → 封裝 getTop() 兼容
- 避免
alert/confirm 阻塞測試 → 使用模態框組件替代
- 測試數據構建:使用 Builder 模式構造複雜 ViewModel