Refactor iModel.test.ts to avoid tests leaking into each other - #9543
Refactor iModel.test.ts to avoid tests leaking into each other#9543MichaelSwigerAtBentley wants to merge 18 commits into
Conversation
…ike/refactor-imodel-tests
There was a problem hiding this comment.
Pull request overview
This PR refactors the previously monolithic iModel backend unit tests into multiple focused test files and introduces shared fixture helpers to reduce test-state leakage between read/write tests. The refactor aims to ensure read-only tests share stable read-only snapshots while write tests operate on fresh writable copies.
Changes:
- Split iModel tests into dedicated suites (ECSql, Elements, Geolocation, Lifecycle, Metadata, Models, Relationships, Views).
- Added shared test-fixture helpers for creating isolated writable snapshots and common error/assert utilities.
- Updated per-suite setup/teardown patterns to close mutable iModels after each test and keep shared read-only snapshots open once per file.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| core/backend/src/test/imodel/IModelECSql.test.ts | ECSQL/SQL tests moved into their own suite with shared read-only fixtures and per-test writable snapshots where needed. |
| core/backend/src/test/imodel/IModelElements.test.ts | Element CRUD/behavior tests isolated via per-test writable snapshots and shared read-only snapshots. |
| core/backend/src/test/imodel/IModelGeolocation.test.ts | Geolocation tests isolated and retain backend restart behavior for GCS workspace loading. |
| core/backend/src/test/imodel/IModelLifecycle.test.ts | Lifecycle tests moved into dedicated suite using shared fixture helpers for error assertions. |
| core/backend/src/test/imodel/IModelMetadata.test.ts | Metadata/schema tests split out and updated to use shared fixture helpers and snapshot lifecycle management. |
| core/backend/src/test/imodel/IModelModels.test.ts | Model tests split out and updated to use shared fixture helpers and snapshot lifecycle management. |
| core/backend/src/test/imodel/IModelRelationships.test.ts | Relationship tests split out; writable-seed tests use per-test generated snapshots for isolation. |
| core/backend/src/test/imodel/IModelViews.test.ts | View tests split out; write tests use fresh writable copies while read-only tests share a read-only snapshot. |
| core/backend/src/test/imodel/IModelTestFixtures.ts | New shared helper module for snapshot creation, error assertion helpers, and JSON roundtrip helper. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
…/itwinjs-core into mike/refactor-imodel-tests
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
hl662
left a comment
There was a problem hiding this comment.
seems like you need a rush change, its refactoring tests so you can leave an empty changelog message.
( You can resolve my comments yourself when you're done)
…/itwinjs-core into mike/refactor-imodel-tests
Code Review: #9543 — Refactor iModel.test.ts to avoid tests leaking into each otherTL;DR / VerdictRequest changes (minor scope). The direction is right and overdue: a 3,728-line monolith with 5 process-wide shared iModels becomes 8 focused files with per-test isolation, and all 79 tests survive (verified by title + body diff). But the execution leaves a 14-line fixture block copy-pasted into 5 files, ships a dead exported helper, and the PR description ("Tests were not changed") is false — at least three test bodies changed semantics, one of which is an undisclosed assertion fix and one of which makes a "random" test not random. ArchitecturePros
Cons
SecurityNo issues found. This is test-only code: no untrusted input, no new deps, no secrets. TypeScript
Correctness — undisclosed behavior changesThe description says "Tests were not changed, just the before and after, and the file structure." I diffed all 79 bodies with mechanical renames normalized. Most changes are indeed pure rebinding, but these are not:
One thing to verify before merge: the original ran the entire suite under Other / Non-TS FilesNone. No Blocking Issues
Nits
Pros & Cons Summary
Mecha-Mike using Opus 5 |
| assert.isTrue(await getRelationshipCount(testImodel, "BisCore.ElementRefersToDocuments") >= Math.floor(relationships.length / 3)); | ||
|
|
||
| // Select a deterministic, unique subset (every 4th relationship => 250 unique entries) | ||
| // so the test is stable, reproducible, and free of duplicate delete requests. |
There was a problem hiding this comment.
Could we keep this deterministic without removing duplicate-input coverage? The old sampling was with replacement, so it almost always passed repeated relationship entries in the same deleteRelationships call. That exercised the batch/native boundary with duplicate IDs; the new unique stride removes the only backend coverage I could find for that case.
Smallest fix: keep the deterministic subset, but intentionally replace one selected entry with a duplicate (or add a focused duplicate-input test). The test name should also drop “random” once the selection is deterministic.
Refactors the monolith iModel test file into 8 separate files:
Previously, iModel test reused 5 opened-once imodels accross all of the tests, leading to cases where write tests could bleed into other tests causing failures if tests were ran in isolation. This refactors the test file such that:
• Read-only tests share one per-file read-only snapshot that is only opened once
• write tests each get a fresh writable copy
Tests were not changed, just the before and after, and the file structure. A pass should probably be done on the tests as well, but for now I will save that for another PR.
Separating the tests like this only leads to a ~5% performance loss (extra time to copy the baselines), in my testing test times went from avg 20s to 21s