|
| 1 | +# Category A Migration Summary |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +This document summarizes the Category A test migration effort to move parallelizable unit tests from `UnitTests` to `UnitTests.Parallelizable`. |
| 6 | + |
| 7 | +## Tests Migrated: 35 |
| 8 | + |
| 9 | +### Drawing/LineCanvasTests.cs: 31 tests |
| 10 | +**Migrated pure unit tests that don't require Application.Driver:** |
| 11 | +- ToString_Empty (1 test) |
| 12 | +- Clear_Removes_All_Lines (1 test) |
| 13 | +- Lines_Property_Returns_ReadOnly_Collection (1 test) |
| 14 | +- AddLine_Adds_Line_To_Collection (1 test) |
| 15 | +- Constructor_With_Lines_Creates_Canvas_With_Lines (1 test) |
| 16 | +- Viewport_H_And_V_Lines_Both_Positive (7 test cases) |
| 17 | +- Viewport_H_Line (7 test cases) |
| 18 | +- Viewport_Specific (1 test) |
| 19 | +- Bounds_Empty_Canvas_Returns_Empty_Rectangle (1 test) |
| 20 | +- Bounds_Single_Point_Zero_Length (1 test) |
| 21 | +- Bounds_Horizontal_Line (1 test) |
| 22 | +- Bounds_Vertical_Line (1 test) |
| 23 | +- Bounds_Multiple_Lines_Returns_Union (1 test) |
| 24 | +- Bounds_Negative_Length_Line (1 test) |
| 25 | +- Bounds_Complex_Box (1 test) |
| 26 | +- ClearExclusions_Clears_Exclusion_Region (1 test) |
| 27 | +- Exclude_Removes_Points_From_Map (1 test) |
| 28 | +- Fill_Property_Can_Be_Set (1 test) |
| 29 | +- Fill_Property_Defaults_To_Null (1 test) |
| 30 | + |
| 31 | +**Tests that remain in UnitTests as integration tests:** |
| 32 | +- All tests using GetCanvas() and View.Draw() (16 tests) |
| 33 | +- Tests that verify rendered output (ToString with specific glyphs) - these require Application.Driver for glyph resolution |
| 34 | + |
| 35 | +### Drawing/RulerTests.cs: 4 tests |
| 36 | +**Migrated pure unit tests:** |
| 37 | +- Constructor_Defaults |
| 38 | +- Attribute_Set |
| 39 | +- Length_Set |
| 40 | +- Orientation_Set |
| 41 | + |
| 42 | +**Tests that remain in UnitTests as integration tests:** |
| 43 | +- Draw_Default (requires Application.Init with [AutoInitShutdown]) |
| 44 | +- Draw_Horizontal (uses [SetupFakeDriver] - could potentially be migrated) |
| 45 | +- Draw_Vertical (uses [SetupFakeDriver] - could potentially be migrated) |
| 46 | + |
| 47 | +## Key Findings |
| 48 | + |
| 49 | +### 1. LineCanvas and Rendering Dependencies |
| 50 | +**Issue:** LineCanvas.ToString() internally calls GetMap() which calls GetRuneForIntersects(Application.Driver). The glyph resolution depends on Application.Driver for: |
| 51 | +- Configuration-dependent glyphs (Glyphs class) |
| 52 | +- Line intersection character selection |
| 53 | +- Style-specific characters (Single, Double, Heavy, etc.) |
| 54 | + |
| 55 | +**Solution:** Tests using [SetupFakeDriver] CAN be parallelized as long as they don't use Application statics. This includes rendering tests that verify visual output with DriverAssert. |
| 56 | + |
| 57 | +### 2. Test Categories |
| 58 | +Tests fall into three categories: |
| 59 | + |
| 60 | +**a) Pure Unit Tests (CAN be parallelized):** |
| 61 | +- Tests of properties (Bounds, Lines, Length, Orientation, Attribute, Fill) |
| 62 | +- Tests of basic operations (AddLine, Clear, Exclude, ClearExclusions) |
| 63 | +- Tests that don't require Application static context |
| 64 | + |
| 65 | +**b) Rendering Tests with [SetupFakeDriver] (CAN be parallelized):** |
| 66 | +- Tests using [SetupFakeDriver] without Application statics |
| 67 | +- Tests using View.Draw() and LayoutAndDraw() without Application statics |
| 68 | +- Tests that verify visual output with DriverAssert (when using [SetupFakeDriver]) |
| 69 | +- Tests using GetCanvas() helper as long as Application statics are not used |
| 70 | + |
| 71 | +**c) Integration Tests (CANNOT be parallelized):** |
| 72 | +- Tests using [AutoInitShutdown] |
| 73 | +- Tests using Application.Begin, Application.RaiseKeyDownEvent, or other Application static methods |
| 74 | +- Tests that validate component behavior within full Application context |
| 75 | +- Tests that require ConfigurationManager or Application.Navigation |
| 76 | + |
| 77 | +### 3. View/Adornment and View/Draw Tests |
| 78 | +**Finding:** After analyzing these tests, they all use [SetupFakeDriver] and test View.Draw() with visual verification. These are integration tests that validate how adornments render within the View system. They correctly belong in UnitTests. |
| 79 | + |
| 80 | +**Recommendation:** Do NOT migrate these tests. They are integration tests by design and require the full Application/Driver context. |
| 81 | + |
| 82 | +## Test Results |
| 83 | + |
| 84 | +### UnitTests.Parallelizable |
| 85 | +- **Before:** 9,360 tests passing |
| 86 | +- **After:** 9,395 tests passing (+35) |
| 87 | +- **Result:** ✅ All tests pass |
| 88 | + |
| 89 | +### UnitTests |
| 90 | +- **Status:** 3,488 tests passing (unchanged) |
| 91 | +- **Result:** ✅ No regressions |
| 92 | + |
| 93 | +## Recommendations for Future Work |
| 94 | + |
| 95 | +### 1. Continue Focused Migration |
| 96 | + |
| 97 | +**Tests CAN be parallelized if they:** |
| 98 | +- ✅ Test properties, constructors, and basic operations |
| 99 | +- ✅ Use [SetupFakeDriver] without Application statics |
| 100 | +- ✅ Call View.Draw(), LayoutAndDraw() without Application statics |
| 101 | +- ✅ Verify visual output with DriverAssert (when using [SetupFakeDriver]) |
| 102 | +- ✅ Create View hierarchies without Application.Top |
| 103 | +- ✅ Test events and behavior without global state |
| 104 | + |
| 105 | +**Tests CANNOT be parallelized if they:** |
| 106 | +- ❌ Use [AutoInitShutdown] (requires Application.Init/Shutdown global state) |
| 107 | +- ❌ Set Application.Driver (global singleton) |
| 108 | +- ❌ Call Application.Init(), Application.Run/Run<T>(), or Application.Begin() |
| 109 | +- ❌ Modify ConfigurationManager global state (Enable/Load/Apply/Disable) |
| 110 | +- ❌ Modify static properties (Key.Separator, CultureInfo.CurrentCulture, etc.) |
| 111 | +- ❌ Use Application.Top, Application.Driver, Application.MainLoop, or Application.Navigation |
| 112 | +- ❌ Are true integration tests testing multiple components together |
| 113 | + |
| 114 | +**Important Notes:** |
| 115 | +- Many tests blindly use the above when they don't need to and CAN be rewritten |
| 116 | +- Many tests APPEAR to be integration tests but are just poorly written and can be split |
| 117 | +- When in doubt, analyze if the test truly needs global state or can be refactored |
| 118 | + |
| 119 | +### 2. Documentation |
| 120 | +Update test documentation to clarify: |
| 121 | +- **UnitTests** = Integration tests that validate components within Application context |
| 122 | +- **UnitTests.Parallelizable** = Pure unit tests with no global state dependencies |
| 123 | +- Provide examples of each type |
| 124 | + |
| 125 | +### 3. New Test Development |
| 126 | +- Default to UnitTests.Parallelizable for new tests unless they require Application/Driver |
| 127 | +- When testing rendering, create both: |
| 128 | + - Pure unit test (properties, behavior) in Parallelizable |
| 129 | + - Rendering test with [SetupFakeDriver] can also go in Parallelizable (as long as Application statics are not used) |
| 130 | + - Integration test (Application context) in UnitTests |
| 131 | + |
| 132 | +### 4. Remaining Category A Tests |
| 133 | +**Status:** Can be re-evaluated for migration |
| 134 | + |
| 135 | +**Rationale:** |
| 136 | +- View/Adornment/* tests (19 tests): Use [SetupFakeDriver] and test View.Draw() - CAN be migrated if they don't use Application statics |
| 137 | +- View/Draw/* tests (32 tests): Use [SetupFakeDriver] and test rendering - CAN be migrated if they don't use Application statics |
| 138 | +- Need to analyze each test individually to check for Application static dependencies |
| 139 | + |
| 140 | +## Conclusion |
| 141 | + |
| 142 | +This migration successfully identified and moved 52 tests (35 Category A + 17 Views) to UnitTests.Parallelizable. |
| 143 | + |
| 144 | +**Key Discovery:** Tests with [SetupFakeDriver] CAN run in parallel as long as they avoid Application statics. This significantly expands the scope of tests that can be parallelized beyond just property/constructor tests to include rendering tests. |
| 145 | + |
| 146 | +The approach taken was to: |
| 147 | +1. Identify tests that don't use Application.Begin, Application.RaiseKeyDownEvent, Application.Navigation, or other Application static members |
| 148 | +2. Keep [SetupFakeDriver] tests that only use View.Draw() and DriverAssert |
| 149 | +3. Move [AutoInitShutdown] tests only if they can be rewritten to not use Application.Begin |
| 150 | + |
| 151 | +**Migration Rate:** 52 tests migrated so far. Many more tests with [SetupFakeDriver] can potentially be migrated once they're analyzed for Application static usage. Estimated ~3,400 tests remaining to analyze. |
0 commit comments