Test-driven development note.

1 minute read

Suppose we want to design a process that provides multiple services. Each service is a microservice, that is it is stateless and all that RESTful thingy. How should we test/develop this?

Many times, because there are just too many ways to do the same thing, we can find starting rather confusing. What direction should I take? Why not choosing that direction?

A major benefit of Test-driven development (TDD), most suprisingly, is that it dictates a workflow, hence, reducing the cognitive uncertainty of starting. More clearly, if we think, not about how to code, rather, what we wish the piece of code that we have not written yet does, then development becomes much more straightforward.

For instance, the first thing I would want to do is to insanitate an instand of this process:

def test_init(robot_fixture):
    robot = robot_fixture
    proc = GeometricComputationServer(robot)

Now, if I run this test I will surely have a NotImplemented error. The easiest way to get over this is to define a dummy GeometricComputationServer class.

class GeometricComputationServer(object):
    def __init__(self, robot):
        pass

Alright, the test will now pass. We have obtained the very first test case. Now what?. The next thing we want to do is to define a callback to return wrench mapping given two frames: The original frame in which the wrench is measure and the target frame of interest. Alright, so the first thing is to check for problematic edge cases:

  • one or both of the frames doesn’t exist
  • more than two frames
  • return result for target stuuffs.

For the first case, we can write a test script:

def test_init(robot_fixture):
    robot = robot_fixture
    proc = GeometricComputationServer(robot)

    request = ComputeRequest(arg_text=["ftsensor", "manip_not_exist"])
    response = prob._cb_compute_wrench_mapping_(request)

    # assertion
    assert not response.success
    assert "not exist" in response.message

This test should fail because we have not defined _cb_compute_wrench_mapping yet. A dummy implementation such as the one below can help us pass this test:

 def _cb_compute_wrench_mapping(self, request):
     return ComputeResponse(success=False, message="Input frame does not exist.")

We can let this bad implementation here for now, and continue with the next test.