4

Possible Duplicate:
Is unit testing or test-driven development worthwhile?

I've been working with C# for the last 2 years, and I've never done any unit testing. I just need to know what the objective of unit testing is. What kind of results do we expect from unit testing? Is code quality checked by unit testing? In my view, unit testing is the job of testers; if that is true, then as a developer why would I need to write test code if the tester does the unit testing? Why should I write extra code for testing? Do I need to maintain a separate copy of a project for unit testing?

Mou
  • 209
  • 1
  • 3
  • 6
  • 9
    Did you at least try to use google and search string like "What is unit testing" ??? – Ladislav Mrnka Jun 16 '11 at 13:58
  • 3
    @Ladislav:What's the problem in the question? Maybe the OP wanted the tactile experience of hearing from real developers rather than static HTML. There would be no exchange of ideas if everyone just looked stuff up, all the time, or were shy of asking lest someone criticise the question. Where's the fun in that? No need to put someone down. –  Jun 16 '11 at 14:11
  • 4
    @Xhalent - if the question starts with "what is objective of ..." then the OP didn't make any effort to find at least basic information himself. Such question is IMHO like asking for link to wikipedia. If I have a problem with the question, I would start closing - I didn't so that was just general comment to point out that OP can get high quality information faster then he type the question. – Ladislav Mrnka Jun 16 '11 at 14:18
  • Unit testing is a systematic form of trial and error. – ThomasX Mar 21 '12 at 13:40

7 Answers7

9

Unit tests serve several related purposes:

  • Verify that requirements are being met;
  • Develop more precise specifications for the code;
  • Test functional units in isolation;
  • Make regression testing easier (i.e., make sure you don't break working code).

Verify that requirements are being met

For example, I'm working on some code to display transaction history for a bank account. I have a requirement that if I get a history record where fee, escrow, or interest amounts are greater than 0, I break those out into separate entries with their own transaction codes and descriptions. One method in one class is responsible for this, so I write code that calls that method directly (or, if that particular method isn't publicly visible, I call the method that calls the method under test) with known inputs for each case, and then check the results for each of those inputs to verify that the right sub-transactions have been created, with the right data.

Develop more precise specifications for the code

As you're developing your unit tests, you will inevitably find that the requirements do not cover all possible cases. For example, I have another requirement that says if the transaction code is X, do one thing, and if it's Y, do something else. But there's nothing telling me what to do if the transaction code isn't either X or Y. It's a hole in the specification that needs to be filled, in this case by the architect. It's a good way of checking your work.

In a way, the unit test becomes the specification for the code.

Test functional units in isolation

This is a biggie. Unit testing allows you to test your code as you're writing it; you don't have to wait until all the pieces are in place before testing can begin. If you're testing a piece of code that relies on another class or method, you can write up a dummy implementation of that class or method that returns known values or behaves in a known manner, so that you can test specific scenarios.

It also encourages you to factor your code more aggressively, reducing dependecies between components, which makes the code easier to maintain and extend.

Make regression testing easier

The nightmare scenario is releasing a patch that breaks working code. By running unit tests as part of every build, you guard against accidental breakage because the associated test will fail. You can then analyze the failure and see if the break is real (i.e., someone coded in a bug) or if the requirement/specification changed, and adjust the unit test accordingly.

John Bode
  • 10,826
  • 1
  • 31
  • 43
  • 1
    I was just thinking of writing an answer to this question, and formulating what points I was going to make. John Bode has written exactly the answer that I wanted to write; so I upvoted this answer instead of supplying my own. But I'd REALLY like to add is that it's important to keep your unit tests in the same source repository as your application code; that way, it's easy to find them and run them as you make changes in your application. The real value of having unit tests is in dealing with changes AFTER the tests are written; not in testing the code at the time that you write it. – Dawood ibn Kareem Mar 22 '12 at 07:50
7

i just need to know what is the objective of Unit Testing.

To make sure that your code works after the changes.

what kind of result we expect from unit testing.

Your mind will be changed. You will think about how to test the code before creating it - so the code becomes better-maintained.

code quality is checked by unit testing?

No. Code quality cannot be measured or checked by unit testing. Code quality can be improved by code reviews.

unit testing is the job of developer of tester.

Both. Usually tester creates integration tests (black-box tests), developer creates both (white-box and black-box tests).

do i need to maintain a separate copy of the same project for unit testing?

You should have a separate copy of the project for each developer (I hope, you have it?). Developer should run unit tests before committing to repository. And integration test system should take the changes into its own copy and run the tests - the result will show whether all the developers run the tests before committing.

Peter K.
  • 3,828
  • 1
  • 23
  • 34
Alex Netkachov
  • 214
  • 1
  • 2
  • Agree, but integration tests != unit tests. So unit testing is pure developers work. – Restuta Jun 16 '11 at 14:11
  • 2
    Yes, integration tests != unit tests. But distinguishing them requires some experience and I think that beginners may just use the "unit tests" buzzword for all kinds of automatic tests. –  Jun 16 '11 at 14:42
  • And I strongly believe that it's not hard at all and that it's important to know that unit test should test a unit, a single one. So beginners will not tend to write test that are brittle and coupled, and will think about substituting additional dependencies that are not part of the current SUT. – Restuta Mar 22 '12 at 01:46
  • And I would argue your statement about code quality. If you use unit tests then your code is by definition more extensible and less coupled and extensibility and coupling are code qualities, aren't they? – Restuta Mar 22 '12 at 01:49
