{"id":22153033,"url":"https://github.com/pecker-io/karate-grpc","last_synced_at":"2025-08-31T22:38:19.608Z","repository":{"id":38022009,"uuid":"148622188","full_name":"pecker-io/karate-grpc","owner":"pecker-io","description":"gRPC Testing Made Simple by Karate","archived":false,"fork":false,"pushed_at":"2023-08-22T09:53:14.000Z","size":2196,"stargazers_count":49,"open_issues_count":13,"forks_count":32,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-11-17T13:09:41.559Z","etag":null,"topics":["grpc","grpc-java","grpc-testing","java","karate","karate-grpc","protobuf","test-automation","testing"],"latest_commit_sha":null,"homepage":"https://pecker-io.github.io/karate-grpc/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pecker-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-13T10:30:14.000Z","updated_at":"2024-11-12T07:52:49.000Z","dependencies_parsed_at":"2024-06-19T02:58:37.163Z","dependency_job_id":null,"html_url":"https://github.com/pecker-io/karate-grpc","commit_stats":null,"previous_names":["thinkerou/karate-grpc"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pecker-io%2Fkarate-grpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pecker-io%2Fkarate-grpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pecker-io%2Fkarate-grpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pecker-io%2Fkarate-grpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pecker-io","download_url":"https://codeload.github.com/pecker-io/karate-grpc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227580484,"owners_count":17789268,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grpc","grpc-java","grpc-testing","java","karate","karate-grpc","protobuf","test-automation","testing"],"created_at":"2024-12-02T01:16:18.400Z","updated_at":"2024-12-02T01:16:19.614Z","avatar_url":"https://github.com/pecker-io.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# karate-grpc\n\n[![Build Status](https://api.travis-ci.org/thinkerou/karate-grpc.svg)](https://travis-ci.org/thinkerou/karate-grpc) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.thinkerou/karate-grpc-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.thinkerou/karate-grpc-core/)\n\nsimple gRPC testing with [karate](https://github.com/intuit/karate) and a dynamic client using [polyglot](https://github.com/grpc-ecosystem/polyglot).\n\nkarate-grpc makes it easy to:\n* build complex protobuf request payloads via json\n* traverse data within the responses \n* chain data from responses into the next request.\n\n## Hello World\n\n[![karate-grpc-hello-world](assets/karate-grpc-hello-world.png)](assets/karate-grpc-hello-world.png)\n\n## Testing hello world\nRequires maven to be installed\n```\n$ # compile and test the whole project\n$ mvn clean install\n\n$ # test demo\n$ cd karate-grpc-demo\n$ mvn test\n$ # or run single test\n$ mvn test -Dtest=HelloWorldNewRunner\n```\n\nWhen running tests, the hello world grpc server is started/stopped automatically in `AbstractTestBase.java`.\n\nKarate also generates beautiful test reports:\n\n[![karate-grpc-hello-world-report](assets/karate-grpc-hello-world-report.png)](assets/karate-grpc-hello-world-report.png)\n\n## Real World Examples\n\nA set of real-life examples which includes `single rpc`, `client stream rpc`, `server stream rpc` and `bidi stream rpc` can be found here: [karate-grpc-demo](karate-grpc-demo)\n\n## Getting Started\n\nkarate-grpc requires Java 8 and then Maven to be installed, these also are required by [karate](https://github.com/intuit/karate) and [polyglot](https://github.com/grpc-ecosystem/polyglot).\n\n\u003e karate-grpc only support Maven currently.\n\n### Maven\n\nYou need to add the following `\u003cdependencies\u003e`:\n\n```maven\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.thinkerou\u003c/groupId\u003e\n    \u003cartifactId\u003ekarate-grpc-core\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.7\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Gradle\n\n\u003e TODO: need to test!!!\n\nAlternatively for Gradle you need to add the following entry:\n\n```gradle\ntestImplementation 'com.github.thinkerou:karate-grpc-core:1.0.7'\n```\n\nAnd simulates `karate-grpc-helper` and `karate-grpc-demo` build your redis helper project and test project.\n\n## What to need for testing grpc server\n\nTesting one grpc server, we have the follow info:\n\n- grpc server `ip` and `port`.\n\n- (optional) protobuf file corresponding grpc server, but usually it's protobuf `jar package` not one single file or more files.\n\nSo, we could test it based on the two point.\n\n**⚠️ Using karate-grpc we can perfect to solve it!**\n\n## What to need in pom file\n\nFor testing your grpc server, as above, need protobuf jar dependency and protobuf build plugins - [`protobuf-maven-plugin`](https://www.xolstice.org/protobuf-maven-plugin/).\n\n**MUST** appoint `descriptorSetFileName` and `protoSourceRoot` params:\n\n```\n\u003cdescriptorSetFileName\u003ekarate-grpc.protobin\u003c/descriptorSetFileName\u003e\n\u003cprotoSourceRoot\u003e${project.build.directory}/dependency/demo\u003c/protoSourceRoot\u003e\n```\n\nEspecially, `descriptorSetFileName` **MUST** equal `karate-grpc.protobin`, please see [here](karate-grpc-core/src/main/java/com/github/thinkerou/karate/constants/DescriptorFile.java) about more details.\n\nAnd other pom settings are the same as `karate`.\n\n## How to write karate feature\n\nWe need to use [Java interop](https://github.com/intuit/karate#java-interop) of Karate in order to call us define grpc client.\n\nAnd use `JSON.parse` javascript function parse the response of grpc server return value.\n\nSo, use `karate-grpc` need the following steps:\n\n1. Calls into karate-grpc GrpcClient via Java Interop.\n\n```\n* def GrpcClient = Java.type('com.github.thinkerou.karate.GrpcClient')\n```\n\n2. Builds one public Grpc client using your grpc ip and port.\n\n```\n* def client = new GrpcClient('localhost', 50051)\n```\n\nIf you want to list protobuf by service name or/and message name, you should use:\n\n```\n* def client = new GrpcClient()\n```\n\nBecause you don't need grpc server ip/port when listing protobuf.\n\n3. Reads JSON data corresponding your protobuf definition.\n\n4. Calls your Grpc server using `call` of karate-grpc.\n\n```\n* def response = client.call('helloworld.Greeter/SayHello', payload, karate)\n```\n\n`call` has two required params, and one optional\n\n1. protobuf full name(`format:\u003cpackage-name\u003e.\u003cservice-name\u003e/\u003crpc-name\u003e`) \n2. JSON data.\n3. `karate` (optional, nullable) -- if present, will add `[request]` and `[response]` to html report. `karate` variable is of type ScenarioBridge and is automatically created when running karate tests.\n\n[![request-response-report](assets/request-response-report.png)](assets/request-response-report.png)\n\n\nIf you input protobuf full name error, `call` will fail and output protobuf message by `list`, like this:\n\nWhen input `helloworld.Greeter/SayHello1`, it will fail and print log:\n\n```\nOct 11, 2018 6:53:24 PM com.github.thinkerou.karate.service.GrpcCall invoke\n警告: Call grpc failed, maybe you should see the follow grpc information.\nOct 11, 2018 6:53:24 PM com.github.thinkerou.karate.service.GrpcCall invoke\n信息: [\n  {\n    \"helloworld.Greeter/SayHelloBiStreaming\":\"\",\n    \"helloworld.Greeter/RecordRoute\":\"\",\n    \"helloworld.Greeter/RouteChat\":\"\",\n    \"helloworld.Greeter/SayHelloServerStreaming\":\"\",\n    \"helloworld.Greeter/ListFeatures\":\"\",\n    \"helloworld.Greeter/SayHello\":\"\",\n    \"helloworld.Greeter/AgainSayHello\":\"\",\n    \"helloworld.Greeter/SayHelloClientStreaming\":\"\",\n    \"helloworld.Greeter/GetFeature\":\"\"\n  }\n]\n\n```\n\n5. Converts response string to JSON.\n\n```\n* def response = JSON.parse(response)\n```\n\nBecause `call` of karate-grpc returns JSON string, we need to convert it and then can use `match` assertion.\n\n6. Asserts payload.\n\n7. (Optional) Saves response for second Grpc.\n\nIf have second Grpc use the response of first Grpc, we should save it, like:\n\n```\n* def message = response[0].message\n```\n\nAnd use it on JSON file:\n\n```\n[\n  {\n    \"message\": \"#(message)\",\n    \"address\": \"BeiJing\"\n  }\n]\n```\n\n8. (Optional) Second Grpc call using response data before.\n\nOne whole example likes [this](karate-grpc-demo/src/test/java/demo/helloworld/helloworld-new.feature):\n\n```\nFeature: grpc helloworld example by grpc dynamic client\n\n  Background:\n    * def client = Java.type('demo.DemoGrpcClientSingleton').INSTANCE.getGrpcClient();\n\n  Scenario: do it\n    * string payload = read('helloworld.json')\n    * def response = client.call('helloworld.Greeter/SayHello', payload)\n    * def response = JSON.parse(response)\n    * print response\n    * match response[0].message == 'Hello thinkerou'\n    * def message = response[0].message\n\n    * string payload = read('again-helloworld.json')\n    * def response = client.call('helloworld.Greeter/AgainSayHello', payload)\n    * def response = JSON.parse(response)\n    * match response[0].details == 'Details Hello thinkerou in BeiJing'\n```\n\n### How to write JSON file\n\nBecause `karate-grpc` supports stream grpc, we use `list` JSON.\n\nInput JSON file like:\n\n```\n[\n  {\n    \"name\": \"thinkerou\"\n  },\n  {\n    \"name\": \"thinkerou2\"\n  }\n]\n```\n\nOutput JSON string also like:\n\n```\n[\n  {\n    \"message\": \"Hello thinkerou\"\n  },\n  {\n    \"message\": \"Hello thinkerou2\"\n  }\n]\n```\n\n**That's all!!!**\n\n## Redis\n\n### Why use Redis?\n\nUsing redis is optional, but caching descriptor sets may save compile time, especially when your project has many protobuf jar package dependencies.\n\n### Mock Redis\nYou can even use jedis-mock so you don't even need to install Redis.\nsee [MockRedisHelperSingleton.java](karate-grpc-core/com/github/thinkerou/karate/utils/MockRedisHelperSingleton.java): \n\n### Redis performance\n\u003ci\u003eNote: while the redis test implementation is thread-safe, Redis uses single-threaded execution so test performance may be degraded for high concurrency.\u003c/i\u003e  \n\nTo use redis, use class `com.github.thinkerou.karate.RedisGrpcClient` instead of `com.github.thinkerou.karate.GrpClient`\n\n[example](karate-grpc-demo/src/test/java/demo/helloworld/helloworld-new.feature):\n\n```\npublic enum DemoGrpcClientSingleton {\n    INSTANCE;\n\n    RedisGrpcClient redisGrpcClient;\n\n    public GrpcClient getGrpcClient() {\n        return redisGrpcClient;\n    }\n\n    DemoGrpcClientSingleton() {\n        redisGrpcClient = new RedisGrpcClient(\"localhost\", 50051, MockRedisHelperSingleton.INSTANCE.getRedisHelper());\n    }\n}\n```\n**TODO:**\n\n- Save `ProtoFullName|InputType|InputMessage|OutputType|OutputMessage|ProtoFileName|RPCAddress` not file content.\n- Support java reflection mode.\n\n## How to write grpc client\n\n**Note:**\n\n\u003e - The part content is outdated draft which initially think about the topic which continues to have saved is for reference only.\n\u003e - Usually you no need to care it and skip it, because `karate-grpc-core` have completed the function.\n\nYou only need two steps:\n\n- Read json file and parse protobuf object to the request of grpc server\n\n- format the response of grpc server to json string and return it as grpc server\n\nLike this:\n\n```java\npublic class Client {\n\n  // ...\n\n  public static String greet(String input) {\n    HelloRequest.Builder requestBuilder = HelloRequest.newBuilder();\n    try {\n      JsonFormat.parser().merge(input, requestBuilder);\n    } catch (ProtocolBufferException e) {\n      // ...\n    }\n\n    HelloReply response = null;\n    try {\n      response = blockingStub.sayHello(requestBuilder.build());\n    } catch (StatusRuntimeException e) {\n      // ...\n    }\n\n    String res = \"\";\n    try {\n      res = JsonFormat.printer().print(response);\n    } catch (ProtocolBufferException e) {\n      // ...\n    }\n\n    return res;\n  }\n\n  // ...\n}\n\n```\n\n\n## Thanks \n\nThanks [Peter Thomas](https://github.com/ptrthomas) for his work for [karate](https://github.com/intuit/karate) and his generous help, also thanks [Dino Wernli](https://github.com/dinowernli) for his contributions for [polyglot](https://github.com/grpc-ecosystem/polyglot). And the favicon of organization generate at [favicon.io](https://favicon.io/).\n\n## Reference\n\nMaybe you want to know more information about Karate or other, please read the follow contents:\n\n- karate project home: [https://github.com/intuit/karate](https://github.com/intuit/karate)\n\n- polyglot project home: [https://github.com/grpc-ecosystem/polyglot](https://github.com/grpc-ecosystem/polyglot)\n\n- ProtoBuf(via JSON) project home: [https://github.com/protocolbuffers/protobuf/tree/master/java](https://github.com/protocolbuffers/protobuf/tree/master/java)\n\n- grpc-java project home: [https://github.com/grpc/grpc-java](https://github.com/grpc/grpc-java)\n\n## License\n\n[karate-grpc](https://thinkerou.com/karate-grpc/) is licensed under MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpecker-io%2Fkarate-grpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpecker-io%2Fkarate-grpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpecker-io%2Fkarate-grpc/lists"}