亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang 測試中可重用的組件和固定裝置

Golang 測試中可重用的組件和固定裝置

Go
RISEBY 2022-01-17 10:20:43
我剛剛開始使用 Golang 并編寫我的第一個測試套件。我有 Rails 的背景,它為測試工具(Rspec、Cucumber 等)提供了極好的支持,所以我正在以類似的心態進行我的 golang 測試(不確定這是對還是錯)我有一個User數據模型(基本上是一個結構),它從 postgres 中的表中讀取記錄users并存儲它們的數組。(本質上是 ActiveRecord 在 Rails 世界中所做的一個非常簡單的版本)我想編寫一個測試來檢查例程是否正確地從數據庫中讀取并構建模型。在幾乎每個測試套件中,我都會連接到數據庫,所以我有一個名為establish_db_connection. 我可以把它放在哪里,以便我的所有測試集中使用它?建立 #1 - 是否有等效的before塊或某些設置/拆卸方法,我可以在每次測試之前建立連接?最后,我如何處理固定裝置?現在在每次測試之前,我都會調用一個clear_db函數來重置所有表并插入一些靜態數據行。我很想擺脫固定裝置并根據需要使用工廠來構建數據(非常類似于FactoryGirl在 Rails 中),但不確定這在 Golang 中有多普遍。內置go test框架是最好的方法,還是有更好的選擇?
查看完整描述

3 回答

?
湖上湖

TA貢獻2003條經驗 獲得超2個贊

Go 基于強大的包管理,這意味著命名空間被視為一個文件。如果establish_db_connection在單個測試包中使用,它可以以小寫字母開頭表示私有實例,并在測試文件中使用與被測試代碼相同的包(注意 Go 中的命名約定是establishDBConnection)。但是,大多數時候,就像在data/sql中一樣,您會希望獲得一次數據庫連接并保持它直到測試完成(更像是工廠和注入模式)。


標準testing包中沒有。如果你喜歡 BDD,Goconvey使用范圍來定義固定裝置和reset用于拆卸的函數。


您可以在測試中使用工廠和依賴注入。我認為這很地道。


一些包括Goconvey,Ginkgo和Testify他們都有自己的優點和缺點。前兩個通常以太多的嵌套范圍結束,但 Goconvey 有一個很棒的基于瀏覽器的實時測試服務器,可以與 Go 標準測試一起使用。


由于 Go 中沒有全局變量/函數,因此您可以以接口委托模式設計項目,以幫助跨包導入函數并在處理跨包測試時避免循環導入。


mypackage


type DBOptions struct {

        Name, Credentials string

}


func aFunc(db *sql.DB) error {

        // do something

        return nil

}


func bFunc(db *sql.DB) int, error {

        // do something

        return 0, nil

}


func establishConn(opts *DBOptions) (*sql.DB, error) {

        db, err := sql.Open(opts.Name, opts.Credentials)

        if err != nil {

                return nil, err

        }

        return db, nil

}


func destroyConn(conn *sql.DB) {

        conn.Close()

}


// test file

mypackage 


import "testing"


var myOpt = &DBOptions{

        Name: "mysql", 

        Credentials: "user:password@tcp(127.0.0.1:3306)/hello",

}


var conn, _ = establishConn(myOpt)


func TestAFunc(t *testing.T) {

        err := aFunc(conn)


        if err != nil  {

                t.Error(err)

        }

}


func TestBFunc(t *testing.T) {

        err := aFunc(conn)


        if err != nil  {

                t.Error(err)

        }

}


// use `conn` in other tests ...


destroyConn(conn)


查看完整回答
反對 回復 2022-01-17
?
www說

TA貢獻1775條經驗 獲得超8個贊

關于 Rails 中類似 FactoryGirl 的測試夾具庫,go 中有一些選擇。

這兩個圖書館得到的明星最多。

而且我還實現了與上述庫相比類型安全、干燥且靈活的測試夾具庫!


查看完整回答
反對 回復 2022-01-17
?
瀟瀟雨雨

TA貢獻1833條經驗 獲得超4個贊

在夾具上:考慮在您的測試用例中傳遞函數:


package main


import "testing"


type testcase struct {

    scenario  string

    before    func(string)

    after     func()

    input     string

    expOutput string

}


var state = ""


func setup(s string) {

    state = s

}


func nilSetup(s string) {}


func reset() {

    state = ""

}


func execute(s string) string {

    return state

}


func TestSetupTeardown(t *testing.T) {

    tcs := []testcase{

        {

            scenario:  "blank output when initial state is wrong",

            before:    nilSetup,

            after:     reset,

            input:     "foo",

            expOutput: "",

        },

        {

            scenario:  "correct output when initial state is right",

            before:    setup,

            after:     reset,

            input:     "foo",

            expOutput: "foo",

        },

    }


    for _, tc := range tcs {

        tc.before(tc.input)

        if out := execute(tc.input); out != tc.expOutput {

            t.Fatal(tc.scenario)

        }

        tc.after()

    }

}


查看完整回答
反對 回復 2022-01-17
  • 3 回答
  • 0 關注
  • 144 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號