Cypress 簡介
- 基于 JavaScript 的前端測試工具,可以對瀏覽器中運行的任何內容進行快速、簡單、可靠的測試
- Cypress 是自集成的,提供了一套完整的端到端測試,無須借助其他外部工具,安裝后即可快速地創建、編寫、運行測試用例,且對每一步操作都支持回看
- 不同于其他只能測試 UI 層的前端測試工具,Cypress 允許編寫所有類型的測試,覆蓋了測試金字塔模型的所有測試類型【界面測試,集成測試,單元測試】
- Cypress 底層協議不采用 WebDriver
Cypress 原理
Webdriver 運行的方式
- 大多數測試工具(如:Selenium/webdriver)通過在外部瀏覽器運行并在網絡上執行遠程命令來運行
- 因為 Webdriver 底層通信協議基于 JSON Wire Protocol,運行需要網絡通信
Cypress 運行的方式
Cypress 和 Webdriver 方式完全相反,它與應用程序在相同的生命周期里執行
Cypress 運行測試的大致流程
運行測試后,Cypress 使用 webpack 將測試代碼中的所有模塊 bundle 到一個 js 文件中
然后,運行瀏覽器,并且將測試代碼注入到一個空白頁中,然后它將在瀏覽器中運行測試代碼【可以理解成:Cypress 將測試代碼放到一個 iframe 中運行】
Cypress 運行測試的技術流程
- 每次測試首次加載 Cypress 時,內部 Cypress Web 應用程序先把自己托管在本地的一個隨機端口上【如:http://localhost:65874】
- 在識別出測試中發出的第一個 cy.visit() 命令后,Cypress 會更改本地 URL 以匹配你遠程應用程序的 Origin【滿足同源策略】,這使得你的測試代碼和應用程序可以在同一個 Run Loop 中運行
Cypress 運行更快的根本原因
- Cypress 測試代碼和應用程序均運行在由 Cypress 全權控制的瀏覽器中
- 且它們運行在同一個Domain 下的不同 iframe 中,所以 Cypress 的測試代碼可以直接操作 DOM、Window Objects、Local Storages而無須通過網絡訪問
Cypress 穩定性、可靠性更高的原因
- Cypress 還可以在網絡層進行即時讀取和更改網絡流量的操作
- Cypress 背后是 Node.js Process 控制的 Proxy 進行轉發,這使得 Cypress 不僅可以修改進出瀏覽器的所有內容,還可以更改可能影響自動化操作的代碼
- Cypress 相對于其他測試工具來說,能從根本上控制整個自動化測試的流程
Cypress 架構圖
C++ 與 Cypress 集成概述
Cypress 主要用于前端自動化測試,而 C++ 是后端開發語言。兩者結合通常涉及以下場景:
- 測試 C++ 應用的 Web 接口(如 REST API)。
- 通過 Cypress 驗證 C++ 編譯的 WebAssembly 模塊。
方法 1:測試 C++ 后端 API
C++ 后端暴露 HTTP API 時,可用 Cypress 進行端到端測試。
步驟
編寫 C++ 服務(例如使用 cpp-httplib)提供 REST API:
#include <httplib.h>
using namespace httplib;int main() {Server svr;svr.Get("/api/data", [](const Request& req, Response& res) {res.set_content("{\"value\": 42}", "application/json");});svr.listen("localhost", 8080);
}
在 Cypress 測試文件中調用 API:
describe('API Test', () => {it('fetches data from C++ backend', () => {cy.request('GET', 'http://localhost:8080/api/data').then((response) => {expect(response.body.value).to.eq(42);});});
});
注意
確保 C++ 服務在運行 Cypress 測試前啟動。
方法 2:測試 WebAssembly 模塊
若 C++ 代碼編譯為 WebAssembly(如通過 Emscripten),可用 Cypress 測試其前端集成。
步驟
編譯 C++ 為 WebAssembly:
emcc -o wasm_module.js wasm_module.cpp -s EXPORTED_FUNCTIONS="['_add']"
在 HTML 中加載 WASM 模塊:
<script src="wasm_module.js"></script>
<script>Module.onRuntimeInitialized = () => {window.add = Module.cwrap('add', 'number', ['number', 'number']);};
</script>
Cypress 測試驗證功能:
describe('WASM Test', () => {it('calls C++ function via WASM', () => {cy.visit('index.html');cy.window().then((win) => {expect(win.add(2, 3)).to.eq(5);});});
});
方法 3:C++ 驅動 Cypress 執行
通過 C++ 程序調用系統命令啟動 Cypress 測試(需 Node.js 環境)。
示例代碼
#include <cstdlib>
int main() {system("npx cypress run --headless");return 0;
}
常見問題與優化
- 跨平臺支持:C++ 編譯需兼容目標平臺(如 Windows 需 MinGW)。
- 調試技巧:結合
cy.log()
和 C++ 日志輸出(如std::cout
)排查問題。 - 性能優化:并行運行 C++ 服務與 Cypress 測試(如 Docker 容器化)。
通過上述方法,可實現 C++ 與 Cypress 的高效協作,覆蓋從后端到前端的自動化測試需求。
C#與Cypress的實踐指南
C#通常用于后端開發,而Cypress是一個前端測試框架。雖然兩者屬于不同領域,但可以通過以下方式結合實踐:
后端API測試
使用C#編寫后端API,Cypress測試前端調用API的邏輯。C#示例代碼:
[ApiController]
[Route("api/products")]
public class ProductsController : ControllerBase
{[HttpGet]public IActionResult GetProducts(){return Ok(new[] { "Product1", "Product2" });}
}
Cypress前端測試代碼:
describe('API Tests', () => {it('Should fetch products', () => {cy.request('GET', '/api/products').then((response) => {expect(response.status).to.eq(200);expect(response.body).to.have.length(2);});});
});
數據庫驗證
C#處理數據持久化,Cypress驗證前端顯示:
public class ProductService
{public List<Product> GetAllProducts(){// 數據庫查詢邏輯}
}
Cypress測試:
it('Displays products from database', () => {cy.visit('/products');cy.get('.product-item').should('have.length.gt', 0);
});
組件測試
對于Blazor等前端框架:
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button @onclick="IncrementCount">Click me</button>@code {private int currentCount = 0;private void IncrementCount() { currentCount++; }
}
Cypress測試