dpxw7293 2017-06-08 05:49
浏览 28
已采纳

在Go中创建包的工作流程

I understand that programs in Go are run from the main function as their starting point. But I was wondering what the workflow is for creating functions for a new package.

In python for example I use __main__ in module's when the module is called directly. When the module is imported from another file __main__ would be ignored. Which is useful when you're developing a new module.

if __name__ == "__main__":
    # Run module code here if module called directly

For Go I'm using a test.go file with a package main along with my main.go file to test functions in packages I'm creating.

// test.go
package main

import (
    "newpackage"
)

func main() {
    newpackage.MyNewFunc()
}

Is there a better way to do this or is this the standard workflow? Thanks.

  • 写回答

1条回答 默认 最新

  • dsa1230000 2017-06-08 06:36
    关注

    You don't test in Go using main. Go has its own test framework.

    First, read "How to Write Go Code" which will explain Go's package layout and testing tools. It's best to go with them because so much of the Go tools expect that layout.

    When creating a package, put it somewhere in ~/go/src. I'd recommend following the convention using the repository you like to use, even for things you aren't necessarily going to upload. It makes for better organization; go get will put other external packages in ~/go/src/ as well.

    For example, I'd use ~/go/src/github.com/schwern/newpackage/ even though I don't intend to upload this to Github. github.com/schwern acts as my "organization" within the Go source tree.

    Put the functions into newpackage.go under package newpackage.

    $ cat ~/go/src/github.com/schwern/newpackage/newpackage.go 
    package newpackage
    
    func MyNewFunc() string {
        return "Hello!"
    }
    

    Then tests go in newpackage_test.go right next to newpackage.go. These should be familiar from Python, write a bunch of Test* functions. Unlike Python it doesn't use asserts.

    $ cat ~/go/src/github.com/schwern/newpackage/newpackage_test.go 
    package newpackage_test
    
    import(
        "testing"
        "github.com/schwern/newpackage"
    )
    
    func TestMyNewFunc( t *testing.T ) {
        want := "Hello!"
        have := newpackage.MyNewFunc()
    
        if have != want {
            t.Errorf("MyNewFunc(): have: '%v', want: '%v'", have, want )
        }
    }
    

    If you run go test inside the package directory it will compile the current package and its dependencies, find and compile all *_test.go files in the package directory, and execute their Test* functions.

    $ pwd
    /Users/schwern/go/src/github.com/schwern/newpackage
    $ go test -v
    === RUN   TestMyNewFunc
    --- PASS: TestMyNewFunc (0.00s)
    PASS
    ok      github.com/schwern/newpackage   0.013s
    

    Note that the test is in a different package than what its testing. That makes it a blackbox test, it can only see the exported (ie. UpperCase) functions. You can make a glassbox test by putting the tests in the same package, it's best to do that in a separate file like newpackage_internal_test.go.

    Unfortunately Go doesn't come with assert functions, the above if and call to t.Errorf is the equivalent. Rather than constantly hand-roll them, there's libraries out there which provide assert functions like stvp/assert. After running go get github.com/stvp/assert you could write...

    package newpackage_test
    
    import(
        "testing"
        "github.com/schwern/newpackage"
        "github.com/stvp/assert"
    )
    
    func TestMyNewFunc( t *testing.T ) {
        assert.Equal( t, newpackage.MyNewFunc(), "Hello!" )
    }
    

    If you want an executable that uses newpackage, it should probably go in its own package. Unless it's an integral part of newpackage.

    $ cat ~/go/src/github.com/schwern/newexec/main.go 
    package main
    
    import (
        "fmt"
        "github.com/schwern/newpackage"
    )
    
    func main() {
        fmt.Println(newpackage.MyNewFunc())
    }
    

    If you want to test main, the testing package provides a special TestMain function... though I admit I do not fully understand it. Like any other language, it's best to put as much functionality as possible into library calls and have main be a thin wrapper.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改