# Q01 岗位搜索真实查询覆盖实施指令 ## 一、任务边界 项目根目录:`C:\Users\15642\Desktop\zhilai` 目标分支:`test/q01-job-search-specification` 本轮只补岗位搜索真实数据库测试和验收证据。原则上不修改生产代码;如果测试复现生产缺陷,先保存失败证据并停止,未经负责人确认不得顺手修复。 禁止修改岗位接口、DTO、权限、状态机和搜索语义;禁止新增 Flyway、表、索引、ErrorCode 或公网接口;禁止进入 R01;禁止删除现有 Mock 测试;禁止 `git add -A`、commit、push、reset、restore、checkout、clean;禁止删除或移动历史未跟踪文件。 ## 二、开始前核查 执行: ```powershell cd C:\Users\15642\Desktop\zhilai git branch --show-current git status --short git diff --cached --name-only git log -5 --oneline git diff --check git status --short -- mydreamjob-server/src/main/resources/db/migration ``` 确认分支正确、暂存区为空、HEAD 为 S03 检查点 `cb3bc57` 或报告实际偏差、历史未跟踪文件保留、V1–V43 均未修改。搜索并完整阅读适用 `AGENTS.md`;当前基线未发现时记录“未发现”。 ## 三、必须阅读 ```text docs/q01-job-search-real-query-design.md mydreamjob-server/src/main/java/com/mydreamjob/job/Job.java mydreamjob-server/src/main/java/com/mydreamjob/job/JobRepository.java mydreamjob-server/src/main/java/com/mydreamjob/job/JobSearchSpecification.java mydreamjob-server/src/main/java/com/mydreamjob/job/JobService.java mydreamjob-server/src/main/java/com/mydreamjob/job/JobController.java mydreamjob-server/src/test/java/com/mydreamjob/job/JobSearchServiceTest.java mydreamjob-server/src/test/resources/application-test.yml mydreamjob-server/src/test/resources/application-integration-test.yml mydreamjob-server/pom.xml mydreamjob-server/src/main/resources/db/migration/V2__business_schema.sql mydreamjob-server/src/main/resources/db/migration/V22__job_search_indexes.sql ``` 执行: ```powershell rg -n "JobSearchSpecification|findAll\(.*Specification|findWithSalarySort|findPublishedJobs" mydreamjob-server/src ``` 记录哪些现有测试 Mock 了查询层,不能把它们描述成真实过滤覆盖。 ## 四、先写 H2 真实 Repository 测试 新增: ```text mydreamjob-server/src/test/java/com/mydreamjob/job/JobSearchSpecificationIntegrationTest.java ``` 要求: - 激活 `integration-test`; - 使用真实 Flyway、H2、JobRepository; - 不 Mock Repository、Specification、EntityManager 或事务; - 直接调用 `jobRepository.findAll(JobSearchSpecification.searchJobs(...), pageable)`; - 每项断言返回 ID 和顺序; - 测试隔离,不依赖种子岗位; - 不用顺序无关的 containsOnly 代替排序断言。 至少实现以下测试: ```text keywordMatchesTitle keywordMatchesDescription keywordMatchesRequirements keywordIsCaseInsensitive nullBlankAndWhitespaceKeywordDoNotFilter keywordIsTrimmed cityUsesTrimmedExactMatch cityCaseVariantHasSameResultAcrossDatabases employmentTypeUsesTrimmedExactMatch employmentTypeCaseVariantHasSameResultAcrossDatabases companyIdFiltersExactly salaryMinMatchesWhenJobMaximumEqualsBoundary salaryMaxMatchesWhenJobMinimumEqualsBoundary salaryRangesUseOverlapSemantics nonOverlappingSalaryRangeIsExcluded multipleConditionsUseAndSemantics nonPublishedJobsAreAlwaysExcluded specialLikeCharactersFollowExistingContract nullSalaryFieldsFollowExistingContract paginationReturnsStableOrderedIds noResultReturnsEmptyPage ``` 不要为了让测试符合预期而预先修改 `JobSearchSpecification`。如果任何既有语义与设计不一致,保留失败测试并报告。 ## 五、补 Service 真实查询测试 新增: ```text mydreamjob-server/src/test/java/com/mydreamjob/job/JobSearchServiceIntegrationTest.java ``` 使用真实 JobService、JobRepository、CompanyRepository 和 EntityManager,覆盖: ```text latestSortUsesCreatedAtThenIdDescending nullSortUsesLatestOrder relevanceCurrentlyUsesLatestOrder salarySortUsesMaximumDescendingAndNullLast salarySortUsesIdDescendingAsTieBreaker salarySortReturnsCorrectTotalAndTotalPages secondPageDoesNotRepeatOrLoseRows companyInformationIsMappedFromRealRepository searchDoesNotReturnDraftOrClosedJobs ``` 原 `JobSearchServiceTest` 保留,用于参数校验和编排;如需修改注释,只能明确它不是 Specification SQL 覆盖,不得删除或放宽断言。 ## 六、补 MySQL 真实测试 新增建议文件: ```text mydreamjob-server/src/test/java/com/mydreamjob/job/JobSearchSpecificationMySqlIntegrationTest.java ``` 使用已有 `org.testcontainers:mysql` 和 `junit-jupiter`: - MySQL 8.x; - 正式 Flyway; - Hibernate `ddl-auto=validate`; - `@DynamicPropertySource` 注入连接参数; - 不打印密码; - 不复用开发数据库; - 不 Mock 查询路径; - 容器用例至少对账 keyword 大小写、特殊字符、城市、薪资边界、非公开过滤、latest、salary NULL LAST、分页。 可复用参数化场景或夹具构造器,确保 H2/MySQL 输入一致。必须逐项断言结果 ID/业务标识和顺序,而不是只断言数量。 如果普通开发环境 Docker 不可用,可以让 Testcontainers 测试环境性跳过;但最终独立验收必须显式运行该类并得到 Tests run > 0、Skipped=0。不得用 H2 结果代替 MySQL。 ## 七、查询副作用与执行计划 新增测试或独立验收证据证明查询前后以下数据不变: - jobs 稳定业务字段; - companies; - applications; - candidate_dimension_scores; - notifications; - messages; - audit_logs。 使用行级稳定字段快照,不能只比较 COUNT、SUM 或 CRC32。 真实 MySQL 验收对组合过滤、latest、salary 和 count SQL 执行 `EXPLAIN FORMAT=JSON`,记录使用索引、access type、estimated rows、temporary/filesort。Q01 不新增索引;发现性能问题记录给 R01。 ## 八、文档 更新: ```text docs/backend-development-roadmap.md docs/phase1-scope-and-acceptance.md ``` 只记录 Q01 的测试层级和真实结果,不改变接口文档。原则上不修改 `docs/openapi-rc.json`;若仅新增测试却产生 OpenAPI 差异,视为异常并停止调查。 新增最终实施报告建议: ```text docs/q01-job-search-real-query-implementation-report.md ``` 不得写“真实 MySQL 已通过”,除非 Testcontainers 或独立 MySQL 实际运行且核心项无 SKIP。 ## 九、验证顺序 先运行 H2 测试: ```powershell cd C:\Users\15642\Desktop\zhilai\mydreamjob-server mvn -Dtest="JobSearchSpecificationIntegrationTest,JobSearchServiceIntegrationTest" test ``` Docker 可用时运行 MySQL 测试: ```powershell mvn -Dtest="JobSearchSpecificationMySqlIntegrationTest" test ``` 运行岗位关联回归: ```powershell mvn -Dtest="*JobSearch*Test,*Job*Test,*CompanyPublic*Test" test ``` 随后: ```powershell mvn test mvn clean verify python ..\docs\verify_openapi.py ``` 最后: ```powershell cd C:\Users\15642\Desktop\zhilai git diff --check git status --short git diff --cached --name-only git status --short -- mydreamjob-server/src/main/resources/db/migration ``` 要求所有必跑测试 Failures=0、Errors=0、Skipped=0,clean verify 成功,OpenAPI 保持 176/214,暂存区为空,V1–V43 未修改。 ## 十、发现缺陷时 如果真实测试发现生产缺陷: 1. 保留最小失败测试; 2. 记录 H2 与 MySQL 是否一致; 3. 精确写明参数、夹具、预期 ID、实际 ID/顺序和生成 SQL; 4. 不自行修改生产代码; 5. 状态标记为 FAIL,等待负责人下发定向整改指令。 禁止通过修改夹具、删除断言、Mock Repository、禁用测试或放宽为只断言数量来制造绿色。 ## 十一、最终报告 必须包含: 1. 分支与 HEAD; 2. 现有 Mock 测试的真实职责; 3. H2 测试数及结果; 4. MySQL 测试数及结果; 5. 每个过滤条件的实际结果; 6. keyword 三字段、大小写和特殊字符结果; 7. 薪资边界与区间重叠结果; 8. PUBLISHED 强制过滤结果; 9. latest/relevance/salary 排序结果; 10. 分页与 total 结果; 11. H2/MySQL 差异; 12. EXPLAIN 摘要; 13. 数据副作用结果; 14. 关联和全量测试数; 15. Failures/Errors/Skipped; 16. clean verify; 17. OpenAPI paths/operations; 18. 精确修改文件; 19. 是否修改生产代码; 20. 是否新增 Flyway、ErrorCode 或接口; 21. Git 状态; 22. 明确未暂存、未提交、未推送; 23. 是否存在待整改缺陷。 实现和自动化通过后只能写: > Q01 已完成真实查询测试实现与自动化验证,待独立代码复验及真实 MySQL/Docker 验收。