4

Objective of UnitTesting is simple - reduce cost of writing and supporting of an application. It's a very high level one. For developer there are few others like: writing better code, saving time on debugging, easier maintain, professional growth after all.

UnitTesting is completely developers job, and yes you will need to maintain addional project with tests, but it worth this effort. (this will not be a copy of your project btw)

Unit Testing is fun. It just fun to write and run tests. You won't understand until you try.

Unit Testing is whole different way of writing code and working with code base. You should understand this and all your team members too. You will need to run tests often, setup CI, feel happy.

Unit Testing is have a good tooling and a big community around, so starting writing tets will not be very hard.

When you have Unit Tests you can't say that project is shining and everything is great, but when after that you get involved into project without tests you starting to understand all importance of them.

Restuta
  • 437
  • 3
  • 6
  • 14
  • I think the real cost saver is over the lifetime of the application. It may actually add to the cost of development. –  Jun 16 '11 at 14:12
  • Agree, added "and supporting" =) – Restuta Jun 16 '11 at 14:16
  • 1
    @Xhalent: unit testing doesn't add to the cost of development, it is an integral part, much like spell checking a document doesn't add to the cost of writing. Unit testing shouldn't be considered an optional extra step. It is part of what you do if you are a professional programmer. – Bryan Oakley Mar 21 '12 at 12:58
  • Kind of, it is different from spell checking, so I would prefer not to use that analogy, but it is definitely should be a part of standard development process. – Restuta Mar 22 '12 at 01:39
2

Unit testing ensures the functional contract of each "unit" is not changed. Here's an example:

For input "A", method X produces result "B"

Having unit tests ensures that, even after many code changes (bug fixes, new features), method X still produces result "B" when given input "A". If every function in your system is validated this way, the chance of creating bugs or accidentally breaking functionality is much lower.

Common practice is to create a MyProj.csproj and a MyProj.Test.csproj, where the Test project contains a set of tests for each contract in MyProj.

Typically there should be one unit test for every conditional/logic-branch inside the function being tested.

Rex M
  • 231
  • 1
  • 8
  • can u please tell me more about for unit testing like....a) unit testing will help me to capture logical flaw? b) if any function take more time and more memory then unit testing will help me to capture the flaw in code? will it also advise me to how to rectify the code. i just need to know point wise what are the benefit a developer will get doing the unit testing. i will be happy if u please discuss here when u get some time. –  Jun 16 '11 at 17:58
  • @user728750 - Unit testing will not capture (a) or (b). Unit testing will only capture errors in the code (caused by changes) where functions (you are testing) return unexpected results. – ocodo Jun 16 '11 at 22:08
2

We've been making good use of unit tests in some the projects I am working on. I'm not a TDD guy by any means, so what I tend to do is write unit tests after I write the code and verify the behaviour is as expected.

When a bug is picked up, and unit test is written to verify that it does not reappear.

Then we integrate unit tests in our continuous integration server (TFS 2010) so that on every check in of code, all the unit tests get run if something somewhere else in the code base breaks a unit test, then we all know about and we can rectify it prior to release.

Having a disciplined approach to unit tests also ends up changing the way you code. You tend to write more cohesive and loosely coupled designed code, because that is what facilitates unit testing. As a by product, the quality of code is improved. Architectural techniques such as DI/IOC gretaly faciliate unit testing.

With unit testing, you want the test to be totally predictable and have no dependencies on the environment such as databases etc. That means you utilise things such as mocks and stubbs to provide those external services.

Writing tests can be quite complex, particularly when mocking system components. IMHO it is a job for developers, because it is programming and besides they should no the code logic back to front. The runnning of the test, as I said before, is the job the test agent such as Visual Studio manually or TFS.

1

Every "unit" has an implicit contract: roughly, "if you supply these inputs, I will give you these outputs". Unit tests serve to prove that the contract has been fulfilled, and notify you when it has been broken.

They are useful if you write them first (tdd) in that you know you are done when all the tests pass (assuming all the tests are a fair representation of the contract). After the code has been written, the unit tests will tell you when a change breaks the contract.

For example, lets say you have a function that converts a string to all uppercase. You unit tests must prove that, given a string, it does exactly that. Later, somebody passes in a unicode string and your function fails. That means either that unicode inputs were not part of the contract, so you have to add a new feature, or it was part of the contract and the test is telling you that the code has a bug and isn't honoring the contract.

Not only do you get the benefits of bug detection, but the very act of writing the unit tests help you to fully understand what your code is expected to do. It makes you think about edge cases, about what inputs are required, and what outputs are expected.

Bryan Oakley
  • 25,192
  • 5
  • 64
  • 89
0

Avoiding Regressions

(had to state that out loud and clear)

Regressions are so incredibly relevant it's unbelievable most schools still don't bother even mentioning them.

Here, read the Wikipedia article on Regression Testing. It's a structured introduction to the topic and highlights both Unit and Functional tests. (a distinction many tutorials overlook, but then, functional tests, don't usually need frameworks or syntax sugar)

Regressions in code obviously don't go away magically with testing, but the combined powers of VCS and Unit Testing help catch them early on and act upon them with viking fury.

ZJR
  • 6,301
  • 28
  • 36