关于golang代码测试的形式化逻辑测试

一些想法

  1. 可被验证的逻辑才是强壮的逻辑
  2. 可被逻辑测试的代码才是高质量的代码,如果一段代码功能很强,能做很多事情,但是,无法被测试和验证,那么,或许某个瞬间,会出现,我们无法识别的问题。
  3. 大家公认的POW共识很强大了,认为这个世界不可能存在51%的攻击力了,但是,谁知道呢?
  4. 要么崩溃,要么就是可以被验证,不要保留隐藏的状态

关于golang的测试框架

  1. golang的测试框架有很多,但是大部分的测试框架都是关于断言的,对于怎么更好的测试自己的代码,很多框架并没有说明
  2. 测试框架本身并不重要,重要的,怎么更好的验证自己代码的逻辑是否有问题
  3. 代码可以简单的抽象为一组输入输出函数,正确的输入,必然得到正确的输出,错误的输出,必然可以验证错误的输入

伪代码

func TimeoutWith(dur time.Duration, fn func()) error {
	if dur < 0 {
		return ErrDurZero
	}

	if fn == nil {
		return ErrParamIsNil
	}

	var ch = make(chan error, 1)
	go func() {
		defer func() {
			if err := recover(); err != nil {
				switch err := err.(type) {
				case error:
					ch <- err
				default:
					ch <- fmt.Errorf("%s", err)
				}
			}
		}()
		fn()
		ch <- nil
	}()

	select {
	case err := <-ch:
		return err
	case <-time.After(dur):
		return ErrFuncTimeout
	}
}

func (t *xtestFixture) TestTimeoutWith() {
	var err1 = errors.New("hello")
	fn := TestFuncWith(func(dur time.Duration, fn func()) error {
		err := TimeoutWith(dur, fn)
		t.So(SliceOf(nil, ErrParamIsNil, ErrFuncTimeout, ErrDurZero, err1), ShouldContain, err)

		switch err {
		case ErrParamIsNil:
			t.So(fn, should.Equal, nil)
		case ErrFuncTimeout:
			t.So(CostWith(fn), should.BeGreaterThan, dur)
		case ErrDurZero:
			t.So(dur, should.BeLessThan, 0)
		}
		return err
	})
	fn.In(time.Duration(-1), time.Millisecond*10)
	fn.In(
		nil,
		func() {},
		func() {
			time.Sleep(time.Millisecond * 20)
		},
		func() {
			panic(err1)
		},
	)
	t.So(fn.Do(), should.BeNil)
}

比如上面的那段代码,我们对TimeoutWith,超时函数进行测试。参数为超时时间,需要执行的函数。该超时函数,只有一个err的返回结果。下面,我们对该函数进行逻辑验证测试。

  1. 输入,首先根据参数个数,以及参数本身的限制,定制输入,输入不仅要考虑正确的数据,还需要考虑错误的,甚至超过范围的数据
  2. 输出,根据函数逻辑的所有的输出信息,以及错误信息,对错误信息和正确的输出信息进行逻辑验证
  3. 验证,对输入信息,输出信息,以及以及错误信息进行参数验证
posted @ 2020-06-16 18:17  白云辉  阅读(288)  评论(0编辑  收藏  举报