错误处理与单元测试是软件开发过程中保证代码质量的关键步骤。

错误处理

Go 语言对错误处理有一个独特的方法。
它没有像 JavaPython 中那样的异常机制,而是将错误作为返回值。
这强制程序员显式地处理错误,而不是依赖于异常和捕获机制。

例子:

package main

import (
	"errors"
	"fmt"
)

// 模拟一个可能出错的函数
func divide(dividend, divisor float64) (float64, error) {
	if divisor == 0 {
		return 0, errors.New("cannot divide by zero")
	}
	return dividend / divisor, nil
}

func main() {
	result, err := divide(10, 0)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Result:", result)
}

输出:

image.png

在这个例子中,divide 函数尝试除以 0,这将导致一个错误。
函数返回一个错误值,调用者检查这个值并相应地处理它。


单元测试

Go 语言中,单元测试是通过内置的 testing 包和 go test 命令来实现的。🦌🔍
单元测试允许你验证各个部分(单元)的代码是否按照预期工作。
Go 中,一个单元通常是一个函数。
为了编写一个测试,你需要创建一个以 _test.go 结尾的文件。

让我们来看一个简单的例子,你有一个函数 Add,它将两个整数相加,并返回结果。
编写一个 add.go 文件如下:

// add.go
package math

// Add 返回两个整数的和
func Add(x, y int) int {
    return x + y
}

为了测试这个 Add 函数,你会创建一个名为 add_test.go 的文件。
编写一个 add_test.go 如下:

// add_test.go
package math

import "testing"

// TestAdd 测试 math.Add 函数
func TestAdd(t *testing.T) {
    result := Add(1, 2)
    expected := 3
    if result != expected {
        t.Errorf("Add(1, 2) = %d; 期望的结果是 %d", result, expected)
    }
}

在测试文件中,你定义了一个测试函数 TestAdd
它使用 testing.T 参数,该参数提供了方法用于报告和记录测试失败。

两个文件放到同一个目录,进入该目录下。
通过运行 go test 命令,Go 会自动找到所有的测试文件和测试函数,并执行它们。

go test

输出:

image.png

修改 expected := 3expected := 4

// add_test.go
package math

import "testing"

// TestAdd 测试 math.Add 函数
func TestAdd(t *testing.T) {
    result := Add(1, 2)
    expected := 3
    if result != expected {
        t.Errorf("Add(1, 2) = %d; 期望的结果是 %d", result, expected)
    }
}

再次测试,输出为:

image.png

如果测试通过了,你通常不会看到任何输出。
如果测试失败了,go test 会打印出失败的测试和相应的错误信息。


表格驱动测试

表格驱动测试是一种组织单元测试的方法,它允许你使用相同的测试逻辑来测试不同的输入。

func TestAddTableDriven(t *testing.T) {
    var tests = []struct {
        x        int
        y        int
        expected int
    }{
        {1, 2, 3},
        {1, 1, 2},
        {2, 2, 4},
    }

    for _, tt := range tests {
        testname := fmt.Sprintf("%d+%d", tt.x, tt.y)
        t.Run(testname, func(t *testing.T) {
            ans := Add(tt.x, tt.y)
            if ans != tt.expected {
                t.Errorf("got %d, want %d", ans, tt.expected)
            }
        })
    }
}

在这个例子中,我们定义了一个测试用例的切片。
每个测试用例包含输入 xy 以及预期的结果 expected
t.Run 允许我们为每个测试用例运行一个子测试。

单元测试是提高你的代码可靠性的重要工具。
通过持续测试你的代码,你可以确保新的变更不会破坏现有的功能,并且可以快速发现和修复错误。


文章作者: Runfa Li
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Linux 小白鼠
GO 入门 GO go
觉得文章不错,打赏一点吧,1分也是爱~
打赏
微信 微信
支付宝 支付宝