我最近修改了我的应用程序,发现测试开始挂起。这是精简的测试代码:
package app_test
import (
"testing"
"github.com/kargirwar/prosql-go/db"
)
func TestApp(t *testing.T) {
db.SetDbPath("")
}
db包如下:
package db
import (
"os"
"context"
"database/sql"
_ "github.com/mattn/go-sqlite3"
"path/filepath"
)
var dbPath string
func SetDbPath(path string) {
dbPath = path
}
func OpenDb(ctx context.Context, db string) (*sql.DB, error) {
db = filepath.Join(dbPath, db)
_, err := os.OpenFile(db, os.O_RDWR, 0600)
if err != nil {
return nil, err
}
return sql.Open("sqlite3", "file:"+db+"?_foreign_keys=true")
}
我将问题追溯到这个依赖项:
_ "github.com/mattn/go-sqlite3"
如果我将其注释掉,那么测试就会正常运行,否则就会挂起。
奇怪的是, go run 工作得很好。 Google 说 go-sqlite3 需要时间来编译,但为什么 go run 可以正常工作?
最佳答案
sqlite3 包使用 cgo。第一次引用 sqlite3 包时,会编译并缓存关联的 sqlite3 C 代码以供以后使用。
$ cat x.go
package main
import _ "github.com/mattn/go-sqlite3"
func main(){}
$ cat x_test.go
package main
import "testing"
func TestSQLite(t *testing.T) {}
$ go clean -cache
$ time go run -v x.go
github.com/mattn/go-sqlite3
command-line-arguments
real 0m41.378s
user 0m41.176s
sys 0m1.353s
$ time go run -v x.go
real 0m0.506s
user 0m0.571s
sys 0m0.209s
$ go clean -cache
$ time go build -v x.go
github.com/mattn/go-sqlite3
real 0m41.038s
user 0m40.779s
sys 0m1.280s
$ time go build -v x.go
real 0m0.239s
user 0m0.379s
sys 0m0.101s
$ go clean -cache
$ time go test -v x.go x_test.go
=== RUN TestSQLite
--- PASS: TestSQLite (0.00s)
PASS
ok command-line-arguments 0.003s
real 0m42.751s
user 0m44.702s
sys 0m2.097s
$ time go test -v x.go x_test.go
=== RUN TestSQLite
--- PASS: TestSQLite (0.00s)
PASS
ok command-line-arguments 0.002s
real 0m0.618s
user 0m0.752s
sys 0m0.306s
$
关于Golang测试挂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73943467/