smartystreets/goconvey
Go testing in the browser. Integrates with `go test`. Write behavioral tests in Go.
Stale — last commit 2y ago
weakest axisnon-standard license (Other); last commit was 2y ago
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.
- ✓30+ active contributors
- ✓Other licensed
- ✓CI configured
Show all 7 evidence items →Show less
- ✓Tests present
- ⚠Stale — last commit 2y ago
- ⚠Concentrated ownership — top contributor handles 57% of recent commits
- ⚠Non-standard license (Other) — review terms
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
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 "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/smartystreets/goconvey)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/smartystreets/goconvey on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: smartystreets/goconvey
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/smartystreets/goconvey 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
WAIT — Stale — last commit 2y ago
- 30+ active contributors
- Other licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 2y ago
- ⚠ Concentrated ownership — top contributor handles 57% of recent commits
- ⚠ Non-standard license (Other) — review terms
<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 smartystreets/goconvey
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/smartystreets/goconvey.
What it runs against: a local clone of smartystreets/goconvey — 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 smartystreets/goconvey | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 676 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of smartystreets/goconvey. If you don't
# have one yet, run these first:
#
# git clone https://github.com/smartystreets/goconvey.git
# cd goconvey
#
# 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 smartystreets/goconvey and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "smartystreets/goconvey(\\.git)?\\b" \\
&& ok "origin remote is smartystreets/goconvey" \\
|| miss "origin remote is not smartystreets/goconvey (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "convey/convey.go" \\
&& ok "convey/convey.go" \\
|| miss "missing critical file: convey/convey.go"
test -f "convey/context.go" \\
&& ok "convey/context.go" \\
|| miss "missing critical file: convey/context.go"
test -f "convey/assertions.go" \\
&& ok "convey/assertions.go" \\
|| miss "missing critical file: convey/assertions.go"
test -f "convey/reporting/reporter.go" \\
&& ok "convey/reporting/reporter.go" \\
|| miss "missing critical file: convey/reporting/reporter.go"
test -f "web/client/index.html" \\
&& ok "web/client/index.html" \\
|| miss "missing critical file: web/client/index.html"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 676 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~646d)"
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/smartystreets/goconvey"
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
GoConvey is a Go testing framework that translates behavioral test code (written with nested Convey() calls and So() assertions) into both terminal output and a live-reloading web UI. It integrates directly with go test, allowing developers to run tests via the standard Go toolchain while optionally viewing real-time results in a browser with coverage metrics and stack traces. Monolithic package structure: convey/ is the core testing framework (with assertions.go, context.go, discovery.go, and reporting/ subpackage for console/JSON/gotest output formatters); examples/ contains runnable test samples (bowling_game_test.go); web/ holds the browser UI client (HTML, CSS, JavaScript); goconvey.go is the CLI entry point. The reporting/ subpackage abstracts output reporters (console.go, json.go, dot.go) behind a reporter.go interface.
👥Who it's for
Go developers who want BDD-style (Behavior-Driven Development) test syntax with readable nested contexts instead of table-driven tests, and who appreciate instant visual feedback in a browser while developing. Both individual contributors and teams managing complex test suites benefit from the automatic web UI and test discovery.
🌱Maturity & risk
GoConvey is stable and production-ready. It has a substantial codebase (238K lines of Go), comprehensive test coverage (evidenced by files like focused_execution_test.go, isolated_execution_test.go, story_conventions_test.go), active CI/CD via Travis (.travis.yml present), and clear versioning (go.mod shows v1 maturity). However, commit activity is not visible in the provided data; based on Go 1.16+ support in README, it is actively maintained but not bleeding-edge development.
Dependency risk is low: only 3 direct dependencies (gls, smarty/assertions, golang.org/x tools) plus 2 transitive ones. The smarty/assertions library (v1.15.1) is first-party and well-maintained. Single-maintainer risk exists (SmartyStreets organization), but the project is stable and unlikely to break for existing users. No evidence of breaking changes in the Go 1.16+ support window.
Active areas of work
No recent commits visible in the provided data snapshot. The project is in maintenance mode: Go version support is frozen at 1.16+ (see README), and the assertion suite and discovery mechanisms are stable. Active areas of focus are likely bug fixes in stack_trace_test.go and isolated_execution_test.go rather than new features.
🚀Get running
go install github.com/smartystreets/goconvey(installs the goconvey CLI)- Clone or navigate to your Go project:
cd /path/to/your/project - Start the web server:
goconvey - Open http://localhost:8080 in your browser
- Write tests using the pattern in examples/simple_example_test.go (import . "github.com/smartystreets/goconvey/convey", then use Convey() and So() in your *_test.go files)
Daily commands:
Development: Run tests for the framework itself with go test ./... from the repo root. To use GoConvey in a project: (1) add tests using convey/assertions.go (e.g., examples/simple_example_test.go as a template), (2) run goconvey in your project directory, (3) tests auto-run on save and display in http://localhost:8080. No dev server setup needed; goconvey is the server.
🗺️Map of the codebase
convey/convey.go— Main entry point defining the Convey() function—the core DSL for writing behavioral tests in GoConvey.convey/context.go— Manages test execution context, nesting, and state isolation—essential for understanding how tests are scoped and executed.convey/assertions.go— Core assertion functions that power the fluent So() syntax for test expectations.convey/reporting/reporter.go— Abstract reporter interface that all output formats (console, web, JSON) implement—critical for extensibility.web/client/index.html— Web UI entry point for browser-based test visualization and the main visual interface users interact with.goconvey.go— Package-level documentation and initialization for the GoConvey testing framework.convey/discovery.go— Test discovery mechanism that introspects Go test files to extract and organize GoConvey tests.
🧩Components & responsibilities
- Conv — undefined
🛠️How to make changes
Add a New Assertion Type
- Define the assertion builder function in convey/assertions.go following the So() pattern (
convey/assertions.go) - Import the smarty/assertions package and delegate to existing assertion implementations (
convey/assertions.go) - Add example usage in examples/assertion_examples_test.go showing the new assertion (
examples/assertion_examples_test.go)
Add a New Output Reporter Format
- Create new file in convey/reporting/ implementing the Reporter interface from reporter.go (
convey/reporting/reporter.go) - Implement required methods: BeginStory, Enter, Exit, Report, EndStory for your format (
convey/reporting/console.go) - Register the reporter in convey/reporting/init.go alongside existing reporters (
convey/reporting/init.go) - Add tests for your reporter in convey/reporting/ following *_test.go naming convention (
convey/reporting/reporter_test.go)
Add a New Web UI Feature
- Add HTML structure in web/client/index.html for the new UI component (
web/client/index.html) - Implement JavaScript logic in web/client/resources/js/goconvey.js to handle interactions (
web/client/resources/js/goconvey.js) - Add CSS styling in web/client/resources/css/common.css or a theme file (
web/client/resources/css/common.css)
Add New Behavioral Test Examples
- Create a new *_test.go file in examples/ following naming convention (
examples/simple_example_test.go) - Use Convey() for test nesting and So() for assertions, following existing patterns (
examples/simple_example_test.go) - Add documentation comment block at package level in examples/doc.go (
examples/doc.go)
🔧Why these technologies
- Go goroutines & channels (gls package) — Enables isolated test contexts in parallel test execution while maintaining per-goroutine scope separation.
- go/ast introspection (golang.org/x/tools) — Discovers Convey() test blocks in source code without requiring separate test annotations or registries.
- HTTP server + JavaScript (web UI) — Provides live, interactive test visualization in the browser with real-time updates and manual test composition.
- smarty/assertions package — Delegates complex assertion logic to a battle-tested library, keeping GoConvey DSL layer thin.
⚖️Trade-offs already made
-
Test discovery via AST introspection rather than runtime registration
- Why: Eliminates boilerplate and allows tests to be written as pure functions; integrates seamlessly with go test.
- Consequence: Tightly couples discovery to source code structure; advanced test filtering/composition requires parsing Go syntax.
-
Fluent assertion syntax (So()) instead of native Go assertions
- Why: Makes test code more readable and BDD-like; provides precise failure messages.
- Consequence: Adds a DSL layer that developers must learn; requires go test integration to avoid confusion with native testing package.
-
Optional web UI built on plain JavaScript rather than a modern SPA framework
- Why: Minimizes dependencies and keeps GoConvey lightweight; web UI is optional, not core.
- Consequence: UI may be harder to extend; no built-in state management or component architecture.
-
Hierarchical test nesting with Convey() instead of flat test functions
- Why: Enables readable story-like test organization and shared setup/teardown across groups.
- Consequence: Requires careful context and scope management; test isolation complexity increases.
🚫Non-goals (don't propose these)
- Real-time collaborative test editing (web UI is for viewing and composing, not concurrent multi-user editing)
- Replacement for Go's native testing package (designed as complementary, integrates with go test)
- Performance benchmarking or profiling tools (focused on behavioral testing, not performance analysis)
- Mocking or test doubles library (integrates with existing Go mocking ecosystems)
- CI/CD pipeline automation (reporting only; deployment integration is user's responsibility)
🪤Traps & gotchas
Goroutine-local storage: GoConvey uses github.com/jtolds/gls to store execution context in goroutines; tests that spawn goroutines may lose context and fail silently or show incorrect assertion failures—always run assertions in the same goroutine as the Convey(). Reporter initialization: The reporter is set globally in convey/init.go and selected at first test run; changing reporters mid-test (e.g., in reporting_hooks_test.go) requires understanding the initialization order. Discovery vs. execution: convey/discovery.go parses source without executing; if you dynamically generate test names or use reflection heavily, discovery may not see them. Go version: The project targets Go 1.16+ (see README); using generics or other 1.18+ features in test helpers requires explicit version bumping. No environment variables required for basic usage, but custom reporters may need configuration passed via the Convey API rather than env vars.
🏗️Architecture
💡Concepts to learn
- Behavior-Driven Development (BDD) — GoConvey's core philosophy: nested Convey() calls structure tests as executable specifications ('Given-When-Then'), making them readable to non-developers and maintainable over time
- Goroutine-Local Storage (GLS) — GoConvey uses jtolds/gls to attach execution context to goroutines; understanding GLS is essential when debugging why nested Convey() scopes fail to capture test state in concurrent tests
- Abstract Syntax Tree (AST) Parsing — convey/discovery.go parses Go source using golang.org/x/tools to identify Convey() calls statically; knowing how AST discovery works helps you understand why dynamically-defined tests may not appear in the web UI
- Reporter/Listener Pattern — convey/reporting/reporter.go defines an interface for pluggable output formatters (console, JSON, gotest); this pattern lets you add custom reporting (e.g., XML, Slack notifications) without modifying core test execution
- Static Test Discovery vs. Dynamic Execution — GoConvey separates test discovery (convey/discovery.go, AST-based) from execution (convey/context.go); this allows the web UI to render test structure before running, enabling focused test runs and skipping tests without re-parsing
- Go's testing.T Integration — GoConvey is built on top of Go's standard testing package (convey/gotest/utils.go bridges the two); understanding how GoConvey wraps testing.T helps you debug test failures and mix GoConvey tests with standard Go tests
- Live-Reload Web Architecture — GoConvey serves a browser UI (web/client/) that polls or watches JSON test results (convey/reporting/json.go) from the running go test process; the architecture enables real-time feedback without test-runner restarts
🔗Related repos
onsi/ginkgo— Alternative BDD testing framework for Go with similar nested context and assertion syntax; direct competitor but with additional matchers and integration with Gomega assertion librarystretchr/testify— Popular Go testing toolkit offering assert and require packages; simpler than GoConvey but lacks the BDD nesting and browser UI; many users combine it with standard Go testssmarty/assertions— First-party dependency (v1.15.1) that provides the actual assertion implementations; understanding this library is key to extending GoConvey matchersjtolds/gls— Goroutine-local storage library used by GoConvey to track test execution context across nested Convey() scopes; critical for understanding how context flows through testsgolang/tools— Standard Go tools package (x/tools) used for AST parsing in discovery.go to locate Convey() calls in source code without executing them
🪄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 comprehensive tests for convey/context.go functionality
The context.go file is a core component for managing test context and scope in GoConvey, but there are no dedicated test files for it (no context_test.go). This is a critical gap since context management is fundamental to the Convey DSL. Tests should cover context initialization, nesting behavior, cleanup, and isolation - which are referenced in isolated_execution_test.go but need dedicated coverage.
- [ ] Create convey/context_test.go with tests for context creation and lifecycle
- [ ] Add tests for nested context behavior and scope isolation
- [ ] Add tests for context cleanup and resource management
- [ ] Verify edge cases like deeply nested contexts and concurrent access patterns
- [ ] Reference existing isolated_execution_test.go patterns for consistency
Add tests for convey/gotest/utils.go utility functions
The gotest/utils.go file provides utility functions for Go test integration, but only has doc_test.go which is likely documentation-focused. There's no dedicated utils_test.go covering the actual utility functions. These utilities are critical for the core integration with go test command.
- [ ] Create convey/gotest/utils_test.go with unit tests for each exported function
- [ ] Add tests for path resolution and test discovery logic
- [ ] Add tests for any parsing or string manipulation utilities
- [ ] Include tests for edge cases and error conditions
- [ ] Ensure tests follow patterns used in convey/reporting/gotest_test.go
Add GitHub Actions workflow to replace or supplement Travis CI
The repo uses .travis.yml for CI, but the README snippet shows Travis CI build badge and the Travis CI ecosystem has evolved. GitHub Actions is now the standard, provides better integration with GitHub, and would modernize the CI/CD pipeline. This is especially important since go.mod specifies Go 1.21.7 support but .travis.yml configuration isn't visible - a modern workflow would test multiple Go versions systematically.
- [ ] Create .github/workflows/test.yml with matrix testing for Go 1.21, 1.22, and tip versions
- [ ] Configure workflow to run
go test ./...for all packages including examples/ - [ ] Add linting step using golangci-lint or similar (referenced by smarty/assertions dependency quality expectations)
- [ ] Configure workflow to check third-party licenses using check_third_party.sh
- [ ] Add build step for the web component to ensure no regressions in web/client assets
🌿Good first issues
- Add ShouldBeLessThanOrEqualTo assertion variant: convey/assertions.go has ShouldBeLessThan but is missing the <= variant used in inequality chains; add the matcher and corresponding test in examples/assertion_examples_test.go. Requires understanding the assertion registration pattern and how matchers return error messages.
- Extend JSON reporter with test execution timing: convey/reporting/json.go currently does not record per-test or per-scope execution duration; add timing fields to the JSON output structure (convey/reporting/reports.go) and propagate timing from context.go. Would enable performance regression detection in the web UI.
- Add example test using HTTP mocking and multiple goroutines: examples/ lacks a realistic concurrent test scenario; create examples/http_mocking_test.go demonstrating correct use of goroutines within Convey scopes, with guidance on when (and why) context is lost. Would help onboard users migrating from table-driven tests.
⭐Top contributors
Click to expand
Top contributors
- @riannucci — 57 commits
- @srabraham — 6 commits
- @ezk84 — 4 commits
- @mdwhatcott — 2 commits
- [@Lucas Lee](https://github.com/Lucas Lee) — 2 commits
📝Recent commits
Click to expand
Recent commits
a50310f— Merge pull request #688 from srabraham/2024-02-13-watcher (riannucci)42e0453— fix(web): fix nondeterministic tests (srabraham)6705b94— Merge pull request #687 from srabraham/2024-02-12-go-121 (riannucci)5c42754— chore(go.mod): upgrade to go 1.21.7 (srabraham)e004177— Merge pull request #686 from srabraham/2024-02-12-broken-tests (riannucci)55c259d— chore: make a few tweaks based on code review (srabraham)f5ff363— fix: fix a few tests that were broken at HEAD (srabraham)227a4cc— Fix checker script to run updater with bash. (riannucci)e4b0a39— Merge pull request #685 from srabraham/2024-02-08-convey-xss (riannucci)eff725c— fix(web): protect against XSS in test description (srabraham)
🔒Security observations
GoConvey has a reasonable security posture for an open-source testing framework. The codebase uses minimal, well-maintained dependencies with no critical vulnerabilities identified. Primary concerns are around the web client's potential XSS risks and the need for updated Go versions in CI/CD. The project would benefit from establishing a formal security disclosure policy and ensuring proper input validation/output encoding in the browser-based testing interface.
- Medium · Outdated Go Version —
go.mod. The project specifies 'go 1.21.7' in go.mod. While Go 1.21 is relatively recent, the project should regularly update to the latest stable Go version to benefit from security patches and improvements. Go follows a release policy where older versions may not receive critical security updates. Fix: Regularly update to the latest stable Go version. Monitor Go security advisories and update go.mod and CI/CD configurations accordingly. - Low · Potential XSS Risk in Web Client —
web/client/ (HTML and JavaScript files). The project contains web client files (index.html, composer.html, composer.js, config.js) that serve as a browser-based testing interface. If user input from test files is rendered without proper escaping, this could lead to XSS vulnerabilities. Fix: Ensure all dynamic content is properly HTML-escaped before rendering. Use templating engines with auto-escaping features. Implement Content Security Policy (CSP) headers. - Low · No Security.txt File —
Repository root. The repository does not appear to have a security.txt or SECURITY.md file for responsible disclosure of security vulnerabilities. Fix: Create a SECURITY.md file with instructions for responsible vulnerability disclosure, including contact information for security researchers. - Low · Incomplete README Security Information —
README.md. The README appears to be truncated and lacks information about security best practices, known vulnerabilities, or security considerations for users of the library. Fix: Complete and expand the README with security considerations, supported Go versions, security update policies, and dependency management information.
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.