douningle7944 2018-02-20 10:22
浏览 20
已采纳

如何使用标准Go测试包实施BDD实践?

I want to write tests first, then write code that makes the tests pass.

I can write tests functions like this:

func TestCheckPassword(t *testing.T) {
    isCorrect := CheckPasswordHash("test", "$2a$14$rz.gZgh9CHhXQEfLfuSeRuRrR5uraTqLChRW7/Il62KNOQI9vjO2S")

    if isCorrect != true {
        t.Errorf("Password is wrong")
    }
}

But I'd like to have more descriptive information for each test function.

For example, I am thinking about creating auth module for my app. Now, in plain English, I can easily describe my requirements for this module:

  1. It should accept a non-empty string as input.
  2. String must be from 6 to 48 characters long.
  3. Function should return true if password string fits provided hash string and false if not.

What's the way to put this information that is understandable by a non-tech business person into tests besides putting them into comments?

  • 写回答

3条回答 默认 最新

  • douwen5246 2018-02-20 11:44
    关注

    In Go, a common way of writing tests to perform related checks is to create a slice of test cases (which is referred to as the "table" and the method as "table-driven tests"), which we simply loop over and execute one-by-one.

    A test case may have arbitrary properties, which is usually modeled by an anonymous struct.
    If you want to provide a description for test cases, you can add an additional field to the struct describing a test case. This will serve both as documentation of the test case and as (part of the) output in case the test case would fail.

    For simplicity, let's test the following simple Abs() function:

    func Abs(x int) int {
        if x < 0 {
            return -x
        }
        return x
    }
    

    The implementation seems to be right and complete. If we'd want to write tests for this, normally we would add 2 test cases to cover the 2 possible branches: test when x is negative (x < 0), and when x is non-negative. In reality, it's often handy and recommended to also test the special 0 input and the corner cases: the min and max values of the input.

    If we think about it, this Abs() function won't even give a correct result when called with the minimum value of int32, because that is -2147483648, and its absolute value is 2147483648 which doesn't fit into int32 because max value of int32 is: 2147483647. So the above implementation will overflow and incorrectly give the negative min value as the absolute of the negative min.

    The test function that lists cases for each possible branches plus includes 0 and the corner cases, with descriptions:

    func TestAbs(t *testing.T) {
        cases := []struct {
            desc string // Description of the test case
            x    int32  // Input value
            exp  int32  // Expected output value
        }{
            {
                desc: "Abs of positive numbers is the same",
                x:    1,
                exp:  1,
            },
            {
                desc: "Abs of 0 is 0",
                x:    0,
                exp:  0,
            },
            {
                desc: "Abs of negative numbers is -x",
                x:    -1,
                exp:  1,
            },
            {
                desc: "Corner case testing MaxInt32",
                x:    math.MaxInt32,
                exp:  math.MaxInt32,
            },
            {
                desc: "Corner case testing MinInt32, which overflows",
                x:    math.MinInt32,
                exp:  math.MinInt32,
            },
        }
    
        for _, c := range cases {
            got := Abs(c.x)
            if got != c.exp {
                t.Errorf("Expected: %d, got: %d, test case: %s", c.exp, got, c.desc)
            }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办