שיעורי מודול (1/5)
חבילת ה'בדיקות'
ב-Go, בדיקות הן חלק מה-stdlib: אין ספרייה חיצונית, אין מסגרת להגדרה. כל מה שאתה צריך זה קובץ *_test.go ליד הקוד, כמה פונקציות TestXxx והפקודה go test.
מוסכמות בסיסיות
- קובצי הבדיקה נקראים
<something>_test.goוהם חיים באותה חבילה כמו הקוד שהם בודקים (או בחבילה<name>_testעבור "בדיקות קופסה שחורה"). - לפונקציות הבדיקה יש חתימה מדוייקת:
func TestXxx(t *testing.T)כאשרXxxמתחיל באות גדולה. - אתה מייבא את
testingמה-stdlib. - לא
assertEquals: אתה משתמש ב-if got != want { t.Errorf(...) }עםfmt-פעלים.
// math.go
package math
func Sum(a, b int) int { return a + b }
// math_test.go
package math
import "testing"
func TestSum(t *testing.T) {
got := Sum(2, 3)
if got != 5 {
t.Errorf("Sum(2,3) = %d; voglio %d", got, 5)
}
}הפעל את זה עם:
go test ./... # all packages in the module
go test -v ./pkg # verbose: prints test names
go test -run TestSum # only tests matching the regext.Error לעומת t.Fatal
אלה שני הפעלים הבסיסיים לאותת כישלון:
| שיטה | אפקט |
|---|---|
t.Log(args...) | יומן אך אינו נכשל (גלוי רק עם -v או בכשל). |
t.Error(args...) | יומן, מסמן FAIL, ממשיך את פונקציית הבדיקה. |
t.Errorf(fmt, ...) | כמו Error עם עיצוב. |
t.Fatal(args...) | יומן, מסמן FAIL, עצור את הבדיקה (קורא runtime.Goexit). |
t.Fatalf(fmt, ...) | כמו Fatal עם עיצוב. |
כלל אצבע: השתמש ב-Fatal כאשר המשך לא הגיוני (לדוגמה, הגדרה כושלת, הפניית מצביע אפסית קרובה); אחרת Error, המאפשר לך לראות את כל הכשלים בהפעלה אחת.
func TestOpen(t *testing.T) {
f, err := os.Open("fixtures/sample.txt")
if err != nil {
t.Fatal(err) // if it doesn't open, the next steps would fail on nil
}
defer f.Close()
// ... assert on content with t.Errorf
}הגדרה והפסקה עם t.Cleanup
כדי לשחרר משאבים בסוף מבחן (או מבחן משנה), השתמש ב-t.Cleanup במקום ב-defer:
func TestDB(t *testing.T) {
db := newTestDB(t)
t.Cleanup(func() { db.Close() })
// ... test
}היתרון על פני defer: העוזר שיוצר את db יכול לרשום את הניקוי פנימי, כך שהמתקשרים לא צריכים לזכור אותו.
עוזרי מבחן
שיטת t.Helper() מסמנת פונקציה כ"מסייעת": כאשר בדיקה נכשלת, עקבות המחסנית מדלגת על פונקציית העזר ומצביעה ישירות על המתקשר:
func mustParseInt(t *testing.T, s string) int {
t.Helper()
n, err := strconv.Atoi(s)
if err != nil {
t.Fatalf("parse %q: %v", s, err)
}
return n
}תרגילים
הגדר את הפונקציה TestSum שמאמתת Sum(2,3) == 5 באמצעות t.Errorf עם הודעה מעוצבת.
הפתרון זמין לאחר 3 ניסיונות
ב-TestDiv, השתמש ב-t.Fatal כדי לעצור מיד את הבדיקה אם Div מחזיר ערך לא צפוי.
הפתרון זמין לאחר 3 ניסיונות
מה ההבדל המהותי בין t.Error ל-t.Fatal?
if err != nil {
t.???(err)
}