A passing test does not mean the code is finished. The implementation or its tests may still be repetitive or hard to extend. Refactoring changes that structure to make the next small change easier while keeping the tested behavior intact. section 3.3
Keep refactoring close to the work it supports:
- Write a test for one expected result, run it, and make the smallest change that passes it. section 3.2
- Simplify the code or tests, then run the tests again to check that the restructuring worked. section 3.2 section 3.3
- Treat a newly discovered edge case as a new test and implementation step, not as proof that the refactor alone added the needed behavior. section 3.3
Make translation tests easier to extend
Separate assertions for English, German, Finnish, and Dutch translations repeat the same check. Put the inputs and expected outputs in a table instead, so another case can be added without another copy of the assertion. Run the tests after the change. A case such as translating “bye” is a separate check of behavior: a passing table does not guarantee that every untested input is handled correctly. section 3.3
Listing 3.7 translator_test.go
package translation_test
import (
"testing"
"github.com/holmes89/hello-api/translation"
)
func TestTranslate(t *testing.T) {
// Arrange
tt := []struct { #1
Word string
Language string
Translation string
}{
{ #2
Word: "hello",
Language: "english",
Translation: "hello",
},
{
Word: "hello",
Language: "german",
Translation: "hallo",
},
{
Word: "hello",
Language: "finnish",
Translation: "hei",
},
{
Word: "hello",
Language: "dutch",
Translation: "",
},
}
for _, test := range tt { #3
// Act
res := translation.Translate(test.Word, test.Language) #4
// Assert
if res != test.Translation { #5
t.Errorf(
`expected "%s" to be "%s" from "%s" but received "%s"`,
test.Word, test.Language, test.Translation, res)
}
}
}
The Go test listing shows translation scenarios collected as rows with Word, Language, and Translation fields. section 3.3
Keep the feedback loop short: restructure one piece, rerun the tests, then add the next case. Tests near implementation help catch unintended business-logic changes before those bugs reach QA. section 3.3 section 3.0





















