6.8 KiB
test K1
Tiến độ
§0 Baseline ĐO TƯƠI trước khi viết (không tin số đề bài) — XONG
Lệnh: dotnet test SolutionErp.slnx --nologo --verbosity minimal -p:BuildInParallel=false -maxcpucount:1
Domain: Failed 0, Passed 45, Total 45
Infra : Failed 1, Passed 544, Total 545
⇒ baseline 590 test = 589 PASS / 1 FAIL. Đề bài ghi "590/590" — LỆCH 1.
🔴 FAIL KHÔNG liên quan K1: Forms.DocxRendererTests.RenderAsync_UnknownPlaceholder_KeepsLiteralToken_NoCrash
→ System.OutOfMemoryException tại WordprocessingDocument.AddMainDocumentPart() (DocxRendererTests.cs:26).
Nghi flake do áp lực RAM (fan-out nhiều agent chạy song song), KHÔNG phải regression code.
Sẽ đo lại RIÊNG test đó ở §3 để phân biệt flake ⟂ vỡ thật.
§1 Đọc nguồn — XONG
sub-invest-fable-b2-cum1.md:59-75§K1.e (5 case) + §K1.f (checklist acceptance)- Code THẬT (test theo CODE, không theo spec):
·
Domain/Master/Catalogs/ContractCatalogEntry.cs:13-25— 10 cột ·Persistence/Configurations/ContractCatalogEntryConfiguration.cs:27-29— UNIQUE filtered[IsDeleted] = 0+ index ApprovalGroup + query filter ·DbInitializer.cs:3163-3324SeedContractCatalogAsync(ApplicationDbContext, ILogger)private static → gọi qua REFLECTION (khuôn S67) ·DbInitializer.cs:3293-3296—IgnoreQueryFilters()khi dò existing (né #75/#76) ·Application/Master/Catalogs/ContractCatalogFeatures.cs— List/Get/Create/Update/Delete + 2 validatorInclusiveBetween(1,8)·Api/Controllers/ContractCatalogController.cs:20-23—[Authorize]class +Roles="Admin"cho 3 verb ghi (0 policy key) ·MenuKeys.cs:28-32 + :173— constContractCatalogVÀOAll;DbInitializer.cs:1776menu row parentCatalogs
PHẦN 2 (relaunch)
§2 Tiền-đề đề bài SAI — file ĐÃ LAND trên đĩa (đo, không suy)
Đề bài relaunch nói "lượt trước chết sau khi đọc contract, CHƯA viết test". ĐĨA nói khác:
?? tests/SolutionErp.Infrastructure.Tests/Application/ContractCatalogTests.cs (git status: untracked)
-rw-r--r-- 25005 Jul 31 14:49 ContractCatalogTests.cs # sub-test-k1.md sửa lần cuối 14:46
⇒ lượt-1 VIẾT XONG file lúc 14:49 rồi chết trước khi cập nhật sub-md/return (đúng hình #53:
việc land, vết mất). Sub-md dừng ở "(ĐANG LÀM)" nên lead đọc thành "chưa làm".
🔴 Bài: git status 1 lệnh phân biệt "chưa-làm" ⟂ "làm-rồi-mất-vết" — KHÔNG viết đè, sẽ mất 7 test.
Khác 2 điểm so với lệnh (lượt-1 tự chốt, ghi rõ ở header file :41-42 + :29-39):
- Đường dẫn
Application/(khôngServices/) —Services/là chỗ code-generator + workflow-service; hàng xóm đúng nghĩa =MasterCatalogFilteredUniqueTests.cs/*SeedTests.csởApplication/. - 7 test (không 6): tách thêm T1b
Seed_AfterSoftDeleteOfOneCode_DoesNotResurrectIt— phép đo riêng choIgnoreQueryFilters()@DbInitializer.cs:3294(né #75/#76).
§3 Việc CÒN LẠI của lượt này = CHẠY (file chưa từng được biên dịch/chạy)
Rủi ro thật: file 25KB viết xong mà chưa build lần nào ⇒ có thể sai chữ ký API (skeleton nấc-2).
Đo: build + chạy filter ContractCatalogTests trước, rồi full-suite.
Kết quả filter (build SẠCH ngay lần đầu — không sai chữ ký API nào):
dotnet test tests/SolutionErp.Infrastructure.Tests/... --filter "FullyQualifiedName~ContractCatalogTests"
Passed! - Failed: 0, Passed: 7, Skipped: 0, Total: 7, Duration: 8 s
7 test (không 6): T1 idempotent-86 · T1b không-hồi-sinh · T2 phân bố · T3 unique-filtered 2-chiều · T4 validator 1..8 · T5 vòng đời handler + xoá mềm · T6 menu-key/policy/grant.
§4 Probe VI-PHÂN — chứng T1b có RĂNG (không đụng production)
File tạm Application/_TempProbeK1.cs (đã XOÁ) tái lập ĐÚNG biểu thức dò-tồn-tại của seeder
DbInitializer.cs:3293-3296 nhưng bỏ IgnoreQueryFilters(), chạy trên chính DB thật sau khi
xoá mềm A1-01:
(A) CÓ IgnoreQueryFilters → 86 mã, CÓ "A1-01" ⇒ seeder skip ⇒ không hồi sinh
(B) BỎ IgnoreQueryFilters → 85 mã, THIẾU "A1-01" ⇒ seeder Add lại ⇒ tổng 87 ⇒ T1b ĐỎ
Passed! - Failed: 0, Passed: 1, Total: 1
⇒ 2 tập KHÁC NHAU ⇒ T1b phân biệt được 2 thế giới, không phải assert rỗng nghĩa.
Zero-risk: không mimic production, gọi seeder THẬT, chỉ đổi 1 toán tử ở phía test.
Dọn dẹp verify 2 chiều: ls → No such file · git status --short tests/ → chỉ còn đúng 1 dòng
?? ContractCatalogTests.cs (không sót file tạm).
§5 FULL SUITE — đo tươi, 0 FAIL
dotnet test SolutionErp.slnx --nologo --verbosity minimal -p:BuildInParallel=false -maxcpucount:1
Domain: Failed 0, Passed 45, Total 45 (54 ms)
Infra : Failed 0, Passed 552, Total 552 (59 s)
⇒ TỔNG 597 test / 0 FAIL (45 + 552).
Đối chiếu với §0 baseline đo tươi đầu lượt-1:
| Domain | Infra | Tổng | Fail | |
|---|---|---|---|---|
| §0 baseline | 45 | 545 | 590 | 1 |
| §5 sau K1 | 45 | 552 | 597 | 0 |
| delta | 0 | +7 | +7 | −1 |
- +7 Infra khớp ĐÚNG 7
[Fact]củaContractCatalogTests.cs— không test nào bị nuốt/trùng tên. - 🟢 1 FAIL của §0 TỰ KHỎI:
Forms.DocxRendererTests.RenderAsync_UnknownPlaceholder_KeepsLiteralToken_NoCrash(OutOfMemoryException @DocxRendererTests.cs:26) nay XANH khi máy rảnh ⇒ xác nhận FLAKE do áp lực RAM lúc fan-out chạy song song, KHÔNG phải regression. Nghi ngờ §0 đóng bằng phép đo, không bằng đoán. - ⚠️ Số đề bài ("590/590 → 596") sai cả 2 vế: baseline có 1 fail, và K1 là 7 test chứ không 6. THẬT = 597/0.
§6 Không đụng production — không có bug cần báo
- File duy nhất thêm:
tests/SolutionErp.Infrastructure.Tests/Application/ContractCatalogTests.cs(untracked). git status --short tests/cuối lượt: đúng 1 dòng??đó._TempProbeK1.csđã xoá sạch.- KHÔNG commit (theo lệnh). KHÔNG sửa
src/Backend/**. - Đọc code K1 lượt này KHÔNG thấy bug. 2 điểm CỐ Ý đáng ghi (đã khoá thành invariant có răng):
·
DbInitializer.cs:3293-3296dùngIgnoreQueryFilters()— khác khuôn:2970(Projects) và ĐÚNG hơn khuôn đó (#75/#76); T1b khoá lại để ai "chuẩn hoá về khuôn cũ" là ĐỎ. · Dup-check handler (ContractCatalogFeatures.cs:131,193) chạy trên active-set ⇒ khớp index filtered[IsDeleted]=0⇒ mã của dòng đã xoá tái dùng được (T3 khoá tầng DB, T5 khoá tầng handler).
END test-k1 — +7 test · 597 PASS / 0 FAIL