Close DDD cleanup and tests-support closure
This commit is contained in:
7
server-rs/crates/tests-support/Cargo.toml
Normal file
7
server-rs/crates/tests-support/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "tests-support"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
@@ -1,18 +1,21 @@
|
||||
# tests-support 共享 crate 占位说明
|
||||
# tests-support 共享测试支撑 crate
|
||||
|
||||
日期:`2026-04-20`
|
||||
|
||||
## 1. crate 职责
|
||||
|
||||
`tests-support` 是测试支撑共享 crate,后续负责:
|
||||
`tests-support` 是测试支撑共享 crate,当前已作为 `server-rs` workspace member 落位,负责承接跨 crate 复用的测试辅助能力。
|
||||
|
||||
1. contract、integration、smoke 测试的共享夹具与辅助工具
|
||||
2. 测试环境配置、测试数据装配与断言工具
|
||||
3. 供 `crates/api-server`、`crates/spacetime-module` 与各模块 crate 复用的测试基础设施能力
|
||||
当前首版只放无业务规则的 smoke/HTTP 通用断言:
|
||||
|
||||
1. Maincloud healthz 默认地址常量
|
||||
2. smoke URL 空值与尾斜杠归一化
|
||||
3. HTTP 2xx 状态码断言
|
||||
4. healthz 非空响应体断言
|
||||
|
||||
## 2. 当前阶段说明
|
||||
|
||||
当前提交仅完成目录占位,不提前进入测试夹具、断言工具与 smoke 支撑实现。
|
||||
当前阶段不提前引入伪环境、不编造业务夹具,也不承接 contract DTO 或 SpacetimeDB reducer 的测试数据装配。
|
||||
|
||||
后续与本 crate 直接相关的任务包括:
|
||||
|
||||
@@ -26,3 +29,4 @@
|
||||
1. `tests-support` 只承接测试支撑能力,不承接业务规则实现。
|
||||
2. 测试夹具要尽量贴近真实 contract 与真实模块边界,避免重新引入脱离现网的伪环境。
|
||||
3. 不允许把测试辅助逻辑散落到各模块 crate 中重复实现。
|
||||
4. SpacetimeDB 表、reducer、procedure 和迁移规则仍归 `spacetime-module` 与 `WP-ST`,本 crate 不定义 schema。
|
||||
|
||||
92
server-rs/crates/tests-support/src/lib.rs
Normal file
92
server-rs/crates/tests-support/src/lib.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use std::fmt;
|
||||
|
||||
pub const DEFAULT_MAINCLOUD_HEALTHZ_URL: &str = "http://127.0.0.1:3100/healthz";
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct SmokeAssertionError {
|
||||
message: String,
|
||||
}
|
||||
|
||||
impl SmokeAssertionError {
|
||||
/// 测试支撑 crate 只提供断言辅助,不承接业务错误分类。
|
||||
pub fn new(message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SmokeAssertionError {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
formatter.write_str(&self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for SmokeAssertionError {}
|
||||
|
||||
/// 归一化本地 smoke URL,供不同测试入口复用同一套空值与斜杠处理口径。
|
||||
pub fn normalize_smoke_url(input: impl AsRef<str>) -> String {
|
||||
let trimmed = input.as_ref().trim();
|
||||
if trimmed.is_empty() {
|
||||
return DEFAULT_MAINCLOUD_HEALTHZ_URL.to_string();
|
||||
}
|
||||
|
||||
trimmed.trim_end_matches('/').to_string()
|
||||
}
|
||||
|
||||
/// 断言 HTTP 状态码处于 2xx,避免 smoke 测试散落重复判断。
|
||||
pub fn assert_success_status(status: u16) -> Result<(), SmokeAssertionError> {
|
||||
if (200..=299).contains(&status) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Err(SmokeAssertionError::new(format!(
|
||||
"期望 HTTP 2xx 状态码,实际为 {status}"
|
||||
)))
|
||||
}
|
||||
|
||||
/// 断言 healthz 响应体非空。具体 JSON 字段语义仍归 api-server 自己的 contract 测试负责。
|
||||
pub fn assert_non_empty_healthz_body(body: impl AsRef<str>) -> Result<(), SmokeAssertionError> {
|
||||
if body.as_ref().trim().is_empty() {
|
||||
return Err(SmokeAssertionError::new("healthz 响应体不能为空"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn normalize_smoke_url_uses_maincloud_healthz_when_empty() {
|
||||
assert_eq!(
|
||||
normalize_smoke_url(" "),
|
||||
DEFAULT_MAINCLOUD_HEALTHZ_URL.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normalize_smoke_url_removes_trailing_slash() {
|
||||
assert_eq!(
|
||||
normalize_smoke_url(" http://127.0.0.1:3100/ "),
|
||||
"http://127.0.0.1:3100"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assert_success_status_rejects_non_2xx() {
|
||||
let error = assert_success_status(503).expect_err("非 2xx 状态码必须失败");
|
||||
assert_eq!(error.message(), "期望 HTTP 2xx 状态码,实际为 503");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assert_non_empty_healthz_body_rejects_blank_body() {
|
||||
let error = assert_non_empty_healthz_body(" \n ").expect_err("空响应体必须失败");
|
||||
assert_eq!(error.message(), "healthz 响应体不能为空");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user