我正在学习一些创建双向grpc客户端和服务器的教程。客户端将传递一些值,当服务器上的最后一个最大值发生变化时,它将以当前最大值响应客户端。最后,我想写下一些测试用例,但我没有测试场景的经验,这就是为什么我不确定我是否正在做正确的事情。
func TestClientConnection(t *testing.T) {
creds, _ := credentials.NewClientTLSFromFile("../server-cert.pem", "")
conn, err := grpc.Dial(address, grpc.WithTransportCredentials(creds))
if err != nil {
t.Error("Had problem with connection, NOT PASSED")
}
defer conn.Close()
c := proto.NewHerdiusServerClient(conn)
stream, err := c.CheckMax(context.Background())
if err != nil {
t.Error("Had problem with stream, NOT PASSED")
return
}
err = stream.Send(&proto.MaxRequest{Val: int32(10)})
err = stream.Send(&proto.MaxRequest{Val: int32(12)})
err = stream.Send(&proto.MaxRequest{Val: int32(13)})
err = stream.Send(&proto.MaxRequest{Val: int32(9)})
if err != nil {
t.Error("Had problem with stream, NOT PASSED")
return
}
return
}
现在,当我测试这个场景时,go test
它通过但我也想测试从服务器端收到的东西。
我的第二个问题是,如果我想将此测试分解为不同的场景,例如检查服务器已连接或流连接或是否收到服务器端的响应,我该怎么做?我应该创建另一个类来检索连接和流并在测试函数上使用吗?
创建一个超时context.WithTimeout
的比赛,并在流上发送数据调用Recv
。检查是否在超时内收到任何内容。
具体取决于此处的协议 - 如果您必须同时发送服务器数据,则可能需要goroutine到Recv
。
至于你的第二个问题,Go哲学是为每个场景提供清晰,明确,可读的测试。如果某些代码重复,则可以。更重要的是,每个单独的测试都是可读和可理解的。如果测试非常重复,应该使用table driven tests,但在你描述的情况下,这听起来像是对我的单独测试。
进行“构建”功能的测试很有用。一个测试测试连接,另一个连接和发送,另一个连接和发送和接收。这样,当测试失败时,通过单独重新运行它们,即使在查看测试代码之前,您也可以非常快速地隔离问题。