Skip to content

Add Parallel() option for SubTest()#20

Merged
jbsmith7741 merged 1 commit intomainfrom
parallel
Jan 30, 2026
Merged

Add Parallel() option for SubTest()#20
jbsmith7741 merged 1 commit intomainfrom
parallel

Conversation

@jbsmith7741
Copy link
Member

@jbsmith7741 jbsmith7741 commented Jan 27, 2026

PR Type

Enhancement


Description

  • Add Parallel() method to enable concurrent subtest execution

  • Implement parallel execution in SubTest() with proper loop variable capture

  • Add comprehensive tests for parallel functionality and method chaining

  • Update documentation with parallel execution examples and best practices


Diagram Walkthrough

flowchart LR
  Trial["Trial struct"] -->|"add parallel field"| ParallelMethod["Parallel() method"]
  ParallelMethod -->|"enables"| SubTestExec["SubTest() execution"]
  SubTestExec -->|"calls tb.Parallel()"| ConcurrentRun["Concurrent test runs"]
  Trial -->|"loop variable capture"| GoCompat["Go <1.22 compatibility"]
Loading

File Walkthrough

Relevant files
Enhancement
trial.go
Add parallel execution support to Trial                                   

trial.go

  • Add parallel boolean field to Trial struct
  • Implement Parallel() method that sets the parallel flag and returns
    the Trial for chaining
  • Modify SubTest() to capture loop variables for Go <1.22 compatibility
  • Call tb.Parallel() in subtests when parallel flag is enabled
+17/-4   
Tests
trial_test.go
Add tests for parallel execution feature                                 

trial_test.go

  • Add TestParallel() to verify parallel execution with multiple test
    cases
  • Add TestParallel_Chaining() to test method chaining with Parallel,
    Timeout, and Comparer
  • Both tests verify correct behavior and return value of Parallel()
    method
+40/-0   
Documentation
README.md
Document parallel execution feature                                           

README.md

  • Add parallel execution feature to feature list with example usage
  • Update main description to mention .Parallel() option for faster test
    execution
  • Include note about thread-safety requirement for parallel tests
+3/-1     
api.md
Update API documentation with Parallel method                       

docs/api.md

  • Add .Parallel() method to API reference table
  • Include description that it enables parallel execution for subtests
+1/-0     
examples.md
Add comprehensive parallel execution documentation             

docs/examples.md

  • Add "Parallel Execution" section to table of contents
  • Provide detailed explanation of parallel execution with thread-safety
    warnings
  • Include practical example with I/O-bound HTTP tests
  • Show method chaining example combining Parallel with Timeout and
    Comparer
  • Add note that Parallel() only works with SubTest(), not Test()
+51/-0   

@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Parallel race risk: Enabling tb.Parallel() can run t.testCase(msg, test) concurrently across cases and may
introduce data races or shared-state issues if Trial or case execution mutates shared
state, which is not verifiable from the diff.

Referred Code
for msg, test := range t.cases {
	msg, test := msg, test // capture loop variables for parallel execution (Go <1.22)
	tst.(*testing.T).Run(msg, func(tb *testing.T) {
		tb.Helper()
		if t.parallel {
			tb.Parallel()
		}
		r := t.testCase(msg, test)

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Use *testing.T parameter directly

*Modify the SubTest function to accept a testing.T parameter directly, instead
of testing.TB, to avoid an unsafe type cast that could cause a panic.

trial.go [94-114]

-func (t *Trial[In, Out]) SubTest(tst testing.TB) {
-  if h, ok := tst.(tHelper); ok {
-    h.Helper()
-  }
+func (t *Trial[In, Out]) SubTest(tb *testing.T) {
+  tb.Helper()
 
   for msg, test := range t.cases {
-    msg, test := msg, test // capture loop variables for parallel execution (Go <1.22)
-    tst.(*testing.T).Run(msg, func(tb *testing.T) {
+    msg, test := msg, test // capture loop variables for parallel execution
+    tb.Run(msg, func(tb *testing.T) {
       tb.Helper()
       if t.parallel {
         tb.Parallel()
       }
       r := t.testCase(msg, test)
       ...
     })
   }
 }

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a potential runtime panic caused by an unsafe type assertion from testing.TB to *testing.T and proposes a valid fix that improves type safety and robustness.

Medium
Possible issue
Assert actual parallel execution

In TestParallel, measure the total execution time to verify that the subtests
actually run in parallel, asserting that the elapsed time is less than the sum
of the individual test delays.

trial_test.go [321-342]

 func TestParallel(t *testing.T) {
   fn := func(in int) (int, error) {
-    time.Sleep(10 * time.Millisecond) // small delay to verify parallelism
+    time.Sleep(10 * time.Millisecond)
     return in * 2, nil
   }
 
   cases := map[string]Case[int, int]{
     "double 1": {Input: 1, Expected: 2},
     "double 2": {Input: 2, Expected: 4},
     "double 3": {Input: 3, Expected: 6},
     "double 4": {Input: 4, Expected: 8},
   }
 
-  // Test that Parallel() returns the Trial for chaining
   tr := New(fn, cases).Parallel()
   if tr == nil {
     t.Fatal("Parallel() should return the Trial")
   }
 
-  // Test that parallel subtests execute correctly
+  start := time.Now()
   tr.SubTest(t)
+  elapsed := time.Since(start)
+  if elapsed > 30*time.Millisecond {
+    t.Errorf("expected parallel execution but took %v", elapsed)
+  }
 }
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly points out that the test for parallel execution does not actually verify parallelism. The proposed change to measure execution time makes the test more robust and meaningful.

Medium
  • More

@jbsmith7741 jbsmith7741 merged commit aad618b into main Jan 30, 2026
16 checks passed
@jbsmith7741 jbsmith7741 deleted the parallel branch January 30, 2026 22:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant