|
# Stardust.WebApiTests
Stardust.WebApi(解耦纯 API 版)的**é›†æˆæµ‹è¯•工程**(xUnit,net10.0)。本文档记录测试基座约定,**新增测试å‰è¯·å…ˆé˜…读**,é¿å…釿–°è¸©è¿›å…¨å±€çжæ€å’Œå¹¶å‘çš„å‘。
## 测试分层定ä½
本工程是** HTTP é›†æˆæµ‹è¯•**:用 `WebApplicationFactory<Program>` å¯åŠ¨çœŸå®žçš„ Stardust.WebApi 主机,通过真实 HTTP 请求(带 Bearer 登录æ€ï¼‰éªŒè¯å„区域的 `meta` ç‰ç«¯ç‚¹ï¼Œä¸ mock 控制器与数æ®å±‚。
- 验è¯å¯¹è±¡ï¼šç»Ÿä¸€å“åº”ä¿¡å° `{code, data, message}`ã€å„åŒºåŸŸå—æ®µç«¯ç‚¹ï¼ˆ`GET {area}/{controller}/meta`)å¯ç”¨æ€§ã€`list/form/search` 区段契约。
- å•元测试(æœåС层ã€å®žä½“行为)放在 `Stardust.ServerTests`,ä¸åœ¨æœ¬å·¥ç¨‹ã€‚
- API 宿主专属的控制器行为测试(如 `Mcp/` 下ç»åå°„éªŒè¯ `StarWebApi` çš„ `McpTokenController`)放在本工程:`Stardust.ServerTests`
åŒæ—¶å¼•用 Stardust.Web,与 `NewLife.Cube`(API版) çš„åŒå程åºé›†å†²çªï¼Œæ— æ³•åŠ è½½ API 宿主。
- å‰ç«¯ e2e 在 `Stardust.Web.Vue`(`pnpm exec playwright test`),与åŽç«¯æµ‹è¯•分层互ä¸é‡å 。
## 接入被测工程
`Stardust.WebApi.csproj` 用顶级è¯å¥ï¼Œéšå¼ `Program` 类是全局命å空间下的 `internal`。为了让本工程能用 `WebApplicationFactory<Program>`,在 WebApi 工程的 csproj 里声明了:
```xml
<InternalsVisibleTo Include="Stardust.WebApiTests" />
```
本工程**未**é‡å¤å¼•用 Stardust.Data / Stardust.Extensions / Stardust,它们由 Stardust.WebApi ä¼ é€’å¼•å…¥ã€‚
## å¹¶å‘与è¿è¡Œé…ç½®
- `xunit.runner.json` å…³é—集åˆçº§å¹¶è¡Œï¼ˆ`parallelizeTestCollections: false`),全工程串行执行,å¤ç”¨åŒä¸€ä¸ªä¸»æœºå®žä¾‹é¿å… OOM。
- 所有测试类用 `[Collection(WebApiCollection.Name)]` 声明å¤ç”¨ `WebApiTestFactory` 共享实例。
## 进程级状æ€å¥‘约
`WebApiTestFactory` åœ¨æž„é€ å‡½æ•°é‡Œå†™å…¥ 5 个进程级环境å˜é‡ï¼ˆ4 个 SQLite 连接串 + `StarServer` é‡å®šå‘)æ¥éš”离数æ®åº“与é…ç½®ä¸å¿ƒï¼Œå¹¶åœ¨ `Dispose` ä¸**åŽŸæ ·è¿˜åŽŸ**ï¼Œä¸æ±¡æŸ“åŒä¸€è¿›ç¨‹å†…的其它测试工程。
| çŠ¶æ€ | å¤„ç† |
|---|---|
| `ConnectionStrings__Stardust` ç‰ 4 个 | æž„é€ æ—¶å†™å…¥ä¸´æ—¶ SQLite 路径,Dispose 还原旧值 |
| `StarServer` | æž„é€ æ—¶æŒ‡å‘æ— 效地å€ï¼ŒDispose 还原旧值 |
| `%TEMP%/stardust_webapi_test_*` 临时库目录 | Dispose ä¸å…ˆåœä¸»æœºé‡Šæ”¾æ–‡ä»¶é”,å†åˆ 除 |
## 新增测试指引
- åŒºåŸŸå—æ®µç«¯ç‚¹ï¼šåœ¨ `Areas/` 下对应区域文件里给 `Endpoints` 陿€å±žæ€§åŠ ä¸€è¡Œ `"{Area}/{Controller}/meta"`,å¤ç”¨ `[Theory] Meta_ReturnsListFields`(æ–言 `data.list`ï¼›é…ç½®é¡µåªæœ‰ `form`,改用 `Meta_ConfigPage_ReturnsFormFields`)。
- 需è¦è‡ªå®šä¹‰æ–言的端点:注入 `ITestOutputHelper` æž„é€ `ApiClient`,用 `GetApiAsync<T>` / `GetJsonAsync`,业务æ–言写在测试方法内(æ–言留在测试里,ä¸è—进基类抛异常)。
- æ–°çš„ç‰¹æ€§è·¯ç”±æŽ§åˆ¶å™¨ï¼ˆéž `api/{area}/{controller}/{action}` 模æ¿ï¼‰ï¼šåœ¨ `ApiClient.NormalizeUrl` çš„ `_routeRules` é‡ŒåŠ ä¸€è¡Œå‰ç¼€æ˜ 射。
- 统一信å°å¥‘çº¦ï¼šè§ `Contract/ApiResponseContractTests.cs`(覆盖 `meta` çš„ `list`/`form`/`search` 区段与 `add`/`detail` çœç•¥è§„则)。
### 新增测试检查清å•
- [ ] æ–言业务结果而éžä»…ã€Œæ— å¼‚å¸¸ã€ï¼›å¤±è´¥è·¯å¾„ä¹Ÿè¦æ–言
- [ ] 触碰了进程级状æ€ï¼Ÿç¡®è®¤ `WebApiTestFactory` 已负责还原
- [ ] åŠ äº†ç‰¹æ€§è·¯ç”±æŽ§åˆ¶å™¨ï¼Ÿç¡®è®¤ `ApiClient.NormalizeUrl` æ˜ å°„å·²æ›´æ–°
|