I was following some of the tutorial for creating bidirectional grpc client and server. Client will pass some value and when last maximum value changed on server it'll response client with current max. Finally I'd like to write down some of the test cases but I have no experience with testing scenarios that's why I'm not sure if I'm doing the correct thing or not.
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
}
Right now when I test this scenario wiht go test
it passes but I also want to test if something received from server side.
My second question was If I want to tear this test to different scenarios for example to check is server connected or is stream connected or it received response from server side, how can I do that? Should I create another class to retrieve connection and streaming and use on test functions?
Create a contest with timeout context.WithTimeout
, and after sending your data call Recv
on the stream. Check if you receive anything within the timeout.
The specifics depend on the protocol here - you may need a goroutine to Recv
if you have to send server data at the same time.
As for your second question, the Go philosophy is to have clear, explicit, readable tests for each scenario. It's OK if some code is duplicated. It's much more important that each test in isolation is readable and understandable. In cases where the tests are very repetitive one should use table driven tests, but in the cases you describe that sounds like separate tests to me.
It's useful to have tests that "build up" functionality. One test to test connection, the other connection and sending, yet another connection and sending and receiving. This way when tests fail, by rerunning them individually you can very quickly isolate the problem even before you look at the tests' code.