-
Notifications
You must be signed in to change notification settings - Fork 234
Description
Overview
The test file pkg/console/render_test.go has been selected for quality improvement by the Testify Uber Super Expert. This file contains comprehensive tests for the console rendering system but uses zero testify assertions, relying entirely on plain Go error handling. This issue provides specific, actionable recommendations to modernize these tests using testify best practices.
Current State
- Test File:
pkg/console/render_test.go - Source File:
pkg/console/render.go - Test Functions: 15 test functions
- Lines of Code: 519 lines
- Coverage: Good - Most exported functions are tested
- Testify Usage: ❌ ZERO - No testify assertions used
Test Quality Analysis
Strengths ✅
- Comprehensive coverage - Tests cover struct rendering, slice/table rendering, maps, tag parsing, and formatting
- Some table-driven tests exist -
TestParseConsoleTag,TestIsZeroValue,TestFormatFieldValue, andTestFormatNumberalready use table-driven patterns - Good edge case coverage - Tests include nil pointers, empty values, omitempty behavior, and nested structs
Areas for Improvement 🎯
1. Testify Assertions (CRITICAL - Entire File)
Current Issues:
- ZERO testify assertions in the entire 519-line test file
- All tests use plain Go error handling:
t.Error(),t.Errorf() - Many manual string checks using
strings.Contains() - No structured assertions for better error messages
Impact:
- Poor error messages when tests fail
- Harder to debug failures
- Inconsistent with repository standard (see
scratchpad/testing.md) - More verbose code
Recommended Changes:
// ❌ CURRENT (anti-pattern) - From TestRenderStruct_SimpleStruct
if !strings.Contains(output, "Run ID") {
t.Errorf("Output should contain Run ID field, got:\n%s", output)
}
if !strings.Contains(output, "12345") {
t.Error("Output should contain RunID value")
}
if strings.Contains(output, "should not appear") {
t.Error("Output should not contain skipped field")
}
// ✅ IMPROVED (testify)
assert.Contains(t, output, "Run ID", "output should contain Run ID header")
assert.Contains(t, output, "12345", "output should contain RunID value")
assert.NotContains(t, output, "should not appear", "output should not contain skipped field")// ❌ CURRENT - From TestRenderMap
if !strings.Contains(output, "key1") {
t.Error("Output should contain key1")
}
if !strings.Contains(output, "value1") {
t.Error("Output should contain value1")
}
// ✅ IMPROVED
assert.Contains(t, output, "key1", "map output should contain key1")
assert.Contains(t, output, "value1", "map output should contain value1")// ❌ CURRENT - From TestParseConsoleTag (table-driven but no testify)
if result.skip != tt.expected.skip {
t.Errorf("skip: got %v, want %v", result.skip, tt.expected.skip)
}
if result.omitempty != tt.expected.omitempty {
t.Errorf("omitempty: got %v, want %v", result.omitempty, tt.expected.omitempty)
}
// ✅ IMPROVED
assert.Equal(t, tt.expected.skip, result.skip, "skip flag should match")
assert.Equal(t, tt.expected.omitempty, result.omitempty, "omitempty flag should match")
assert.Equal(t, tt.expected.header, result.header, "header value should match")
assert.Equal(t, tt.expected.title, result.title, "title value should match")Why this matters: Testify provides:
- Clearer error messages with actual vs expected values
- Better test output formatting
- Consistent patterns across the codebase
- Less verbose assertion code
2. Import Statement Required
Action Needed:
Add testify import at the top of the test file:
import (
"reflect"
"strings"
"testing"
"github.com/stretchr/testify/assert" // ADD THIS
)3. Specific Test Conversions
Priority High - Most Impactful Conversions:
-
TestRenderStruct_SimpleStruct (lines 32-58)
- Replace 6 manual string checks with
assert.Contains/assert.NotContains
- Replace 6 manual string checks with
-
TestRenderStruct_OmitEmpty (lines 60-89)
- Replace 4 manual string checks with
assert.Contains
- Replace 4 manual string checks with
-
TestRenderSlice_AsTable (lines 91-115)
- Replace 8 manual string checks with
assert.Contains
- Replace 8 manual string checks with
-
TestRenderMap (lines 117-138)
- Replace 8 manual string checks with
assert.Contains
- Replace 8 manual string checks with
-
TestParseConsoleTag (lines 140-210)
- Replace 4 manual equality checks per test case with
assert.Equal - This table-driven test is perfect for testify
- Replace 4 manual equality checks per test case with
-
TestIsZeroValue (lines 212-238)
- Replace manual equality check with
assert.Equal
- Replace manual equality check with
-
TestFormatFieldValue (lines 240-262)
- Replace manual equality check with
assert.Equal
- Replace manual equality check with
-
TestFormatNumber (lines 396-449)
- Replace 41 manual equality checks with
assert.Equal - Add descriptive failure messages
- Replace 41 manual equality checks with
-
TestBuildTableConfig (lines 307-328)
- Replace manual equality checks with
assert.Equalandassert.Len
- Replace manual equality checks with
-
All "Complex Example" tests (lines 264-518)
- Convert all manual string checks to testify assertions
4. Example Full Test Conversion
Before:
func TestRenderStruct_SimpleStruct(t *testing.T) {
data := TestOverview{
RunID: 12345,
Workflow: "test-workflow",
Status: "completed",
EmptyField: "",
SkipField: "should not appear",
}
output := RenderStruct(data)
// Check that basic fields are present
if !strings.Contains(output, "Run ID") {
t.Errorf("Output should contain Run ID field, got:\n%s", output)
}
if !strings.Contains(output, "12345") {
t.Error("Output should contain RunID value")
}
if !strings.Contains(output, "test-workflow") {
t.Error("Output should contain Workflow value")
}
// Check that skip field is not present
if strings.Contains(output, "should not appear") {
t.Error("Output should not contain skipped field")
}
}After (with testify):
func TestRenderStruct_SimpleStruct(t *testing.T) {
data := TestOverview{
RunID: 12345,
Workflow: "test-workflow",
Status: "completed",
EmptyField: "",
SkipField: "should not appear",
}
output := RenderStruct(data)
// Check that basic fields are present (using header names from tags)
assert.Contains(t, output, "Run ID", "output should contain Run ID header from tag")
assert.Contains(t, output, "12345", "output should contain RunID value")
assert.Contains(t, output, "test-workflow", "output should contain Workflow value")
// Check that skip field is not present
assert.NotContains(t, output, "should not appear", "output should not contain skipped field (console:\"-\" tag)")
}Benefits:
- 4 fewer lines of code
- Better error messages on failure
- Consistent with repository patterns
- More readable assertions
Implementation Guidelines
Priority Order
- CRITICAL: Add testify import statement
- HIGH: Convert all manual string checks to
assert.Contains/assert.NotContains(80% of the file) - HIGH: Convert all equality checks to
assert.Equalin table-driven tests - MEDIUM: Add descriptive assertion messages to all assertions
- LOW: Consider using
require.*for critical setup (though this file doesn't have much setup)
Conversion Pattern
For every test function, follow this pattern:
- Add testify import if not present
- Replace
if !strings.Contains(output, X)withassert.Contains(t, output, X, "message") - Replace
if strings.Contains(output, X)withassert.NotContains(t, output, X, "message") - Replace manual equality checks with
assert.Equal(t, expected, actual, "message") - Replace length checks with
assert.Len(t, slice, expectedLen, "message") - Add descriptive messages explaining what's being tested
Best Practices from scratchpad/testing.md
- ✅ Use
assert.*for test validations (this file doesn't needrequire.*) - ✅ Keep existing table-driven tests (they're good!)
- ✅ Always include helpful assertion messages
- ✅ Use
assert.Containsfor substring checks (not manualstrings.Contains) - ✅ Use
assert.Equalfor exact equality (not manual==checks)
Testing Commands
# Run tests for this file
go test -v ./pkg/console/ -run TestRender
# Run specific test
go test -v ./pkg/console/ -run TestRenderStruct_SimpleStruct
# Run with coverage
go test -cover ./pkg/console/
# Run all tests before committing
make test-unitAcceptance Criteria
- Testify import added:
"github.com/stretchr/testify/assert" - All manual
strings.Containschecks replaced withassert.Contains/assert.NotContains - All manual equality checks replaced with
assert.Equal - All manual length checks replaced with
assert.Len - All assertions include descriptive messages
- Tests pass:
go test -v ./pkg/console/ - Full test suite passes:
make test-unit - Code follows patterns in
scratchpad/testing.md
Expected Impact
Before:
- ❌ 0 testify assertions
- ❌ ~60+ manual string checks
- ❌ ~15+ manual equality checks
- ❌ Poor error messages
- ❌ Inconsistent with repository standard
After:
- ✅ 75+ testify assertions
- ✅ Clear, structured error messages
- ✅ Consistent with repository patterns
- ✅ Easier to maintain and extend
- ✅ Better debugging experience
Additional Context
- Repository Testing Guidelines: See
scratchpad/testing.mdfor comprehensive testing patterns - Example Tests: Look at
pkg/workflow/*_test.gofor testify examples (though most use bothassertandrequire) - Testify Documentation: https://github.com/stretchr/testify
This is a high-impact, low-risk refactoring. The test logic is already solid - we're just modernizing the assertions for better developer experience and consistency.
Priority: Medium
Effort: Medium (~2-3 hours to convert all 15 test functions)
Expected Impact: High - Improved test quality, better error messages, easier maintenance
Files Involved:
- Test file:
pkg/console/render_test.go(519 lines, 15 test functions) - Source file:
pkg/console/render.go(2 exported functions, good coverage)
AI generated by Daily Testify Uber Super Expert
- expires on Feb 6, 2026, 11:26 AM UTC