-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnotes_gemini
More file actions
41 lines (31 loc) · 4.86 KB
/
notes_gemini
File metadata and controls
41 lines (31 loc) · 4.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Prompt (@7d06a28):
My next steps are to express how proper decomposition of code leads to large improvements in testability. What's most interesting about that is one ends up with a portion of code which is nicely testable, with the remaining portion need really needing testing. That is, a junction or a handler are somewhat odd to test directly. Well-decomposed code results in less tests, yet greater robustness. And any such "odd to test" areas can then be consciously moved into the "end-to-end test it" pile.
Response:
Okay, that's an excellent and crucial point to articulate. Connecting the "Decomp" philosophy directly to testability highlights one of its most significant practical benefits. Here's a way to frame that argument, incorporating the "Decomp" concepts:
---
**Connecting Decomposition ("Decomp") to Enhanced Testability**
A core principle underlying the "Decomp" approach is that breaking down behavior and data into units with clear purpose directly leads to vastly improved testability. This isn't just about making testing *possible*; it fundamentally changes the testing strategy, often resulting in fewer, more robust tests that provide greater confidence.
1. **Isolating the "Testable Core":**
* When you decompose logic rigorously, you naturally isolate the parts of your code that contain complex transformations, calculations, or specific business rules. In "Decomp" terms, these often manifest as:
* **Seclusions (Subhandlers):** Functions broken out specifically to encapsulate a distinct piece of logic (e.g., validating input, calculating a result, formatting output).
* **Constructions (Calculators, specific Getters):** Functions focused solely on creating or deriving a value based on inputs.
* **Articulations (Closures):** The core logic encapsulated within the returned function.
* These isolated units are prime candidates for **Unit Testing**. They often have fewer external dependencies (or dependencies that are easily mocked) and a clear set of inputs and expected outputs. Testing these units thoroughly provides high confidence in the correctness of the core logic.
2. **Identifying the "Orchestration Layer":**
* The remaining code often serves primarily to connect and orchestrate these core units. This includes:
* **Expositions (Handlers):** Functions whose main job is to receive a request, call one or more "Seclusions" or other functions, and format a response. Their own logic might be minimal.
* **Junctions (Multiplexers):** Functions whose primary role is to inspect input(s) and route control flow to the appropriate handler or function.
* Directly unit testing these orchestrators can be awkward and less valuable. Why?
* They often require extensive mocking of the units they call (the "Seclusions").
* Such tests can become brittle – changes in the Seclusion might require changes in the Handler's mock setup, even if the Handler's own logic didn't change.
* The test often ends up verifying the mocking framework more than the orchestration logic itself.
3. **The Result: Fewer, Better Tests & Conscious Test Strategy:**
* By focusing unit tests on the well-defined "Seclusions" and "Constructions," you test the complex logic thoroughly at its source.
* You consciously *reduce* the need for complex, mock-heavy unit tests on the "Expositions" and "Junctions."
* This doesn't mean the orchestration layer goes untested! Instead, the responsibility for verifying that these parts correctly integrate the core units is **shifted** to higher-level tests:
* **Surface Tests:** Verify the public interface of a component (e.g., does calling the `HandleHello` function *actually* result in the correct output, implicitly testing that it called the right `PrintHello` Seclusion?). These test the integration of the Handler and its Seclusions.
* **System Tests / End-to-End Tests:** Verify complete user flows, ensuring that the routing ("Junctions") and handling ("Expositions") work together correctly from an external perspective.
* This leads to a more efficient and effective testing pyramid: a solid base of focused unit tests for core logic, and integration/system tests verifying the connections. You achieve greater robustness, often with *fewer total tests*, because you avoid redundant testing of the same logic through multiple layers of mocks.
**In essence:** Proper decomposition, as encouraged by frameworks like "Decomp," allows you to consciously separate *logic that needs isolated unit testing* from *logic that primarily orchestrates and needs integration testing*. This targeted approach makes testing easier, more robust, and more maintainable.
Personal Notes:
I had not asked Gemini for a specific type of response, but appreciate the perspective it shared. This is being stored for reference (some of these passages are conveyed more accessibly than what I might produce).