golang BDD兼容的分支测试框架插件库biff的使用

Golang BDD兼容的分支测试框架插件库biff的使用

简介

Biff是一个基于嵌套用例或替代方案的分支框架(BIFurcation Framework)。您可以利用变量作用域使测试更简单、更易读。它是验收和用例测试的良好选择,提供BDD风格的输出。

Biff Logo

快速开始

以下是一个完整的biff使用示例:

package main

import (
	"github.com/fulldump/biff"
)

// 示例服务
type MyService struct {
	users map[string]*User
}

type User struct {
	Email    string
	Password string
}

func NewMyService() *MyService {
	return &MyService{
		users: make(map[string]*User),
	}
}

func (s *MyService) RegisterUser(email, password string) *User {
	user := &User{Email: email, Password: password}
	s.users[email] = user
	return user
}

func (s *MyService) Login(email, password string) *User {
	user, exists := s.users[email]
	if !exists || user.Password != password {
		return nil
	}
	return user
}

func main() {
	// Biff测试示例
	biff.Alternative("Instance service", func(a *biff.A) {

		s := NewMyService()

		a.Alternative("Register user", func(a *biff.A) {

			john := s.RegisterUser("john@email.com", "john-123")
			a.AssertNotNil(john)

			a.Alternative("Bad credentials", func(a *biff.A) {
				user := s.Login(john.Email, "bad-password")
				a.AssertNil(user)

			}).Alternative("Login", func(a *biff.A) {
				user := s.Login(john.Email, john.Password)
				a.AssertEqual(user, john)
			})

		})
	})
}

测试输出示例:

=== RUN   TestExample
Case: Instance service
Case: Register user
    john is &example.User{Email:"john@email.com", Password:"john-123"}
Case: Bad credentials
    user is <nil>
-------------------------------
Case: Instance service
Case: Register user
    john is &example.User{Email:"john@email.com", Password:"john-123"}
Case: Login
    user is &example.User{Email:"john@email.com", Password:"john-123"}
-------------------------------
Case: Instance service
Case: Register user
    john is &example.User{Email:"john@email.com", Password:"john-123"}
-------------------------------
Case: Instance service
-------------------------------
--- PASS: TestExample (0.00s)
PASS

错误定位

当出现错误时,Biff会直接定位到出错的行:

Case: Instance service
Case: Register user
    john is &example.User{Email:"john@email.com", Password:"john-123"}
Case: Login
    Expected: &example.User{Email:"maria@email.com", Password:"1234"}
    Obtained: &example.User{Email:"john@email.com", Password:"john-123"}
    at biff/example.TestExample.func1.1.2(0xc420096ac0
    /home/fulldump/workspace/my-project/src/example/users_test.go:84 +0x12

特性

  1. 隔离的用例:所有可能的分支都以隔离的方式测试

  2. 动态BDD:不需要将测试行为翻译成自然语言。Biff会遍历执行堆栈并解析部分测试代码以漂亮地打印断言

  3. 利用Go函数作用域:避免使用测试助手和辅助方法来维护测试之间的状态,利用语言变量作用域本身编写强大、易写易读的测试

支持的断言

最常用的断言已实现:

  • AssertEqual
  • AssertEqualJson
  • AssertNil
  • AssertNotNil
  • AssertNotEqual
  • AssertInArray
  • AssertTrue
  • AssertFalse

贡献

欢迎fork、修改并向master分支提交pull request。如果您愿意,也可以创建新issue或通过电子邮件联系我获取新功能、问题或其他任何内容。

测试

目前还没有测试,但很快就会有了。

示例项目

该项目包含一个示例项目,包含一些简单的业务逻辑和一些Biff测试。


更多关于golang BDD兼容的分支测试框架插件库biff的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang BDD兼容的分支测试框架插件库biff的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang BDD兼容的分支测试框架插件库biff使用指南

biff是一个轻量级的Golang测试框架,它支持行为驱动开发(BDD)风格的分支测试,可以帮助开发者编写更清晰、更具表达力的测试代码。

安装biff

go get github.com/fulldump/biff

基本用法

1. 简单断言

package main

import (
	"testing"
	"github.com/fulldump/biff"
)

func TestAddition(t *testing.T) {
	biff.AssertEqual(2+2, 4)
}

2. BDD风格测试

func TestCalculator(t *testing.T) {
	biff.Describe("Calculator", func(a *biff.A) {
		a.Describe("Addition", func(b *biff.A) {
			b.It("should add two numbers correctly", func(c *biff.A) {
				result := 2 + 3
				c.AssertEqual(result, 5)
			})
		})

		a.Describe("Subtraction", func(b *biff.A) {
			b.It("should subtract two numbers correctly", func(c *biff.A) {
				result := 5 - 3
				c.AssertEqual(result, 2)
			})
		})
	})
}

3. 表格驱动测试

func TestTableDriven(t *testing.T) {
	testCases := []struct {
		name     string
		input    int
		expected int
	}{
		{"case 1", 1, 1},
		{"case 2", 2, 4},
		{"case 3", 3, 9},
	}

	for _, tc := range testCases {
		biff.Test(tc.name, func(a *biff.A) {
			result := tc.input * tc.input
			a.AssertEqual(result, tc.expected)
		})
	}
}

高级特性

1. 异步测试

func TestAsync(t *testing.T) {
	biff.Describe("Async operations", func(a *biff.A) {
		a.It("should handle async calls", func(b *biff.A) {
			done := make(chan bool)
			
			go func() {
				// 模拟异步操作
				time.Sleep(100 * time.Millisecond)
				done <- true
			}()
			
			b.Await(done, true, "Expected async operation to complete")
		})
	})
}

2. 测试前后钩子

func TestWithHooks(t *testing.T) {
	var db *someDatabase // 假设的数据库连接
	
	biff.Describe("Database tests", func(a *biff.A) {
		a.Before(func() {
			// 测试前初始化
			db = connectToDB()
		})
		
		a.After(func() {
			// 测试后清理
			db.Close()
		})
		
		a.It("should query data", func(b *biff.A) {
			result, err := db.Query("SELECT * FROM users")
			b.AssertNil(err)
			b.AssertNotNil(result)
		})
	})
}

3. 自定义断言

func TestCustomAssertion(t *testing.T) {
	biff.Describe("Custom assertions", func(a *biff.A) {
		a.It("should validate email format", func(b *biff.A) {
			email := "test@example.com"
			b.Assert("email should contain @", strings.Contains(email, "@"))
		})
	})
}

最佳实践

  1. 描述性命名:使用清晰的描述来说明测试的目的
  2. 分层结构:利用Describe/It嵌套来组织测试
  3. 单一职责:每个测试用例只验证一件事
  4. 表格驱动:对相似测试用例使用表格驱动测试
  5. 清理资源:使用After/Before钩子管理测试资源

与其他测试框架比较

biff相比标准库的testing包和Ginkgo等BDD框架有以下特点:

  • 更轻量级
  • 更简单的API
  • 内置断言库
  • 支持BDD风格但不强制
  • 良好的错误报告

总结

biff为Golang提供了一个简单而强大的BDD兼容测试解决方案。它的分层结构和丰富的断言方法使得测试代码更易读、更易维护。通过结合表格驱动测试和异步支持,biff可以满足从简单单元测试到复杂集成测试的各种需求。

希望这个指南能帮助你开始在Golang项目中使用biff进行测试!

回到顶部