golang unit test

cli1871 · · 1359 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

本篇文章展示了怎么写Unit Test及怎么统计coverage, 为了方便写UT,最好exposed Api is Method not function,为了更好的帮助大家理解,给出了一个例子方便大家参考。例子分为三部分,source code, unit test code, Makefile.

Code 目录

mkdir -p ~/test/src/gounit/etcd

source code

package etcd

import (

        "context"

        "log"

        "time"

        "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"

        "go.etcd.io/etcd/clientv3"

)

type KV interface {

        Put(ctx context.Context, key, valstring, opts ...clientv3.OpOption) (*clientv3.PutResponse, error)

}

type etcdClient struct {

        kv KV

}

const (

        DefaultOperationTimeout =3 * time.Second

)

var (

        endpoints = []string{"localhost:2379"}

)

func (ec *etcdClient) Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) {

        ctx, cancel := context.WithTimeout(ctx, DefaultOperationTimeout)

        resp, err := ec.kv.Put(ctx, key, val, opts...)

        cancel()

        if err != nil {

                switch err {

                case context.Canceled:

                        log.Printf("[ETCD] ctx is canceled by another routine: %v", err)

                case context.DeadlineExceeded:

                        log.Printf("[ETCD] ctx is attached with a deadline is exceeded: %v", err)

                case rpctypes.ErrEmptyKey:

                        log.Printf("[ETCD] client-side error: %v", err)

                default:

                        log.Printf("[ETCD] bad cluster endpoints, which are not etcd servers: %v", err)

                }

        }

        return resp, err

}

Unit Test code

package etcd

import (

        "context"

        "errors"

        "testing"

        "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"

        "github.com/stretchr/testify/assert"

        "go.etcd.io/etcd/clientv3"

)

type mockEtcdClient struct {

}

var (

        defaultErr = errors.New("default err")

)

func (mec *mockEtcdClient) Put(ctx context.Context, key, val string, opts ...clientv3.OpOption) (*clientv3.PutResponse, error) {

        switch key {

        case "canceled":

                return nil, context.Canceled

        case "deadline_exceeded":

                return nil, context.

        case "err_empty_key":

                return nil, rpctypes.ErrEmptyKey

        case "default":

                return nil, defaultErr

        default:

                return nil, nil

        }

}

type putResult struct {

        putResponse *clientv3.PutResponse

        err        error

}

func TestPut(t *testing.T) {

        api := &etcdClient{kv: &mockEtcdClient{}}

        tests := []struct {

                key    string

                expect putResult

        }{

                {

                        key:"canceled",

                        expect: putResult{

                                putResponse:nil,

                                err:        context.Canceled,

                        },

                },

                {

                        key:"deadline_exceeded",

                        expect: putResult{

                                putResponse:nil,

                                err:        context.DeadlineExceeded,

                        },

                },

                {

                        key:"err_empty_key",

                        expect: putResult{

                                putResponse:nil,

                                err:        rpctypes.ErrEmptyKey,

                        },

                },

                {

                        key:"default",

                        expect: putResult{

                                putResponse:nil,

                                err:        defaultErr,

                        },

                },

                {

                        key:"fine",

                        expect: putResult{

                                putResponse:nil,

                                err:        nil,

                        },

                },

        }

        for index, test := range tests {

                _, err := api.Put(context.Background(), test.key,"oktestut")

                assert.EqualValuesf(t, test.expect.err, err,"case: %d", index)

        }

}

Makefile

export GOPATH = $(shell pwd)/../../..

TEST_FLAGS=-test.short -v

PKGS = gounit/etcd

print:

        echo$(GOPATH)

dep:

        go get "go.etcd.io/etcd/clientv3"

        go get "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"

        go get "github.com/stretchr/testify/assert"

vet:dep 

        go fmt ./...

        go vet ./...

test:vet 

        go test --cover$(PKGS)

cover-tool:

        go get github.com/jstemmer/go-junit-report

        go get golang.org/x/tools/cmd/cover

        go get github.com/axw/gocov/gocov

        go get github.com/AlekSi/gocov-xml

        go get github.com/wadey/gocovmerge

unit-coverage: dep cover-tool

        mkdir -p report

        cat /dev/null > report/utest.out

        $(foreach i,$(PKGS),go test $(i) $(TEST_FLAGS) --covermode=count -coverprofile=report/cover-`echo $(i) |sed 's/\//./g'`.out >> report/utest.out;)

        cat report/utest.out | go-junit-report > report/unit_test_report.xml

        gocovmerge report/cover-*.out > report/unit_test_coverage.out

        gocov convert report/unit_test_coverage.out | gocov-xml > report/unit_test_coverage.xml

        go tool cover -html=report/unit_test_coverage.out -o report/unit_test_coverage.html

        rm report/{cover-*,utest}.out

clean:

        rm -rf report 


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:cli1871

查看原文:golang unit test

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1359 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传