我想测试一个用Go语言编写的gRPC服务,我使用的例子是grpc-go repo中的Hello World服务器。
protobuf定义如下:
syntax = "proto3";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
而greeter_server
main中的类型是:
// server is used to implement helloworld.GreeterServer.
type server struct{}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}
我已经找了很多例子,但是没有找到任何关于如何在Go语言中实现gRPC服务测试的例子。
8条答案
按热度按时间4jb9z9bj1#
我认为您正在寻找
google.golang.org/grpc/test/bufconn
包来帮助您避免使用真实的的端口号启动服务,但仍然允许测试流RPC。这种方法的好处是,你仍然可以获得网络行为,但通过内存连接,而不需要使用操作系统级别的资源,如端口,这些资源可能会也可能不会很快清理干净。它允许你以实际使用的方式测试它,并为你提供正确的流行为。
我并没有一个流媒体的例子,但是它的神奇之酱料就在上面。它提供了一个正常网络连接的所有预期行为。诀窍是设置WithDialer选项,如图所示,使用bufconn包创建一个监听器,它公开了自己的拨号器。我一直在使用这种技术来测试gRPC服务,效果很好。
vmjh9lq92#
如果您想验证gRPC服务的实现是否如您所期望的那样,那么您可以只编写标准单元测试并完全忽略网络。
例如,使
greeter_server_test.go
:我可能在记忆中把proto语法弄得有点乱,但这就是我的想法。
cnwbcb6i3#
这里可能是一个简单的方法只是测试流媒体服务。抱歉,如果有任何错字的,因为我改编了一些运行代码。
给定以下定义。
使用以下服务器端代码。
现在您所要做的就是在测试文件中模拟pb.SitesService_ListSitesServer。
这会回应**.send事件,并将传送的对象记录在.Results中,然后您可以在assert陈述式中使用。
最后,使用pb.SitesService_ListSitesServer**的模拟实现调用服务器代码。
不,它不测试整个堆栈,但它确实允许您对服务器端代码进行健全性检查,而不必为真实的或模拟形式运行完整的gRPC服务而烦恼。
bt1cpqcv4#
我提出了下面的实现,但这可能不是最好的实现方式。主要是使用
TestMain
函数来启动服务器,使用一个 goroutine:然后在其余测试中实现客户端:
bzzcjhmw5#
测试gRPC服务的方法有很多种。您可以选择不同的测试方法,这取决于您希望获得的可靠性。下面是三个示例,说明一些常见的情况。
Case #1:我想测试我的业务逻辑
在这种情况下,您感兴趣的是服务中的逻辑以及它如何与其他组件交互。
Alex Ellis有一个很好的introduction to unit testing in Go。如果你需要测试交互,那么GoMock是一个很好的方法。Sergey Grebenshchikov写了一个很好的GoMock tutorial。
Omar给出的答案显示了如何对这个特定的
SayHello
示例进行单元测试。案例#2:我想通过网络手动测试我的实时服务的API
在这种情况下,您希望手动对API进行探索性测试。通常,这样做是为了探索实现,检查边缘情况,并确信API的行为符合预期。
您需要:
1.启动gRPC服务器
1.使用网络模拟解决方案来模拟您拥有的任何依赖项,例如,如果您的gRPC服务在测试中对另一个服务进行gRPC调用。例如,您可以使用Traffic Parrot。
1.使用gRPC API测试工具。例如,您可以使用gRPC CLI。
现在,您可以使用模拟解决方案来模拟真实的和假设的情况,同时通过使用API测试工具来观察被测服务的行为。
案例#3:我希望通过网络自动测试我的API
在这种情况下,您对编写自动化的BDD风格的验收测试感兴趣,这些测试通过有线gRPC API与被测系统交互。这些测试的编写、运行和维护成本很高,应该谨慎使用,记住testing pyramid。
thinkerou的答案展示了如何使用karate-grpc用Java编写这些API测试。您可以将其与Traffic Parrot Maven插件结合使用来模拟任何跨线依赖。
kh212irz6#
顺便说一句:作为一个新的贡献者,我不能添加到评论。所以我在这里添加一个新的答案。
我可以确认,通过在没有运行服务的情况下通过接口进行测试,@Omar方法适用于测试非流式gRPC服务。
但是这种方法对流不起作用,因为gRPC支持双向流,所以需要启动服务并通过网络层连接到它来测试流。
joscas采用的方法适用于gRPC流(尽管helloworld示例代码没有使用流)使用goroutine来启动服务,但是我注意到在MacOSX10.11.6上,当从goroutine调用服务时,它并没有释放服务所使用的端口(据我所知,这个服务会阻塞goroutine,而且可能不会干净地退出)通过启动一个单独的进程让服务在其中运行,使用'exec. command',并在完成之前杀死它,端口始终被释放。
我使用流将gRPC服务的工作测试文件上传到github:https://github.com/mmcc007/go/blob/master/examples/route_guide/server/server_test.go
您可以看到Travis上运行的测试:https://travis-ci.org/mmcc007/go
请让我知道,如果任何建议,如何改善测试的gRPC服务。
46scxncf7#
作为一个新的贡献者,我不能发表评论,所以我在这里添加作为一个答案。
@shiblon的答案是测试你的服务的最好方法。我是 * grpc-for-production * 的维护者,其中一个特性是一个正在处理的服务器,这使得使用bufconn更容易。
下面是一个测试迎宾服务的示例
您可以找到以下示例here
myss37ts8#
您可以使用
karate-grpc
来测试grpc服务,您只需要发布您proto jar和grpc服务器ip/port.karate-grpc
构建(基于空手道和多语制)。一个地狱世界的例子:
关于空手道的例子-grpc评论:
而且它会生成漂亮的报告,比如:
更多详情请参见:https://thinkerou.com/karate-grpc/