« Posts tagged bukkit

Programmatic Testing

So, in my Minecraft plugin, I would like to start adding JUnit tests, but I’ve come across an issue that is preventing me from actually making many test cases. There are two issues. My plugin runs as a library inside of another plugin. I could in theory make a test harness, so it can run standalone, but for the most part, it would be nearly impossible to generate test data without it running in a real case, and writing an effective test harness that generated real data to send to the plugin, and returned valid, programmatically verifiable results would be a massive undertaking in and of itself. Secondly, many functions in the program return void, but do some action. For instance, how would one test the following function using JUnit?

public void add(int i, int j){
     System.out.println(i + " plus " + j + " is " + (i + j));
}

This would be a simple function to write a test case for, if only it returned what it computed! The first though is of course to change the function to return the result, as well as printing it to the screen. However, there are two issues: what if this function implemented an abstract function, or overwrote some parent class’s function. In this case, I cannot change the signature. Secondly, what if the results are not programmatically identifiable anyways, for instance, in Minecraft, if you send a message to a player, you would write some code similar to this:

public void sendMessage(int some_input){
     //some_input determines what player we send a message to, and what message to send
     Player p = null;
     String message = "";
     switch(some_input){
          case 1:
               p = new Player("Some player");
               message = "Some message";
           //more cases...
     }
     p.sendMessage(message);
}

In this abstract example, we could change the function to return either the player we send to, or the message we sent, but not both, at least not without doing some serious work on the function. Furthermore, this breaks the paradigm of keeping your tests separate from your production code.

I am genuinely interested in getting these test cases working, because doing regression testing when I add a new feature is starting to get incredibly cumbersome, but in many many cases in my plugin, I have issues like this, where I can’t really figure out how to best test the function, without having a whole slew of tests to manually run. It’s quickly becoming apparent to me that manually testing becomes unscalable, and that a programmatic solution is the only solution.