Skip to content

单元测试

  • 用于测试函数、方法的逻辑正确性。
  • 用于项目整体性测试、确保项目的不同模块之间的交互正常。

基本规则

  • 新建一个test目录,包含所有测试用例
  • 创建一个测试文件,文件名格式必须xxx_test.go
  • 测试函数必须TestXxx开头
  • 测试函数必须接收一个指向 t *testing.T 的指针作为参数

代码示例

curl请求

go
package curl

import (
	"encoding/json"
	"errors"
	"io"
	"net/http"
	"strings"
	"time"
)

type Curl struct {
	Client  *http.Client
	Url     string
	Method  string
	Params  map[string]interface{}
	Body    map[string]interface{}
	Headers map[string]string
	Timeout time.Duration
}

func NewCurl(url string) *Curl {
	return &Curl{
		Url: url,
		Client: &http.Client{
			Timeout: 3 * time.Second,
		},
		Headers: map[string]string{
			"Content-Type": "application/json;charset=UTF-8",
		},
	}
}

func (c *Curl) SetTimeout(timeout time.Duration) *Curl {
	c.Timeout = timeout
	c.Client.Timeout = timeout * time.Second
	return c
}

func (c *Curl) SetParams(params map[string]interface{}) *Curl {
	c.Params = params
	return c
}

func (c *Curl) SetBody(body map[string]interface{}) *Curl {
	c.Body = body
	return c
}

func (c *Curl) SetHeaders(k string, v string) *Curl {
	c.Headers[k] = v
	return c
}

func (c *Curl) Get() (string, error) {
	c.Method = "GET"
	// 拼接params
	if len(c.Params) > 0 {
		u := ""
		for k, v := range c.Params {
			u += "&" + k + "=" + v.(string)
		}
		u = strings.TrimLeft(u, "&")
		c.Url = c.Url + "?" + u
	}
	// 创建请求
	req, err := http.NewRequest(c.Method, c.Url, nil)
	if err != nil {
		return "", errors.New("创建请求失败:" + err.Error())
	}
	// 设置headers
	for k, v := range c.Headers {
		req.Header.Add(k, v)
	}
	// 发送请求
	resp, err := c.Client.Do(req)
	if err != nil {
		return "", errors.New("发送请求失败:" + err.Error())
	}
	// 关闭响应
	defer resp.Body.Close()
	// 解析响应
	response, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", errors.New("解析响应失败:" + err.Error())
	}
	return string(response), nil
}

func (c *Curl) Post() (string, error) {
	c.Method = "POST"
	body, _ := json.Marshal(c.Body)
	// 创建请求
	req, err := http.NewRequest(c.Method, c.Url, strings.NewReader(string(body)))
	if err != nil {
		return "", errors.New("创建请求失败:" + err.Error())
	}
	// 设置headers
	for k, v := range c.Headers {
		req.Header.Add(k, v)
	}
	// 发送请求
	resp, err := c.Client.Do(req)
	if err != nil {
		return "", errors.New("发送请求失败:" + err.Error())
	}
	// 关闭响应
	defer resp.Body.Close()
	// 解析响应
	response, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", errors.New("解析响应失败:" + err.Error())
	}
	return string(response), nil
}

测试案例

go
package main

import (
	"fmt"
	"go_api/utils/curl"
	"testing"
)

var url = "http://127.0.0.1:8100"

func TestEnv(t *testing.T) {
	response, err := curl.NewCurl(url + "/v1/login/env").Get()
	if err != nil {
		t.Errorf("request error: %v", err)
	}
	fmt.Println(response)
}

func TestLogin(t *testing.T) {
	response, err := curl.NewCurl(url + "/v1/login/account").
		SetBody(map[string]interface{}{
			"username": "admin",
			"password": "123456",
		}).Post()
	if err != nil {
		t.Errorf("request error: %v", err)
	}
	fmt.Println(response)
}

运行测试

测试参数

  • -v 显示详细测试日志(verbose),包括每个测试用例的运行结果、耗时等。
  • -run TestXxx 运行指定的测试方法; 例如 -run TestLogin 只运行 TestLogin 方法。
  • -cover 覆盖率测试,显示测试覆盖率百分比。
  • -count n 重复运行测试 n 次,默认值为 1。
  • -failfast 快速失败模式,当第一个测试用例失败时,立即停止测试。
  • -coverprofile=coverage.out 生成覆盖率报告
go
// 显示详细报告
go test -v
// 运行Env和Login测试方法
go test -run "Env|Login"
// 运行次数为5次
go test -count 5

// 显示覆盖率
go test -cover
// 生成覆盖率报告
go test -coverprofile=coverage.out
// 查看覆盖率报告
go tool cover -html=coverage.out