golang 函數(shù)的可靠性測試涉及單元測試,使用 testing 包隔離測試單個函數(shù);表驅(qū)動的測試,使用測試表測試多個輸入;子測試,在單個測試函數(shù)中創(chuàng)建子測試;集成測試,使用諸如 github.com/ory/dockertest 之類的庫測試代碼的集成行為。
如何測試 Golang 函數(shù)以確保其可靠性
在 Golang 中編寫可靠的函數(shù)對于構(gòu)建健壯和穩(wěn)定的應(yīng)用程序至關(guān)重要。測試是確保函數(shù)符合預(yù)期行為的必要手段。本文將介紹如何測試 Golang 函數(shù),并提供一個實(shí)用案例。
單元測試
單元測試是對單個函數(shù)或模塊進(jìn)行隔離測試的技術(shù)。在 Golang 中,使用 testing
包進(jìn)行單元測試:
package mypkg import "testing" func TestAdd(t *testing.T) { tests := []struct { a, b, expected int }{ {1, 2, 3}, {3, 4, 7}, } for _, tt := range tests { actual := Add(tt.a, tt.b) if actual != tt.expected { t.Errorf("Add(%d, %d) = %d, expected %d", tt.a, tt.b, actual, tt.expected) } } }
登錄后復(fù)制
表驅(qū)動的測試
表驅(qū)動的測試允許我們在使用相同測試函數(shù)的同時測試多個輸入。這意味著我們可以為每個測試用例創(chuàng)建單獨(dú)的測試表:
func TestAddTableDriven(t *testing.T) { tests := []struct { a, b, expected int }{ {1, 2, 3}, {3, 4, 7}, } for _, tt := range tests { t.Run(fmt.Sprintf("TestAdd(%d, %d)", tt.a, tt.b), func(t *testing.T) { actual := Add(tt.a, tt.b) if actual != tt.expected { t.Errorf("Add(%d, %d) = %d, expected %d", tt.a, tt.b, actual, tt.expected) } }) } }
登錄后復(fù)制
子測試
子測試允許在單個測試函數(shù)中創(chuàng)建多個子測試。這有助于組織測試并提供更多詳細(xì)的錯誤消息:
func TestError(t *testing.T) { t.Run("case 1", func(t *testing.T) { err := Error(0) if err != nil { t.Errorf("Error(0) = %v", err) } }) t.Run("case 2", func(t *testing.T) { err := Error(1) if err == nil { t.Error("Expected error for Error(1)") } }) }
登錄后復(fù)制
集成測試
集成測試測試代碼的集成行為,包括涉及多個函數(shù)的交互。在 Golang 中,可以使用 github.com/ory/dockertest
等庫進(jìn)行集成測試:
package mypkg_test import ( "context" "fmt" "io" "testing" "github.com/ory/dockertest" ) func TestIntegration(t *testing.T) { // 創(chuàng)建一個容器,在其中運(yùn)行我們的代碼 container, err := dockertest.NewContainer("my-org/my-image", "latest", nil) if err != nil { t.Fatal(err) } // 在容器中執(zhí)行我們的代碼 output, err := container.Run(context.Background()) if err != nil { t.Fatal(err) } // 檢查輸出以驗(yàn)證行為 if _, err := io.WriteString(output, "Hello World\n"); err != nil { t.Fatal(err) } fmt.Fprintln(output, "Done") // 等待容器退出 if err := container.Wait(); err != nil { t.Fatal(err) } }
登錄后復(fù)制