8.6 KiB
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;禁止删除或移动历史未跟踪文件。
二、开始前核查
执行:
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;当前基线未发现时记录“未发现”。
三、必须阅读
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
执行:
rg -n "JobSearchSpecification|findAll\(.*Specification|findWithSalarySort|findPublishedJobs" mydreamjob-server/src
记录哪些现有测试 Mock 了查询层,不能把它们描述成真实过滤覆盖。
四、先写 H2 真实 Repository 测试
新增:
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 代替排序断言。
至少实现以下测试:
keywordMatchesTitle
keywordMatchesDescription
keywordMatchesRequirements
keywordIsCaseInsensitive
nullBlankAndWhitespaceKeywordDoNotFilter
keywordIsTrimmed
cityUsesTrimmedExactMatch
cityCaseVariantHasSameResultAcrossDatabases
employmentTypeUsesTrimmedExactMatch
employmentTypeCaseVariantHasSameResultAcrossDatabases
companyIdFiltersExactly
salaryMinMatchesWhenJobMaximumEqualsBoundary
salaryMaxMatchesWhenJobMinimumEqualsBoundary
salaryRangesUseOverlapSemantics
nonOverlappingSalaryRangeIsExcluded
multipleConditionsUseAndSemantics
nonPublishedJobsAreAlwaysExcluded
specialLikeCharactersFollowExistingContract
nullSalaryFieldsFollowExistingContract
paginationReturnsStableOrderedIds
noResultReturnsEmptyPage
不要为了让测试符合预期而预先修改 JobSearchSpecification。如果任何既有语义与设计不一致,保留失败测试并报告。
五、补 Service 真实查询测试
新增:
mydreamjob-server/src/test/java/com/mydreamjob/job/JobSearchServiceIntegrationTest.java
使用真实 JobService、JobRepository、CompanyRepository 和 EntityManager,覆盖:
latestSortUsesCreatedAtThenIdDescending
nullSortUsesLatestOrder
relevanceCurrentlyUsesLatestOrder
salarySortUsesMaximumDescendingAndNullLast
salarySortUsesIdDescendingAsTieBreaker
salarySortReturnsCorrectTotalAndTotalPages
secondPageDoesNotRepeatOrLoseRows
companyInformationIsMappedFromRealRepository
searchDoesNotReturnDraftOrClosedJobs
原 JobSearchServiceTest 保留,用于参数校验和编排;如需修改注释,只能明确它不是 Specification SQL 覆盖,不得删除或放宽断言。
六、补 MySQL 真实测试
新增建议文件:
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。
八、文档
更新:
docs/backend-development-roadmap.md
docs/phase1-scope-and-acceptance.md
只记录 Q01 的测试层级和真实结果,不改变接口文档。原则上不修改 docs/openapi-rc.json;若仅新增测试却产生 OpenAPI 差异,视为异常并停止调查。
新增最终实施报告建议:
docs/q01-job-search-real-query-implementation-report.md
不得写“真实 MySQL 已通过”,除非 Testcontainers 或独立 MySQL 实际运行且核心项无 SKIP。
九、验证顺序
先运行 H2 测试:
cd C:\Users\15642\Desktop\zhilai\mydreamjob-server
mvn -Dtest="JobSearchSpecificationIntegrationTest,JobSearchServiceIntegrationTest" test
Docker 可用时运行 MySQL 测试:
mvn -Dtest="JobSearchSpecificationMySqlIntegrationTest" test
运行岗位关联回归:
mvn -Dtest="*JobSearch*Test,*Job*Test,*CompanyPublic*Test" test
随后:
mvn test
mvn clean verify
python ..\docs\verify_openapi.py
最后:
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 未修改。
十、发现缺陷时
如果真实测试发现生产缺陷:
- 保留最小失败测试;
- 记录 H2 与 MySQL 是否一致;
- 精确写明参数、夹具、预期 ID、实际 ID/顺序和生成 SQL;
- 不自行修改生产代码;
- 状态标记为 FAIL,等待负责人下发定向整改指令。
禁止通过修改夹具、删除断言、Mock Repository、禁用测试或放宽为只断言数量来制造绿色。
十一、最终报告
必须包含:
- 分支与 HEAD;
- 现有 Mock 测试的真实职责;
- H2 测试数及结果;
- MySQL 测试数及结果;
- 每个过滤条件的实际结果;
- keyword 三字段、大小写和特殊字符结果;
- 薪资边界与区间重叠结果;
- PUBLISHED 强制过滤结果;
- latest/relevance/salary 排序结果;
- 分页与 total 结果;
- H2/MySQL 差异;
- EXPLAIN 摘要;
- 数据副作用结果;
- 关联和全量测试数;
- Failures/Errors/Skipped;
- clean verify;
- OpenAPI paths/operations;
- 精确修改文件;
- 是否修改生产代码;
- 是否新增 Flyway、ErrorCode 或接口;
- Git 状态;
- 明确未暂存、未提交、未推送;
- 是否存在待整改缺陷。
实现和自动化通过后只能写:
Q01 已完成真实查询测试实现与自动化验证,待独立代码复验及真实 MySQL/Docker 验收。