@@ -89,18 +89,23 @@ go test -v ./internal/config -run TestConfig
8989go test -race ./internal/config
9090```
9191
92- ## Test Types
92+ ## Testing Strategy
9393
94- ### 1. Unit Tests
94+ ** Cover new work with end-to-end tests, not unit tests.** A change to the
95+ compiler, an engine, the analysis core or codegen is exercised by running sqlc
96+ the way a user does — a schema, a query file and a committed golden output —
97+ so the test says what sqlc produces rather than what an internal function
98+ returns. Internal APIs move around; the SQL that goes in and the output that
99+ comes out is the contract worth pinning down.
95100
96- - ** Location:** Throughout the codebase as ` *_test.go ` files
97- - ** Run without:** Database or external dependencies
98- - ** Examples:**
99- - ` /internal/config/config_test.go ` - Configuration parsing
100- - ` /internal/compiler/selector_test.go ` - Compiler logic
101- - ` /internal/metadata/metadata_test.go ` - Query metadata parsing
101+ Adding coverage means adding a directory under ` /internal/endtoend/testdata/ ` ,
102+ not a ` *_test.go ` next to the code. Reach for a unit test only when the
103+ behavior genuinely cannot be reached through the CLI, and say why in the test.
102104
103- ### 2. End-to-End Tests
105+ Some ` *_test.go ` files predate this and remain; they are not a precedent for
106+ new ones.
107+
108+ ### End-to-End Tests
104109
105110- ** Location:** ` /internal/endtoend/ `
106111- ** Requirements:** ` --tags=examples ` flag and running databases
@@ -111,7 +116,15 @@ go test -race ./internal/config
111116 - ` TestJsonSchema ` - JSON schema validation
112117 - ` TestExamplesVet ` - Static analysis tests
113118
114- ### 3. Example Tests
119+ A case is a directory holding the inputs and the expected output. ` exec.json `
120+ names the command and its arguments — omit it and the case runs ` generate ` ,
121+ comparing the generated files against the ones committed alongside; give it
122+ ` {"command": "analyze", "args": [...]} ` and the case compares the command's
123+ stdout against ` stdout.txt ` . A case that is expected to fail commits its
124+ ` stderr.txt ` . Regenerate a golden by running the command in its directory and
125+ writing the output back over the committed file.
126+
127+ ### Example Tests
115128
116129- ** Location:** ` /examples/ ` directory
117130- ** Requirements:** Tagged with "examples", requires live databases
@@ -183,6 +196,9 @@ MYSQL_SERVER_URI="root:mysecretpassword@tcp(127.0.0.1:3306)/mysql?multiStatement
183196 - ` /postgresql/ ` - PostgreSQL parser and converter
184197 - ` /dolphin/ ` - MySQL parser (uses TiDB parser)
185198 - ` /sqlite/ ` - SQLite parser
199+ - ` <engine>/dialect/ ` - The engine's type system and standard library, as
200+ JSONL read by ` /internal/core/seed `
201+ - ` /internal/core/ ` - The analysis core: catalog, analyzer and dialect seeds
186202- ` /internal/compiler/ ` - Query compilation logic
187203- ` /internal/codegen/ ` - Code generation for different languages
188204- ` /internal/config/ ` - Configuration file parsing
@@ -232,9 +248,10 @@ go run ./cmd/sqlc-test-setup start
232248## Tips for Contributors
233249
2342501 . ** Run tests before committing:** ` go test --tags=examples -timeout 20m ./... `
235- 2 . ** Check for race conditions:** Use ` -race ` flag when testing concurrent code
236- 3 . ** Use specific package tests:** Faster iteration during development
237- 4 . ** Read existing tests:** Good examples in ` /internal/engine/postgresql/*_test.go `
251+ 2 . ** Cover new behavior end to end:** Add a case under ` /internal/endtoend/testdata/ `
252+ 3 . ** Check for race conditions:** Use ` -race ` flag when testing concurrent code
253+ 4 . ** Iterate on one case:** ` go test ./internal/endtoend -run 'TestReplay/base/<case>' `
254+ 5 . ** Read existing cases:** ` /internal/endtoend/testdata/ ` has one per feature
238255
239256## Git Workflow
240257
0 commit comments