quii/learn-go-with-tests
Learn Go with test-driven development
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓66+ active contributors
- ✓Distributed ownership (top contributor 12% of recent commits)
Show 3 more →Show less
- ✓MIT licensed
- ✓CI configured
- ✓Tests present
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/quii/learn-go-with-tests)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/quii/learn-go-with-tests on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: quii/learn-go-with-tests
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/quii/learn-go-with-tests shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit today
- 66+ active contributors
- Distributed ownership (top contributor 12% of recent commits)
- MIT licensed
- CI configured
- Tests present
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live quii/learn-go-with-tests
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/quii/learn-go-with-tests.
What it runs against: a local clone of quii/learn-go-with-tests — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in quii/learn-go-with-tests | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of quii/learn-go-with-tests. If you don't
# have one yet, run these first:
#
# git clone https://github.com/quii/learn-go-with-tests.git
# cd learn-go-with-tests
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of quii/learn-go-with-tests and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "quii/learn-go-with-tests(\\.git)?\\b" \\
&& ok "origin remote is quii/learn-go-with-tests" \\
|| miss "origin remote is not quii/learn-go-with-tests (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "README.md" \\
&& ok "README.md" \\
|| miss "missing critical file: README.md"
test -f "SUMMARY.md" \\
&& ok "SUMMARY.md" \\
|| miss "missing critical file: SUMMARY.md"
test -f "arrays/v1/sum.go" \\
&& ok "arrays/v1/sum.go" \\
|| miss "missing critical file: arrays/v1/sum.go"
test -f "command-line/v1/server.go" \\
&& ok "command-line/v1/server.go" \\
|| miss "missing critical file: command-line/v1/server.go"
test -f "blogrenderer/renderer.go" \\
&& ok "blogrenderer/renderer.go" \\
|| miss "missing critical file: blogrenderer/renderer.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/quii/learn-go-with-tests"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
A free, open-source Go learning curriculum structured around test-driven development (TDD), featuring ~514KB of runnable Go code organized in progressive chapters from hello-world through concurrency. Each chapter pairs markdown documentation with versioned example code (v1–v8 in directories like arrays/, blogrenderer/) that teaches Go fundamentals by writing tests first, then implementation. Curriculum monorepo: top-level markdown files (hello-world.md, integers.md, arrays-and-slices.md, structs-methods-and-interfaces.md, etc.) correspond to learning chapters; each chapter has a sibling directory (arrays/, blogrenderer/) containing versioned example code (v1/–v8/) with *_test.go files alongside implementation files. Assets live in .gitbook/assets/. This structure makes it easy to follow a chapter while referencing runnable, tested code at each step.
👥Who it's for
Go beginners and developers transitioning from other languages who want to learn Go syntax and idioms through hands-on TDD practice. Also serves instructors and mentors looking for a structured, self-paced curriculum with proven pedagogical order (variables → loops → structs → interfaces → concurrency).
🌱Maturity & risk
Actively maintained and pedagogically mature: the repo has 514KB of well-organized Go code, GitHub Actions CI/CD (go.yml), GitBook integration for professional documentation, and community translations into 10+ languages (中文, 日本語, Français, 한국어, etc.). High educational credibility but not a production library—it's a teaching resource that has proven effective across multiple language communities.
Standard open source risks apply.
Active areas of work
No recent commits visible in provided metadata; the repo appears in a stable, feature-complete state as an educational resource. GitHub Actions CI is configured to run Go tests (go.yml), suggesting ongoing verification that code examples compile and pass tests. No active development roadmap visible, but the curriculum remains current for Go 1.24 (per go.mod).
🚀Get running
Clone and navigate: git clone https://github.com/quii/learn-go-with-tests.git && cd learn-go-with-tests. Open README.md or SUMMARY.md to find your starting chapter. For example, to run the hello-world tests: cd hello-world && go test -v ./... (or navigate to a chapter directory like cd arrays/v1 && go test ./... to run tests for that lesson version).
Daily commands:
Each chapter directory is independently runnable. Example: cd arrays/v1 && go test -v executes that lesson's tests. To run the full test suite: go test ./... from repo root. No build step, no server to start—this is a pure learning resource. View the curriculum by opening README.md or the GitBook link: https://quii.gitbook.io/learn-go-with-tests.
🗺️Map of the codebase
README.md— Entry point documenting the TDD learning curriculum structure, formats, and translations—essential for understanding the repo's educational mission.SUMMARY.md— GitBook table of contents defining the lesson progression and module organization—critical for navigating the codebase structure.arrays/v1/sum.go— First practical example in the curriculum demonstrating basic Go syntax and test-driven development patterns.command-line/v1/server.go— Core HTTP server implementation showing intermediate TDD patterns and dependency injection—a major learning module.blogrenderer/renderer.go— Advanced template rendering example demonstrating interface-driven design and functional composition in Go..github/workflows/go.yml— CI/CD pipeline configuration ensuring all lessons and examples remain executable and correct.go.mod— Module declaration defining dependencies (approval tests, markdown, websockets) required for advanced lessons.
🛠️How to make changes
Add a new lesson chapter to the curriculum
- Create a new markdown file in the repo root (e.g., pointers.md) with the lesson narrative (
pointers.md) - Add an entry in SUMMARY.md under the appropriate section with the file path and display title (
SUMMARY.md) - Create a corresponding folder (e.g., pointers/) with v1, v2, etc. subdirectories for progressive examples (
pointers/v1/) - Implement the example Go code (e.g., pointers/v1/example.go) and test file (e.g., pointers/v1/example_test.go) (
pointers/v1/example_test.go) - Ensure CI passes by running 'go test ./...' locally to validate all examples execute correctly (
.github/workflows/go.yml)
Add a new progressive example version to an existing module
- Copy the previous version folder (e.g., cp -r arrays/v7 arrays/v8) as a starting point (
arrays/v8/) - Refactor the implementation in the .go file to teach a new concept while keeping tests passing (
arrays/v8/sum.go) - Update the test file to include new test cases covering the refactored behavior (
arrays/v8/sum_test.go) - Update the lesson markdown file (e.g., arrays-and-slices.md) to explain the changes and when to use this pattern (
arrays-and-slices.md) - Run 'go test ./arrays/v8/...' to ensure the new version passes all tests (
.github/workflows/go.yml)
Add a new approval-tested template rendering example
- Create a new struct and renderer function in (e.g., blogrenderer/widget.go) to process domain data (
blogrenderer/widget.go) - Create a new Go HTML template file in blogrenderer/templates/ (e.g., widget.gohtml) with desired output format (
blogrenderer/templates/widget.gohtml) - Write a test in renderer_test.go that calls the renderer and uses Approve() to capture the output (
blogrenderer/renderer_test.go) - Run the test once to generate the .approved.txt file, review it, and commit it as the golden reference (
blogrenderer/renderer_test.TestRender.it_renders_a_widget.approved.txt) - Future test runs will fail if output diverges from the approved file, ensuring correctness (
.github/workflows/go.yml)
🔧Why these technologies
- Go 1.24 — The language being taught; ensures all examples are idiomatic and compatible with current Go releases.
- GitBook — Provides structured, searchable, multi-format (HTML, EPUB, PDF) documentation ideal for a learning resource.
- GitHub Actions (go.yml) — Validates all examples compile and tests pass on every commit, maintaining quality of the curriculum.
- approval-tests — Golden-file testing pattern for complex outputs (HTML templates) without fragile string assertions.
- go-markdown & gorilla/websocket — Optional dependencies for advanced lessons on markdown rendering and real-time communication patterns.
⚖️Trade-offs already made
-
Progressive versioning (v1, v2, v3) per module rather than single-file refactoring
- Why: Allows learners to see incremental improvements and compare historical code patterns.
- Consequence: Increases number of files but improves pedagogical clarity and avoids merge conflict anxiety.
-
Repository contains both lesson markdown and executable code examples
- Why: Keeps code and narrative synchronized; examples are always up-to-date with lessons.
- Consequence: Single repository must serve dual purposes (documentation + code examples), increasing CI scope.
-
Use Go standard library for most examples (no heavy frameworks)
- Why: Teaches foundational patterns and idioms rather than framework-specific patterns.
- Consequence: Some real-world patterns (ORM, logging) not demonstrated; learners must extrapolate.
-
Approval testing with golden files instead of assertion libraries
- Why: Makes large outputs (HTML, JSON) human-reviewable; catches unintended changes visually.
- Consequence: Requires commitment discipline: approving new golden files is a deliberate, tracked action.
🚫Non-goals (don't propose these)
- Real-time collaborative learning platform (GitBook is static documentation).
- Supporting Go versions below 1.24; cutting-edge language features only.
- Teaching frameworks or third-party libraries extensively (focus is on stdlib idioms).
- Providing automated grading or progress tracking of learner code.
- Covering advanced topics like low-level systems programming, unsafe pointers, or cgo integration.
🪤Traps & gotchas
None critical for learning use. Minor consideration: examples expect Go 1.24 (per go.mod); older Go installations may fail. The blogrenderer/ and websocket examples use gomarkdown and gorilla/websocket respectively—these are only needed if you run those specific chapters; basic chapters have zero dependencies. No environment variables, no external services required. Approval tests (go-approval-tests) stores golden files; on first run, tests may fail waiting for approval—this is intentional and documented in mocking/approval chapters.
🏗️Architecture
💡Concepts to learn
- Test-Driven Development (TDD) / Red-Green-Refactor — The entire curriculum is structured around TDD discipline; understanding the Red (write failing test), Green (implement), Refactor cycle is essential to get value from this repo's pedagogical approach.
- Table-Driven Tests — Visible in arrays/v8/sum_test.go; a Go idiom for parameterized testing that learners encounter early and use throughout the curriculum to test multiple cases concisely.
- Interfaces & Polymorphism — Taught in structs-methods-and-interfaces.md and reinforced through dependency injection and mocking chapters; Go's implicit interface satisfaction is a subtle concept that TDD helps clarify.
- Goroutines & Channels — Concurrency is a core Go strength; the concurrency and select chapters teach lightweight goroutines and channel communication patterns that distinguish Go from many other languages.
- Dependency Injection (DI) — Chapter 9 explicitly teaches DI patterns in Go (passing interfaces, not concrete types); enables testable, decoupled code and sets foundation for mocking strategies in Chapter 10.
- Mocking & Golden File Testing (Approval Testing) — Mocking chapter and go-approval-tests dependency introduce learners to advanced testing patterns; golden files validate complex output without brittle assertions.
- Benchmarking in Go — Iteration chapter introduces the testing.B interface and benchmarking; learners see how to empirically measure performance as part of refactoring, not as an afterthought.
🔗Related repos
golang/go— The official Go repository; contains stdlib source, language spec, and proposal discussions referenced by this curriculum's examples.golang/tour— The official Go Tour interactive tutorial; covers similar fundamentals but uses interactive exercises rather than TDD structure and written narrative.quii/coding-in-one-hour-per-week— Companion project by the same author (quii) showing advanced TDD practices in Go; picks up where learn-go-with-tests leaves off for intermediate learners.enocom/gopher-reading-list— Community-curated Go learning resources; includes links to other Go tutorials, blogs, and books; useful for finding supplementary material to pair with this curriculum.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add missing tests for blogrenderer package templates and edge cases
The blogrenderer package has template files (blog.gohtml, bottom.gohtml, index.gohtml, top.gohtml) but the renderer_test.go only has 2 approved test cases. There are likely missing test cases for edge cases like empty posts, special characters in titles, malformed markdown, and individual template rendering. This is a high-value contribution as it improves test coverage for a real-world example that teaches testing practices.
- [ ] Review blogrenderer/renderer_test.go and identify untested code paths in renderer.go
- [ ] Add test cases for edge cases: empty post list, posts with special HTML characters, missing fields
- [ ] Add test cases for template rendering failures and markdown parsing edge cases
- [ ] Run tests and generate new .approved.txt files using go-approval-tests
- [ ] Verify all template files (blog.gohtml, bottom.gohtml, index.gohtml, top.gohtml) are exercised by tests
Create integration tests for command-line package with actual file I/O
The command-line/v1 directory contains CLI and webserver binaries but there are no visible *_test.go files in the command-line directory structure. Adding integration tests that verify the CLI parses flags correctly, reads/writes game.db.json, and the webserver starts would complement the TDD teaching philosophy of this repo and provide a realistic testing example.
- [ ] Create command-line/v1/cmd/cli/main_test.go with tests for flag parsing and CLI argument handling
- [ ] Create command-line/v1/cmd/webserver/main_test.go with tests for database initialization and webserver startup
- [ ] Add test fixtures in command-line/v1/testdata/ for sample game.db.json files
- [ ] Verify tests use temporary directories (t.TempDir()) to avoid side effects
- [ ] Update go.yml workflow if needed to ensure new tests run in CI
Add comprehensive error case tests across arrays/v1-v8 progression examples
The arrays package has 8 versions showing progression but appears to lack explicit error/edge case testing (negative numbers, nil inputs, overflow scenarios). Adding a v9 version or enhancing existing tests with error cases would provide learners with a complete TDD example including error handling patterns, which is currently under-demonstrated in the progression.
- [ ] Review arrays/v8/sum_test.go to identify missing edge case tests (empty slice, negative numbers, large numbers)
- [ ] Create arrays/v9/ directory with enhanced sum.go that handles errors explicitly
- [ ] Add tests for error scenarios: nil slice handling, integer overflow detection
- [ ] Add corresponding markdown documentation in arrays-and-slices.md explaining the v9 error handling approach
- [ ] Ensure all v1-v9 versions can be compiled and tested via go test ./arrays/...
🌿Good first issues
- Add missing integration test for blogrenderer/post.go: the file exists but no *_test.go is visible in the file list; contributing a full chapter lesson with versioned examples (v1–v4) teaching struct methods and interface design would strengthen the blogrenderer chapter.
- Expand concurrency/ chapter with an additional worked example: metadata shows 'Select' chapter is mentioned in README but incomplete (text cuts off at 'se'); completing the Select lesson with a v1–v5 progression teaching channel selection and timeouts would fill a visible gap.
- Create a 'generics' chapter: Go 1.18+ introduced generics; no chapter files (generics.md, generics/) exist; this modern topic would be a high-value addition for learners using recent Go versions, following the TDD pattern of other chapters.
⭐Top contributors
Click to expand
Top contributors
- @quii — 12 commits
- @dario-piotrowicz — 5 commits
- @UponTheSky — 5 commits
- @deining — 3 commits
- @pesterhazy — 3 commits
📝Recent commits
Click to expand
Recent commits
dc00c65— Update Denise Yu link in gb-readme.md (#910) (codigoisaac)e703a89— docs: fix stale contributing link, broken anchor, and dummyStdOut typo (#909) (aoncodev)c9a9387— docs: correct terminology in concurrency chapter (#906) (reminli)541ff81— docs: fix indentation in pointers chapter (#905) (reminli)46b468a— Vietnamese translate (#902) (bjergsen243)9b678a3— docs: fix typo in concurrency chapter (#900) (Franciswann)24e4a6e— fix: interfaces and methods provide ad hoc polymorphism (#899) (Minoru)8eaa757— Docs: Add warning for Linux users regarding system freeze (#896) (andy-lee-cat)2048c9e— GitBook: No commit message (quii)23214cc— fix: typo in concurrency.md (#889) (holahoon)
🔒Security observations
This is an educational repository with moderate security posture. The primary concerns are outdated dependencies (particularly go-approval-tests from 2021) and potential XSS vulnerabilities in the markdown rendering pipeline. The repository lacks some security analysis tooling in CI/CD. Overall, the codebase appears well-structured with no obvious hardcoded secrets or critical misconfigurations. For an educational project, security practices are reasonable but could be improved by updating dependencies, adding security scanning tools, and ensuring proper output sanitization in the blog renderer.
- High · Outdated Dependency: go-approval-tests —
go.mod - github.com/approvals/go-approval-tests. The dependency github.com/approvals/go-approval-tests is pinned to v0.0.0-20211008131110-0c40b30e0000, which is from October 2021. This is significantly outdated and may contain unpatched security vulnerabilities. The version string suggests this is a very old pre-release or snapshot version. Fix: Update to the latest stable version of go-approval-tests. Run 'go get -u github.com/approvals/go-approval-tests' and verify compatibility with the codebase. - Medium · Outdated Dependency: gomarkdown/markdown —
go.mod - github.com/gomarkdown/markdown. The dependency github.com/gomarkdown/markdown is pinned to v0.0.0-20240626202925-2eda941fd024. While more recent than go-approval-tests, markdown parsing libraries can have XSS vulnerabilities if not properly maintained. The commit-based versioning without a release tag suggests potential stability concerns. Fix: Verify this is the latest version or update if available. Consider checking the upstream repository for any reported security issues. Use 'go get -u github.com/gomarkdown/markdown@latest' to update. - Low · Potential XSS Risk in Blog Renderer —
blogrenderer/ package - specifically templates/blog.gohtml, templates/index.gohtml. The blogrenderer package processes markdown and converts it to HTML templates (blog.gohtml, index.gohtml, etc.). If user-supplied markdown is processed without proper sanitization, this could lead to XSS vulnerabilities. The use of gomarkdown/markdown library should include output sanitization. Fix: Ensure all markdown output is properly sanitized before rendering in templates. Use html/template instead of text/template, and consider using a sanitization library like bluemonday for markdown HTML output. - Low · Database File Stored in Repository —
command-line/v1/cmd/webserver/game.db.json, command-line/v2/cmd/webserver/game.db.json. The file command-line/v1/cmd/webserver/game.db.json and command-line/v2/cmd/webserver/game.db.json appear to be database files committed to the repository. While these are likely example/test data for a learning repository, this is not a recommended practice. Fix: Move database files to .gitignore and provide example/seed data through documentation or separate setup scripts instead. This prevents accidental commits of sensitive data in real projects. - Low · No Go Security Analysis Configuration —
.github/workflows/go.yml. The repository does not appear to have gosec or similar Go security analysis tools configured in the CI/CD pipeline (based on .github/workflows/go.yml), which could miss security issues in code. Fix: Add gosec (Go Security Checker) to the CI/CD pipeline. Install via 'go install github.com/securego/gosec/v2/cmd/gosec@latest' and add a scan step to the workflow. - Low · Missing Security Headers in Web Server Examples —
command-line/v1/server.go, command-line/v2/server.go. The command-line/v1/server.go and command-line/v2/server.go files may serve HTTP responses without security headers. The codebase is educational, but should demonstrate security best practices. Fix: Add security headers to HTTP responses such as X-Content-Type-Options, X-Frame-Options, and Content-Security-Policy. Include examples in the educational materials.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.