# Testing Strategies to Validate Go Modern Guidelines Across Different Go Versions

> Validate Go modern guidelines across Go versions with a multi-layered test suite. Discover version-aware filtering, Go version resolution, and JSON schema validation strategies.

- Repository: [JetBrains/go-modern-guidelines](https://github.com/jetbrains/go-modern-guidelines)
- Tags: testing-strategies
- Published: 2026-08-30

---

**The JetBrains/go-modern-guidelines repository validates guideline correctness through a multi-layered test suite that combines version-aware filtering, robust Go version resolution, and strict JSON schema validation.**

The `go-modern-guidelines` project maintains a curated set of best practices that evolve with each Go release. To ensure recommendations remain accurate across Go 1.24 through 1.27 and beyond, the repository implements comprehensive **testing strategies** that verify guideline applicability, version detection logic, and data integrity. These tests guarantee that developers receive only relevant advice when running the tool against different Go versions.

## Version-Aware Guideline Selection

The core challenge involves determining which guidelines apply to a specific Go version. The repository solves this through dynamic filtering backed by rigorous unit tests.

### Filtering by Target Version

In [`internal/guidelines/guidelines.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines.go), the `supportedGuidelines` function uses `goversion.Compare` to filter the embedded `modernGoGuidelines` slice. This ensures only guidelines with `SinceVersion ≤ targetVersion` are included in results.

The test file [`internal/guidelines/guidelines_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines_test.go) contains `TestListForResolvedVersion` and `TestListForGo127`, which verify that `ListText` returns a newest-first list for requested versions like `1.26` and `1.27`. These tests assert that older guidelines never appear before newer ones, maintaining the expected priority order.

### Validating Version Constraints

The selection logic handles edge cases where guidelines introduce breaking changes or deprecations. Tests confirm that when a user targets Go 1.25, they do not see guidelines requiring Go 1.26 features, while users on Go 1.27 receive the complete applicable set.

## Robust Go Version Resolution

Accurate guideline selection depends on correctly identifying the active Go version from diverse sources, including module files and environment strings.

### Normalizing Diverse Version Strings

The [`internal/goversion/goversion.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/goversion/goversion.go) file implements normalization and comparison logic that handles inputs like `1.24`, `go1.24.3`, `Go1.25`, and the special `devel` identifier with user-supplied fallbacks.

Tests in [`internal/goversion/goversion_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/goversion/goversion_test.go) cover:

- **Normalization**: Converting various prefix formats to canonical versions
- **Comparison semantics**: Handling major/minor boundaries correctly (e.g., `1.9` vs `1.10`, `2.0` vs `1.99`)
- **Format detection**: Validating `IsMajorMinor` checks

### Resolving from Module Files

The `Resolve` function extracts the `go` directive from `go.mod` and `go.work` files, including error handling for malformed directives. The `TestResolveFromNearestGoMod` test simulates temporary module hierarchies to confirm that the nearest `go.mod` influences version resolution correctly.

```go
// Resolve the Go version for a source file, falling back to the local toolchain.
v, err := goversion.Resolve("path/to/file.go", "", "1.27")
if err != nil {
    log.Fatal(err)
}
fmt.Println("Using Go version:", v) // → e.g. "1.26"

```

## Schema Validation for Guideline Integrity

Guidelines are stored as JSON and parsed by the `schema` package. Strict validation prevents corrupted or inconsistent data from reaching users.

### Enforcing Field Constraints

The [`internal/guidelines/schema/schema_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/schema/schema_test.go) suite includes `TestParseValidGuidelines` and `TestParseRejectsInvalidGuideline`, which check:

- Rejection of unsafe IDs
- Validation of major/minor version formats
- Presence of required modernizer flags
- Non-empty text fields

### Detecting Structural Violations

Additional tests verify ordering constraints and uniqueness:

- `TestParseRejectsDuplicateIDs` ensures no two guidelines share the same identifier
- Ordering validation confirms guidelines remain sorted newest-first
- Error messages are asserted to contain clear diagnostics for rapid debugging

```go
// Parse and validate a new guideline definition.
data := []byte(`[{"id":"example","since_version":"1.28","modernizer":true,"category":"Security","impact":"High","guideline":"Use x","details":"Details","examples":[{"before":["old"],"after":["new"]}]}]`)
guidelines, err := schema.Parse(data)
if err != nil {
    log.Fatalf("invalid guideline: %v", err)
}
fmt.Printf("Loaded %d guideline(s)\n", len(guidelines))

```

## Integration and CLI Safeguards

Beyond core logic, the test suite protects against documentation drift and command-line ambiguity.

### Documentation Synchronization

The [`internal/guidelines/featuresgen/main_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/featuresgen/main_test.go) file contains `TestFeaturesMarkdownInSync`, which regenerates [`FEATURES.md`](https://github.com/JetBrains/go-modern-guidelines/blob/main/FEATURES.md) from [`guidelines.json`](https://github.com/JetBrains/go-modern-guidelines/blob/main/guidelines.json) and verifies byte-for-byte equality. This prevents documentation from describing features that no longer exist or omitting newly added guidelines.

### CLI Argument Validation

The [`internal/cli/cli_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/cli/cli_test.go) suite confirms that conflicting version-source flags are rejected, preventing ambiguous version resolution. These tests ensure users cannot simultaneously specify a version via `--go-version` and `--go-mod-path` without clear precedence rules.

```go
// List the guidelines that apply to Go 1.27 or newer.
fmt.Println(guidelines.ListText("1.27"))
// Output (truncated):
// generic_methods: Use generic methods instead of package-level helpers.
// promoted_field_literals: Set embedded struct fields directly …

```

## Summary

The repository employs a defense-in-depth approach to **testing strategies that validate guideline correctness across different Go versions**:

- **Version-aware selection** filters guidelines using `goversion.Compare` in `supportedGuidelines`, verified by [`guidelines_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/guidelines_test.go)
- **Version resolution** normalizes diverse version strings and extracts values from `go.mod`/`go.work`, tested in [`goversion_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/goversion_test.go)
- **Schema integrity** enforces strict JSON validation through [`schema_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/schema_test.go), catching duplicates and malformed entries
- **Documentation sync** via [`featuresgen/main_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/featuresgen/main_test.go) ensures [`FEATURES.md`](https://github.com/JetBrains/go-modern-guidelines/blob/main/FEATURES.md) reflects the actual guideline set
- **CLI robustness** in [`cli_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/cli_test.go) prevents ambiguous version-source configurations

## Frequently Asked Questions

### How does the repository determine which Go version to use for validation?

The `goversion.Resolve` function in [`internal/goversion/goversion.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/goversion/goversion.go) checks multiple sources in priority order: explicit CLI flags, the nearest `go.mod` or `go.work` file, and finally the local toolchain. Tests in `TestResolveFromNearestGoMod` verify this hierarchy using temporary module hierarchies.

### What prevents invalid guideline definitions from being merged?

The [`schema_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/schema_test.go) suite validates every field in [`guidelines.json`](https://github.com/JetBrains/go-modern-guidelines/blob/main/guidelines.json) through tests like `TestParseRejectsInvalidGuideline`. These catch unsafe IDs, non-conforming version strings, missing modernizer flags, and empty text fields before they reach production.

### How are version strings like "go1.24.3" or "devel" handled during testing?

[`goversion_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/goversion_test.go) includes `TestNormalizeGoVersion` cases that strip prefixes (e.g., "go", "Go"), handle patch versions, and substitute fallbacks for the special `devel` identifier. Comparison tests verify correct ordering across major and minor boundaries.

### Where are the tests for CLI version-source conflicts located?

Argument Validation logic resides in [`internal/cli/cli_test.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/cli/cli_test.go), which ensures mutually exclusive flags (such as specifying both a direct version and a module file path) trigger clear errors, preventing ambiguous resolution behavior.