上海網(wǎng)站備案流程app下載注冊量推廣平臺
我們需要從訪客那里收集哪些信息,以便將其登記為電子郵件通訊的訂閱者?
- 電子郵件地址:這是最基本的要求,因為我們需要通過電子郵件地址向訂閱者發(fā)送內(nèi)容。
- 姓名:雖然這不是強制性的,但我們希望收集一個名字,以便在電子郵件中個性化問候(例如,“您好 {{subscriber.name}}!”)。這有助于增加郵件的親和力和互動性。
為什么收集這些信息?
- 電子郵件地址:這是發(fā)送消息的唯一標(biāo)識符。
- 姓名:用于個性化郵件,使訂閱者感到更親切。我們不強制要求真實姓名,允許用戶使用任何他們喜歡的標(biāo)識符(例如,coderLZ)。
表單提交的編碼方式
假設(shè)數(shù)據(jù)是通過HTML表單收集的,并通過POST請求傳遞給后端API,表單數(shù)據(jù)的編碼方式可以選擇?application/x-www-form-urlencoded
。這是最常見的表單數(shù)據(jù)編碼方式,適用于大多數(shù)簡單的表單提交場景。
示例HTML表單
<form action="/subscribe" method="post"><label for="email">電子郵件地址:</label><input type="email" id="email" name="email" required><label for="name">姓名 (可選):</label><input type="text" id="name" name="name"><button type="submit">訂閱</button>
</form>
后端API接收的數(shù)據(jù)格式
當(dāng)表單提交時,數(shù)據(jù)將以?application/x-www-form-urlencoded
?格式編碼,并通過POST請求的請求體(body)傳遞給后端API,比如
email=example%40example.com&name=DenverCoder9
通常在URL編碼中使用%20替換空格,%40替換@符號,以確保URL的標(biāo)準(zhǔn)化、兼容性和安全性。通過URL編碼,可以確保各種字符在URL中正確傳輸和解析。
將需求轉(zhuǎn)化為測試用例,在實際開發(fā)過程中也是如此,測試先行
測試用例
- 驗證電子郵件地址的有效性
- 描述:確保用戶提供的電子郵件地址是有效的。
- 測試用例:
- 輸入:email=example@example.com
- 期望輸出:訂閱成功。
- 輸入:email=invalidemail
- 期望輸出:顯示錯誤消息,提示電子郵件格式無效。
- 驗證姓名字段的靈活性
- 描述:確保用戶可以使用任何形式的姓名,包括空值。
- 測試用例:
- 輸入:email=example@example.com&name=John Doe
- 期望輸出:訂閱成功。
- 輸入:email=example@example.com&name=DenverCoder9
- 期望輸出:訂閱成功。
- 輸入:email=example@example.com&name=
- 期望輸出:訂閱成功,姓名字段為空。
- 驗證表單提交的編碼方式
- 描述:確保表單數(shù)據(jù)以 application/x-www-form-urlencoded 格式正確編碼。
- 測試用例:
- 輸入:email=example%40example.com&name=John%20Doe
- 期望輸出:訂閱成功,電子郵件地址和姓名正確解析。
- 驗證重復(fù)訂閱
- 描述:確保同一電子郵件地址不能多次訂閱。
- 測試用例:
- 輸入:第一次訂閱?email=example@example.com&name=John Doe
- 期望輸出:訂閱成功。
- 輸入:第二次訂閱?email=example@example.com&name=John Doe
- 期望輸出:顯示錯誤消息,提示該電子郵件地址已訂閱。
- 驗證錯誤處理
- 描述:確保系統(tǒng)能夠正確處理各種錯誤情況。
- 測試用例:
- 輸入:email=example@example.com&name=
- 期望輸出:訂閱成功,姓名字段為空。
- 輸入:email=&name=John Doe
- 期望輸出:顯示錯誤消息,提示電子郵件地址不能為空。
- 輸入:email=example@example.com&name=<>
- 期望輸出:顯示錯誤消息,提示姓名字段包含非法字符。
編寫測試用例代碼
本文結(jié)合表驅(qū)動測試(Table-Driven Testing)方法,它通過使用一個數(shù)據(jù)表來組織測試用例。每個測試用例通常包含輸入數(shù)據(jù)、預(yù)期輸出結(jié)果以及可能的其他信息,如測試描述或標(biāo)簽。這種方法使得測試代碼更加簡潔、易于理解和維護,同時也方便擴展新的測試用例。
表驅(qū)動測試的優(yōu)勢
- 代碼簡潔:通過將測試用例組織成表格形式,可以避免大量的重復(fù)代碼,使測試邏輯更加清晰。
- 易于維護:當(dāng)需要添加新的測試用例或修改現(xiàn)有測試用例時,只需更新表格中的數(shù)據(jù),而不需要改動測試邏輯。
- 便于擴展:可以輕松地向表格中添加新的行,以涵蓋更多的測試場景。
- 更好的可讀性:將測試用例組織成表格形式,使得測試意圖更加明確,更容易理解。
///! src/health_check.rs
#[tokio::test]
async fn subscribe_returns_a_200_for_valid_form_data() {let app_address = spawn_app();let client = reqwest::Client::new();let body = "name=le%20guin&email=ursula_le_guin%40gmail.com";let response = client.post(&format!("{}/subscriptions", &app_address)).header("Content-Type", "application/x-www-form-urlencoded").body(body).send().await.expect("Failed to execute request .");//此處我們希望返回200,但是很明顯/subscriptions路徑根本不存在,應(yīng)該返回404assert_eq!(200, response.status().as_u16());
}#[tokio::test]
async fn subscribe_returns_a_400_when_data_is_missing() {let app_address = spawn_app();let client = reqwest::Client::new();
///```test_cases:定義了一個包含多個測試用例的向量。每個測試用例是一個元組,包含兩個字符串:
/// invalid_body:無效的請求體,用于模擬缺少某些必要字段的情況。
///```error_message:描述該測試用例的錯誤信息,用于在斷言失敗時提供更詳細的錯誤信息。let test_cases = vec![("name=le%20guin", "missing the email"),("email=ursula_le_guin%40gmail.com", "missing the name"),("", "missing both name and email"),];for (invalid_body, error_message) in test_cases {let response = client.post(&format!("{}/subscriptions", &app_address)).header("Content-Type", "application/x-www-form-urlencoded").body(invalid_body).send().await.expect("Failed to execute request.");assert_eq!(400,response.status().as_u16(),"The API did not fail with 400 bad Request when the payload was {}.",error_message);}
}
這段代碼通過表驅(qū)動測試的方法,驗證了一個 HTTP API 在接收到缺少必要數(shù)據(jù)的請求時是否會正確返回 400 Bad Request 狀態(tài)碼。每個測試用例都包含一個無效的請求體和一個描述性的錯誤信息,以便在斷言失敗時提供詳細的錯誤提示。雖然并沒有覆蓋到所有的測試用例,但是這種測試方法不僅提高了代碼的可讀性和可維護性,還確保了 API 的健壯性。
下一節(jié)我們將開始實現(xiàn)/subscriptions 功能