Unit Testing Procedural Code – Is it Effective?

object-orientedproceduralunit testing

On a current project, the powers that be want to have unit testing incorporated into our development cycle to avoid the constant amount of bugs that seem to seep into our code. The problem is that the spaghetti code is 95% percent procedural, which I've never done unit testing with (all my experience with unit testing has been with OOP code)

So my question in a nutshell is would it be wise to proceed with unit testing with our current codebase, or suggest that it be postponed until the application has been migrated to a proper OOP framework?

PS: While I tried to style this question as language agnostic, I feel that stating the application in question uses PHP and javascript will help provide more specific answers that could answer this question since from experience this occurrence occurs most with such applications.

Best Answer

Unit testing works well with objects, especially since it provides lots of fancy features, like mock objects, which helps creating better tests faster.

This being said, nothing forbids doing unit testing on a procedural codebase. In OOP, most unit tests are testing methods by passing some parameters to them and expecting either a result, or an exception of a specific type. This can be done as far with procedural code too; just that instead of testing methods, you'll test functions.

Note that you'll have to:

  • Isolate the functions you have to test and the ones you don't need to. In OOP, this is easy: private methods don't have to be tested because the callers will never be able to access them directly. Chances are, in your procedural code, some functions are like this and don't need tests.

  • Think about global scope. The problem exists in OOP too, but if you say that you have to test spaghetti code, chances are that the people who wrote this code have bad habits, such as using global scope too much, and doing some crazy things like changing $_GET or $_POST arrays inside functions.

  • Deal with code outside functions. This is a more complicated case, but still possible. Either you require_once a page to see what happens and catch the output through ob_start/ob_get_clean, or you do an HTTP request from the test suite and analyze the response by parsing the HTML. This is not really an UI testing: here, you don't care if a button on a page appears at the left or at the right or if a link is in big red capital letters or in small blue ones. What you care about is to find some HTML elements through DOM and compare their content to the expected one.

  • Test the response codes. require_once with output buffering is good, but you also have to test how the web application deal with errors. For example if the expected result of a test is 404 Not Found, you must do an HTTP request in order to know what the response is.

Related Topic