I have read about unit testing and how it is used to test specific pieces of your code.

A very quick example has to do with processing JSON data onto a database.

The unit test reads a file from the project bundle and executes the method that is in charge of processing JSON data.

But I dont get how this is different from actually running the app and testing with the server.

So my question might be a bit general, but I honestly dont understand the proper use of unit testing, or even how it is useful; I hope the experienced programmers that surf around StackOverflow can help me.

3 Answers
3

The idea of unit testing is to enable completely modular code development. You probably already know that modular code is the way to go, as it encourages reusable and clearly focused designs.

If you attempt to test an entire system as a whole, then many different parts have a possibility of failing. In any reasonably sized system, it would be nearly impossible to account for every possible problem. Also, when problems are found, it may be difficult (or nearly impossible) to locate the responsible code.

However, if different portions of your code are completely separated from other portions (i.e. they don't rely on each other), then you can use unit testing to test a subset of your larger system. It is much easier to detect bugs in a small amount of code, as opposed to a large amount.

In the example you presented, there are two super-portions of your code: the part that retrieves data from a database; and the part that processes that data. If you attempted to test the two together, your test could become riddled with failures because of the attempted database access. There are numerous networking and other I/O issues that could come up when reading the database. Especially in extreme cases, this can make it very difficult to test the processing portion of your code. Similarly, there could be bugs in the processing code which, for some reason, are not clearly located within that part of the code.

The solution is to use unit testing. Rather than test the retrieval and processing together, you separate them. You can feed any data you want to the processing portion to see if it functions correctly. If something does go wrong, you know that the problem is a processing issue, and not related to reading the database. Similarly, you can make simple tests to ensure that you are attempting to access that database in a correct manner. Any problems that arise this time are sure to be related to the database reading.

So unit testing is really invaluable in testing code for robustness. Also, it encourages a design pattern which is greatly encourage. Specifically, developers wising to use unit tests must design in such a way that their code can be separated into modular units. For example, a function that relies heavily on global mutable state is inherently less unit-testable than a function which only relies on it arguments to produce a result.

Edit

One thing I forgot to mention is that unit tests are not an afterthought. They are intended to be an integral part of the development process, so that small pieces of code are guaranteed to be robust. This increases the robustness of the code throughout development. As each new portion is written, it can be immediately unit tested to discover potential flaws. Thus, robust foundation is laid upon which layers of robust code may be written. The end result is a final product is more likely to have a much higher level of correctedness than an equivalent product which is tested after the development process. Also, the time spent testing is generally reduced.

Unit testing allows you to test modules of code without the application. You can test the code well before the application exists. In object oriented development, unit tests should test only one class. Integration tests are used to verify multiple classes working in concert. Fortunately, many integration tests can be run using unit testing frameworks. Unit testing single classes can be difficult as you may need to provide mock objects to meet their dependencies. This is especially the case when testing database related code. In many cases, your example could be an integration test.

Assuming you have unit and/or integration tested the code that takes the bundle and processes it into the database, you make testing the application simpler. Now if the application fails to process data into the database, you know the problem is likely to occur before the code that actually loads the data into the database. Perhaps the bundle is not being prepared correctly, or dispatched to the correct handler.

The more code you have that is unit and/or integration tested, the simpler it is to test the whole application as you should have many parts which are already tested and can be trusted to work correctly.

Unit and integration tests simplify testing in that developers or build systems can test the code before the application is complete. Similar testing is done when building things like aircraft and cars. Everything from screws on up are tested to ensure they are up to the job; then assemblies are tested; and finally the completed product is tested. This makes it easier to substitute parts when required, as the tests can be applied to the substitute part. When we apply these techniques, unit, integration, and application testing, we generally get more reliable and maintainable software.

When a problem is found with code that is unit or integration tested, it is common to add a new test case to verify the problem is solved. This increases the robustness of the test suite over time.

Automated build systems will often run the unit and integration tests as part of the build process. This allows the build system to flag or reject code which no longer passes the test suites. The application tests can then concentrate on verifying business functionality and usability without worrying too much about the functionality of the code.

EDIT: I realized I hadn't answered the title of this question.

When to use use UNIT testing: Use unit testing to test the public interface to your classes or modules. You may choose not to test trivial code. Generally, private methods are not tested. The more complex the code the more important it is to develop unit tests.

How to unit test: Use a testing framework, such as jUnit (the framework has been developed for many languages and as a group are referred to as xUnit). Develop a set of inputs an expected outputs. Concentrate on testing edge cases and boundary cases. Add tests which will handle common cases not already covered. Use these expectations to write test cases that verify the given inputs give the expected results. Don't forget to test failure conditions.