I'm currently writing a Java Client Server Application. So i want to implement two Libraries, one for the Client and one for the Server. The Client Server Communication has a very strict protocol, that I wan't to test with JUnit.
As build tool im using Maven and a Husdon Server for continues Integration.
Actually I do not have any good Idea how to test these Client / Server Libraries.
I got following Approaches:
Just write a Dummy Client for testing the server and write a Dummy Server to test the Client.
Disadvantages: Unfortunately this will result in many extra work. I could not be 100% sure that client and Server could work together, because I'm not sure that the Tests are completely identical.
Write an separate Test Project that Tests the Client and the Server together.
Disadvantages: The Unit Tests does not belong to the Project it self, so Hudson will not run them automatically. Everyone who changes anything at one of these Libraries, will have to run the Tests manually to ensure, everything is correct. Also i will not receive any Code Coverage Report.
Are there any better approaches to test codes like that?
Maybe test a Maven Multi Module Project, or something like that.
I hope any one got a good solution for that Issue.
Thanks.
Think of all your code as "transforms input to output": X -> [A] -> Y
X
is the data that goes in, [A]
is the transformer, Y
is the output. In your case, you have this setup:
[Client] -> X -> [Server] -> Y -> [Client]
So the unit tests work like this:
You need a test that runs the client code to generate X
. Verify that the code actually produces X
with an assert. X
should be a final static String
in the code.
Use the constant X
in a second test to call the server code which transforms it into Y
(another constant).
A third test makes sure that the client code can parse the input Y
This way, you can keep the tests independent and still make sure that the important parts work: The interface between the components.
My suggestion would be to use two levels of testing:
For your client/server project, include some mocking in your unit tests to ensure the object interfaces are working as expected.
Following the build, have a more extensive integration test run, with automation to install the compiled client and server on one or more test systems. Then you can ensure that all the particulars of the protocol are tested thoroughly. Have this integration test project triggered on each successful build of the client/server project. You can use JUnit for this and still receive the conventional report from Hudson.
So finally the resolution was to build a Multi Module Project, with a separate Test Module that includes the Server and the Client Module
Works great in Husdon. And even better in the Eclipse IDE.
Thanks @ Aaron for the hint
The latest approach to solve this problem is by using Docker containers. Create a docker file containing a base image and all the necessary dependencies required for your client server application. Create a separate container for each node type of your distributed client-server system and test all the entry point server API/client interactions using TestNG or JUnit. The best part of this approach is that you are not mocking any service calls. In most cases you can orchestrate all the end-to-end client-server interactions.
There is a little bit of learning curve involved in this approach but Docker is becoming highly popular in the Dev community especially for solving this problem.
Here is an example of how you could use docker client api to pull docker images in your JUnit test:
https://github.com/influxdb/influxdb-java/blob/master/src/test/java/org/influxdb/InfluxDBTest.java
You may use any mock object framework to create mock objects - Try jmockit.