views:

562

answers:

8

I'm developing a small TCP server, which will process some TCP packets and behave differently based on the request.

How can I write unit test for this? If it's really hard to write, is it even worth the effort?

+2  A: 

It will be well worth it.

The number of unit tests should coincide with the type of requests (different behaviors). This will be useful when you make modifications and see if it did or did not impact other parts of the TCP Server.

YOu can mimic sending TCP packets with several available tools out there. Let me know how it goes.

CodeToGlory
Which tool do you recommend? I'm planning get a license for TypeMock but I'm not quite sure if it supports it.
dr. evil
You have to use some other tools for this purpose like http://www.netscantools.com/nstpro_packet_generator_tcp.html
CodeToGlory
A: 

I don't know anything about .net, but I can tell you about unit testing.

You need to factor things out. For example, your server might run in a thread and do some work. Where it does the work should be inside a function. You also probably have a request object. Make the tcp server's "work function" take the request object as a parameter. Then unit test as usual: at the beginning of the test, setup the request, and pass it to the tcp server object's "work function". Don't actually have the server open sockets or anything. You are just unit testing the methods that do the work, and only testing the handling of the request. You are not testing sockets or network reliability or anything like that. You need to test that stuff differently.

Tom
+3  A: 

The first thing to do is to separate the behavior(s) from the TCP packets that are incoming. Abstract that into a dispatch table or other such thing.

Then write unit tests for each of the behaviors independent of how they were invoked. You can test the final TCP -> behavior layer with a test tool you write or borrow. That layer should be almost trivial if the code is factored properly.

Darren Clark
+1  A: 

You might take a look at NMock, a mocking library for .NET. If two parties are involved in a unit-test it's always good to just "mock" one party (the one you are not testing, in that case the Client).

This will however require some changes to your code, but believe me, it's worth it.

Marcel J.
+3  A: 

I'd try to extract the TCP-specific bit from the processing bit. Is your protocol really packet-based, or is it stream-based? If it's stream-based you can just make the processing part accept a stream (or possibly a pair of streams, one for input and one for output) and feed it with either a MemoryStream or your own similar stream implementation giving a bit more control.

Either way, you basically want to mock out the network side of things so you can test the real logic without getting the network involved at all. Testing the network layer (i.e. the thin piece of logic between the framework network classes and the processing logic) may well be a bit harder, but if you can make it thin enough there shouldn't be an awful lot to test.

Jon Skeet
Good point, he should abstract out both the packet parsing, and the logic and put unit tests around both. Using an interface for the business logic and then a mocking library lets you isolate the parsing code.
Darren Clark
A: 

I can't give you any specific helpers as your question is fairly open-ended.

However it sounds as though you'd want to write a mock server/client depending on your needs. It'd be worth looking at Rhino Mocks.

You might also want to take a look at Oren's NMemCached project which implements a cache server using a custom TCP/IP implementation. That project has some interesting unit/integration tests written using Rhino Mocks.

Codebrain
A: 

It's certainly worth the effort. What I've dome for a HTTP small server=based app I'm working on is have aseries of scripts that fire requests at the server using wget. I then usen diff to compare the saved wget output with what I expected to get, and report any fifferences. I run this bunch of scripts every time I change the server, and it has caught a lot of errors.

Obviously, this only works for HTTP servers, but it will be worth your while to write a small app that can fire TCP requests at your server and save the results.

anon
+1  A: 

If you write a TCP server, you should also be writing a client library. Unless you are doing something fancy, you can simply fire packets over the loopback adapter between your unit test and the stub server. You only need to verify that you are doing TCP properly with these tests, as the rest of your tests should, in proper unit test fashion, stub out/skip over the TCP/socket logic and jump right in to the individual unit being tested.

Doing all this is completely worth it. If you are new enough to TCP that you aren't sure how and why you should unit test it, chances are you'll make a few mistakes/faulty assumptions in how you write your TCP code, and unit tests will be invaluable for calling that out. You will also find it encourages you to focus on the client's needs more, which tends to result in a cleaner protocol and a cleaner server codebase.

Christopher Smith
+1: Client library tested with mock server is one effort. Actual server can then be tested via the client library. This is how we're doing this kind of thing.
S.Lott