What is unit testing, and does it require code being written? - unit-testing

I've joined a new team, and I've had a problem understanding how they are doing unit tests. When I asked where the unit tests are written, they explained they don't do their unit tests that way.
They explained that what they're calling unit tests is when they actually check the code they wrote locally, and that all of the points are being connected. To me, this is integration testing and just testing your code locally.
I was under the impression that unit tests are code written to verify behavior in a small section of a code. For example, you may write a unit test to make sure it returns the right value, and make the appropriate calls to the database. use a framework like NUnit or MbUnit to help you out in your assertions.
Unit testing to me is supposed to be fast and quick. To me, you want these so you can automate it, and have a huge suite of tests for your application to make sure that it behaves AS YOU EXPECT.
Can someone provide clarification in my or their misunderstandings?

I have worked places that did testing that way and called it unit testing. It reminded me of a quote attributed to Abe Lincoln:
Lincoln: How many legs does a dog have?
Other Guy: 4.
Lincoln: What if we called the tail a leg?
Other Guy: Well, then it would have 5.
Lincoln: No, the answer is still 4. Calling a tail a leg doesn't make it so.

They explained that what they're calling unit tests is when they
actually check the code they wrote locally, and that all of the points
are being connected.
That is not a unit test. That is a code review. Code reviews are good, but without actual unit tests things will break.
Unit tests involve writing code. Specifically, a unit test operate on one unit, which is just a class or component of your software.
If a class under test depends on another class, and you test both classes together, you have an integration test. Integration tests are good. Depending on the language/framework you might use the same testing framework (e.g. junit for java) for both unit and integration tests. If you have a dependency but mock or stub that dependency, then you have a pure unit test.
Unit testing to me is supposed to be fast and quick. To me, you want
these so you can automate it, and have a huge suite of tests for your
application to make sure that it behaves AS YOU EXPECT.
That is essentially correct. How 'fast and quick' developing unit tests is depends on the complexity of what is being tested and the skill of the developer writing the test. You definitely want to build up a suite of tests over time, so you know when something breaks as a codebase becomes more complex. That is how testing makes your codebase more maintainable, by telling you what ceases to function as you make changes.

Your team-mates are not doing unit testing. They are doing "fly by the seat of your pants" development.

Your assumptions are correct.
Doing a project without unit-tests (as they do, don't be fooled) might seem nice for the first few weeks: less code to write, less architecture to think about, less problems to worry about. And you can see the code is working correctly, right?
But as soon as someone (someone else, or even the original coder) comes back to an existing piece of code to modify it, add feature, or simply understand how it worked and what it exactly did, things will become a lot more problematic. And before you realize it, you'll spend your nights browsing through log files and debugging what seemed like a small feature just because it needs to integrate with other code that nobody knows exactly how it works. ANd you'll hate your job.
If it's not worth testing it (with actual unit-tests), then it's not worth writing the code in the first place. Everyone who tried coding without and with unit tests know that. Please, please, make them change their mind. Every time a piece of untested code is checked in somewhere, a puppy dies horribly.
Also, I should say, it's a lot (A LOT) harder to add tests later to a project that was done without testing in mind, than to build the test and production code side-to-side from the very start. Testing not only help you make sure your code works fine, it improves your code quality by forcing you to make good decisions (i.e. coding on interfaces, loose coupling, inversion of control, etc.)

"Unit testing" != "unit tests".
Writing unit tests is one specific method of performing unit testing. It is a very good one, and if your unit tests are written well, it can give you good value over a long time. But what they're doing is indeed unit testing. It's just the kind of unit testing that doesn't help you at all the next time you need to carve on the same code. And that's wasteful.

To add my two cents, yes, that is indeed not Unit testing. IMHO, the main features of unit tests are that it should be fast, automated and isolated. You can using a mocking framework such as RhinoMocks to isolate external dependencies.
Unit tests also have to be very simple and short. Ideally no more than a screen length. It is also one of the few places in software engineering where copy and pasting code might be a better solution than creating highly reusable and highly abstract functions. The reason simplicity is given such a high priority is to avoid the "Who watches the Watchers" problem. You really don't want to be in a situation where you have complex bugs in your unit tests, because they themselves aren't being tested. Here you are relying on the extreme simplicity and tiny size of the tests to avoid bugs.
The names of the unit tests also should be very descriptive, again following the simplicity and self documenting paradigm. I should be able to read the name of the test method and know exactly what it is doing. A quick glance at the code should show me exactly what functionality is being tested and if any external dependencies are being mocked.
The descriptive test names also make you think about the application as a whole. If I look at the entire test run, ideally just by looking at the names of all the tests that were run, I should have a fairly good idea of what the application does.

Related

Is there such a thing as a bad unit test?

Given you can't write tests for dynamic content, outside of this, is there ever a reason you should not add a unit test? Maybe a test project integrity might be considered not necessary, but I could argue this both ways.
Example:
Objective-C/xCode = Write a test to make sure fonts are listed in your constants are also listed in your projects info.plist UIAppFonts array.
Technically, tests are supposed to adhere to a few key metrics: they should be fast, easy to read and interpret, consistent results, etc.
If any of these (and more) qualities of a good unit test are not met, you will end up with a cost. If the unit tests are slow then you spend time twindling your thumbs or if they are too hard you're spending time interpreting tests instead of writing new ones/code, same goes for tests that have inconsistent results.
Therefore we can say that bad unit tests exist.
However if we look into your concrete example of "should we test X" then that is a lot more subjective.
If something is easy to test like a getter/setter (aka: trivial code) then some might not find it worth their time while others consider it no problem: by adding these quick, small tests you will never encounter an unexpected problem just because someone added logic to their getter/setter and there are no tests to catch any mistakes.
I have no knowledge about Objective-C but at first glance that seems like a reasonable concept to test.
General rule: unless you have an explicit reason not to test something, test it.
Unit tests are really just a tool to create a lower watermark for quality of your code.
If you're 100% confident that your code works as intended, then you have enough unit tests. Adding more tests in this case is just a waste of time.
Think "hello world". How many unit tests would you write for that? 1 or 0?
If you're unsure about something, then you need more unit tests. Reasons for this feeling can be:
You or someone else just found a bug. Always write unit tests for bugs.
Someone asked for a new feature and you're not confident how to implement -> write tests to design the API and to be sure the final result will meet the expectation (and to make sure that everyone knows and agrees on expectations).
You are using a new technology and want to document a) how it works and b) how you use it. These tests work as a kind of template when you wonder later "how did I do this?"
You just found a bug in a library that you use. When you fix the bug, you should also add a test case that tells you "this bug has now been fixed!" so you don't hunt in the wrong place later.
Examples for bad unit tests:
Integration test hiding inside of a unit test
Testing setters and getters
Disabled unit tests
Commented out unit tests
Unit tests that break one per day or week (they erode your confidence and your willingness to write unit tests)
Any test that takes more than 10s to execute
Unit tests that are longer than 50 lines (incl. all the setup code)
My answer would be yes, writing tests is still writing code and the best way to avoid bugs is to not write the code in the first place.
IMHO, writing good tests is generally harder than writing good code. You can't write a useable test until you understand the problem, both in how it should work and how it can fail. The former is generally much easier to understand than the latter.
Having said all that, you have to start somewhere and sometimes it's easiest to write the simplest tests first, even if then don't really test anything useful.
However, you should winnow those tests out as you work through the TDD process. Work towards having a test set that documents just the external interfaces of an object. This is important, as when you come back to the object for later refactoring, you want a set of tests that defines the responsibilities of the object to the rest of the program, not the responsibilities of the object to itself.
(i.e. you want to test the inputs and outputs of the object as a "black box", not the internal wiring of the object. This allows you as much freedom to change w/o causing damage outside of the object. )

Are unit tests useful for real? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is Unit Testing worth the effort?
I know what is the purpose of unit tests generally speaking, but I found some things that bother me.
1)
Purpose of tests early bug discovery. So, in some of later iterations, if I make some changes in code, automated test have to alarm me and tell me that I've screwed up some long ago forgotten piece of my software.
But, say that I have class A and say that is interact with some others class' instance, call it class B.
When one writes unit test for class A, he has to mock class B.
So, in some future, if one makes some changes in class B, and that causes some bugs, they will reflect only in class B's unit test, not in A's ('cause A's test doesn't use real class B, but it's mock with fixed inputs and outputs).
So, I can't see how could unit test do early notifying of made bugs that one isn't aware of? I'm aware of possible bugs in class that I'm changing, I do not need unit test for it, I need test to alarm me of consequences of my changes that makes bug in some "forgotten" class, and that isn't possible with unit tests. Or am I wrong?
2)
When writing mocks and right expectations of calling methods, their inputs and returning values, one has to know how class-under-test is going to be implemented.
And I think that that contradicts with test driven development. In TDD one writes tests first, and, driven by them, one writes a code.
But I can't write right expectations (and tests in general) unless I write code that has to be tested. That contradicts with TDD, right?
Both of those problems could be solved if I used real objects instead of mocks. But that isn't unit testing then, right? In unit test class-under-test has to be isolated form the rest of the system, not using real classes but mocks.
I'm sure that I'm wrong somewhere, but I cannot find where. I've been reading and reading and I can't find what have I understood wrong.
I have just implemented TDD and unit testing for the first time. I think its great, and I have never used it in a contiguous integration environment, where I imagine its even more valuable.
My process:
Create the skeleton of class where business logic will go (be it a
serivce layer, or domain object, etc).
Write the test, and define the
method names and required functionaility in the test - which then prompts my
ide to write the skelton method (a small but nice plus)
Then write the actual class methods being tested.
Run tests, debug.
I can now no longer write code without first writing its test, it really does aid develop. You catch bugs straight away, and it really helps you mentally order your code and development in a structured simple manner. And of course, any code that breaks existing functionality is caught straightaway.
I have not needed to use mock objects yet (using spring I can get away with calling service layer, and controller methods directly).
Strictly speaking, you spend more time in writing unit test rather than concentrating on the actual code.
there is no way you can achieve 100% code coverage. I do unit test my application, but I feel its not worth it. But not every one agrees with it.
If you change a piece of code, your unit test fail and figure out why its failing but for me its not worth it.
I am not big fan of Unit testing... You mock everything but mocking is big task..........
But now a days companies are trying for TDD approach.
Simple answer: Yes, they are useful for real.
TDD is nice and all in theory but I've hardly ever seen seen it done in practice. Unittests are not bound to tdd, however. You can always write unittests for code that works to make sure it still works after changes. This usage of unittests have saved me countless hours of bugfixing because the tests immediately pointed out what went wrong.
I tend to avoid mocks. In most cases, they're not worth it in my opinion. Not using mocks might make my unittest a little more of an integrationtest but it gets the job done. To make sure, your classes work as designed.
Unit Tests itself aren't stupid, it depends of your project.
I think Unit Tests are good, not just in TDD development but in any kind of project. The real pro for me is that if you wrap crucial code in your project with Unit Tests, there's a way to know if what you meant with it is still working or not.
For me, the real problem is that if someone is messing your code, there should be a way for him/her to know if the tests are still succedding, but not by making them run manually. For instance, lets take Eclipse + Java + Maven example. If you use Unit tests on your Maven Java Project, each time anyone build it, the tests run automatically. So, if someone messed your code, the next time he build it, he'll get a "BUILD FAILED" Console error, pointing that some Unit Tests failed.
So my point is: Unit Tests are good, but people should know that they're screwing things up without running tests each time they change code.
0) No, it doesn't. Sound stupid, I mean. It is a perfectly valid question.
The sad fact is that ours is an industry riddled with silver bullets and slick with snake oil, and if something doesn't make sense then you are right to question it. Any technique, any approach to any part of engineering is only ever applicable in certain circumstances. These are typically poorly documented at best, and so it all tends to deteriorate into utterly pointless my-method-is-better-than-yours arguments.
I have had successes and failures with unit testing, and in my experience it can be very useful indeed, when correctly applied.
It is not a good technique when you're doing a massive from-scratch development effort, because everything is changing too rapidly for the unit tests to keep up. It is an excellent technique when in a maintenance phase, because you're changing a small part of a larger whole which still needs to work the way it's supposed to.
To me, unit testing is not about test-driven development but design-by-contract: the unit test checks that the interface has not been violated. From this, it's pretty easy to see that the same person should not be writing a unit and its corresponding unit test, so for very small-scale stuff, like my own pet projects, I never use it. In larger projects, I advocate it - but only if design-by-contract is employed and the project recognizes interface specifications as important artefacts.
Unit testing as a technique is also sensitive to the unit size. It is not necessarily the case that a class is testable on its own, and in my experience the class is generally too small for unit testing. You don't want to test a class per se, you want to test a unit of functionality. Individually deployable (installable) binaries, eg jars or DLLs, make better candidates in my book, or packages if you're in a Java-style language.

Unit-Testing Acceptance-Tests?

I am currently making some Acceptance-Tests that will help drive the design of a program I am about to do. Everything seems fine except I've realized that the Acceptance-Tests are kinda complex, that is, although they are conceptually simple, they require quite a bit of tricky code to run. I'll need to make a couple of "helper" classes for my Acceptance-Tests.
My question is in how to develop them:
Make Unit-Tests of my Acceptance-Tests(this seems odd -- has anyone done anything like it?)
Make Unit-Tests for those help classes. After I have done all the code of those help classes, I can pass and start working on the real Unit-Tests of my System. When using this approach, where would you put the helper classes? In the tests' project or in the real project? They don't necessarily have dependencies on testing/mocking frameworks.
Any other idea?
A friend is very keen on the notion that acceptance tests tell you whether your code is broken, while unit tests tell you where it's broken; these are complementary and valuable bits of information. Acceptance tests are better at letting you know when you're done.
But to get done, you need all the pieces along the way; you need them to be working, and that's what unit tests are great at. Done test-first, they'll also lead you to better design (not just code that works). A good approach is to write a big-picture acceptance test, and say to yourself: "when this is passing, I'm done." Then work to make it pass, working TDD: write a small unit test for the next little bit of functionality you need to make the AT pass; write the code to make it pass; refactor; repeat. As you progress, run the AT from time to time; you will probably find it failing later and later in the test. And, as mentioned above, when it's passing, you're done.
I don't think unit testing the acceptance test itself makes much sense. But unit testing its helper classes - indeed, writing them test-first - is a very good way to go. You're likely to find some methods that you write "just for the test" working their way into the production code - and even if you don't, you still want to know that the code your ATs use is working right.
If your AT is simple enough, the old adage of "the test tests the code, and the code tests the test" is probably sufficient - when you have a failing test, it's either because the code is wrong or because the test is wrong, and it should be easy enough to figure out which. But when the test is complicated, it's good to have its underpinnings well tested, too.
If you think of software development like a car production plant, then the act of writing software is like developing a new car. Each component is tested separately because it's new. It's never been done before. (If it has, you can either get people who've done it before or buy it off the shelf.)
Your build system, which builds your software and also which tests it, is like the conveyor belt - the process which churns out car after car after car. Car manufacturers usually consider how they're going to automate production of new components and test their cars as part of creating new ones, and you can bet that they also test the machines which produce those cars.
So, yes, unit-testing your acceptance tests seems perfectly fine to me, especially if it helps you go faster and keep things easier to change.
There is nothing wrong with using unit test framework (like JUnit) to write acceptance tests (or integration tests). People don't like calling them 'unit tests' for many reasons. To me the main reason is that integration/acceptance tests won't run every time one checks in the changes (too long or/and no proper environment).
Your helper classes are rather standard thing that comprise "test infrastructure code". They don't belong anywhere else but test code. It's your choice to test them or not. But without them your tests won't be feasible in big systems.
So, your choice is #2 or no tests of tests at all. There is nothing wrong with refactoring infrastructure code to make it more transparent and simple.
Your option 2 is the way I'd do it: Write helper classes test-first - it sounds like you know what they should do.
The tests are tests, and although the helper classes are not strictly tests, they won't be referenced by your main code, just the tests, so they belong with the tests. Perhaps they could be in a separate package/namespace from regular tests.

Does it make sense to unit test throwaway code that runs in production?

One of the primary benefits of unit testing is to provide confidence that when one needs to later alter the code one is not breaking it. However, what benefits does unit testing provide for code that is literally used as one-off throwaway code? This throwaway code is most certainly used in production, but is never actually altered once it's deployed. Does unit testing still make sense in this situation and if so how specifically?
UPDATE: The throwaway code actually is functional-tested before hitting production. Normally, for non-throwaway code it still makes sense to have unit tests despite functional testing occurring. The question here is whether or not it makes sense to also have the unit tests also in the case of throwaway code.
UPDATE 2: The reason why throwaway code is in production in the first place is that this code is literally used for one client, one time only. It's never subject to revision. It is used by a used a single time for a few days. It's very specific to a single client. It's not ever used after that for any other purpose, including the same client. Is there still value in writing unit tests in this case, despite functional tests occurring?
I'm not sure how code can be both production code and throwaway code. The fact that it is being used in production means that it is not throwaway. What makes you so sure that just because you don't plan on changing it now, someone else might not come around and reuse it or alter it at a later date?
Regardless, there are many benefits to unit testing beyond protection when refactoring. Unit tests (like all tests) help prove that the code is doing what is supposed to do. You will need to test at some level before you go into production to prove that, and unit tests are an easy way to automate some of that.
The process of writing unit tests often exposes bugs. It forces you to think about cases that you may not have thought of when you wrote the happy day case.
I'd be willing to bet the time you spent asking the question and coming back to read the answers would have been more than enough time to write a few unit tests. Which was the better use of your time?
It's simple: if you care whether the code is correct or not, you need to test it. Unit test, acceptance test, service test, whatever you call it, it needs to be tested one way or another.
Tests provide benefits in three ways:
When code is written test-first, tests help drive design and ensure you write testable code. If this is truly throwaway code, then this doesn't matter to you.
Tests provide a safety net for refactoring. Again, in your situation you may not care.
Tests prove the code does what it is supposed to do. This DOES apply to throwaway code, especially if the code is written in a test-first manner. I'd much rather write tests as I go, and be confident that I'm shipping something solid to QA, than skip the tests and wait for a QA person to tell me about defects. What if a defect is reported and you have to make a significant change to the code? With automated tests, it's easy to tell if your "fix" broke anything else. Without automated tests you have to repeat the full suite of manual tests, which might be expensive.
To summarize, if the code is truly "throwaway" AND is small or very simple, then you may not get a lot of benefit. If the code is complex, or is relatively large, then tests may be worth something. (Although, I'd focus on writing high value tests only, targeting features that are hard or costly to test by hand)
You should be testing this code somehow before putting it into production. Unit testing can be a valuable part here, regardless of the need to do automated regression tests later.
Unit testing can also be used in test-driven development, where you sketch out what the code is supposed to do before actually writing the code. In this scenario, the unit tests help speed up the development process (precisely because you have automated tests at a time when the code still does change).
If I only had a dollar for every piece of "thorwaway" code I ever needed to maintain...

What is unit testing? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I saw many questions asking 'how' to unit test in a specific language, but no question asking 'what', 'why', and 'when'.
What is it?
What does it do for me?
Why should I use it?
When should I use it (also when not)?
What are some common pitfalls and misconceptions
Unit testing is, roughly speaking, testing bits of your code in isolation with test code. The immediate advantages that come to mind are:
Running the tests becomes automate-able and repeatable
You can test at a much more granular level than point-and-click testing via a GUI
Note that if your test code writes to a file, opens a database connection or does something over the network, it's more appropriately categorized as an integration test. Integration tests are a good thing, but should not be confused with unit tests. Unit test code should be short, sweet and quick to execute.
Another way to look at unit testing is that you write the tests first. This is known as Test-Driven Development (TDD for short). TDD brings additional advantages:
You don't write speculative "I might need this in the future" code -- just enough to make the tests pass
The code you've written is always covered by tests
By writing the test first, you're forced into thinking about how you want to call the code, which usually improves the design of the code in the long run.
If you're not doing unit testing now, I recommend you get started on it. Get a good book, practically any xUnit-book will do because the concepts are very much transferable between them.
Sometimes writing unit tests can be painful. When it gets that way, try to find someone to help you, and resist the temptation to "just write the damn code". Unit testing is a lot like washing the dishes. It's not always pleasant, but it keeps your metaphorical kitchen clean, and you really want it to be clean. :)
Edit: One misconception comes to mind, although I'm not sure if it's so common. I've heard a project manager say that unit tests made the team write all the code twice. If it looks and feels that way, well, you're doing it wrong. Not only does writing the tests usually speed up development, but it also gives you a convenient "now I'm done" indicator that you wouldn't have otherwise.
I don't disagree with Dan (although a better choice may just be not to answer)...but...
Unit testing is the process of writing code to test the behavior and functionality of your system.
Obviously tests improve the quality of your code, but that's just a superficial benefit of unit testing. The real benefits are to:
Make it easier to change the technical implementation while making sure you don't change the behavior (refactoring). Properly unit tested code can be aggressively refactored/cleaned up with little chance of breaking anything without noticing it.
Give developers confidence when adding behavior or making fixes.
Document your code
Indicate areas of your code that are tightly coupled. It's hard to unit test code that's tightly coupled
Provide a means to use your API and look for difficulties early on
Indicates methods and classes that aren't very cohesive
You should unit test because its in your interest to deliver a maintainable and quality product to your client.
I'd suggest you use it for any system, or part of a system, which models real-world behavior. In other words, it's particularly well suited for enterprise development. I would not use it for throw-away/utility programs. I would not use it for parts of a system that are problematic to test (UI is a common example, but that isn't always the case)
The greatest pitfall is that developers test too large a unit, or they consider a method a unit. This is particularly true if you don't understand Inversion of Control - in which case your unit tests will always turn into end-to-end integration testing. Unit test should test individual behaviors - and most methods have many behaviors.
The greatest misconception is that programmers shouldn't test. Only bad or lazy programmers believe that. Should the guy building your roof not test it? Should the doctor replacing a heart valve not test the new valve? Only a programmer can test that his code does what he intended it to do (QA can test edge cases - how code behaves when it's told to do things the programmer didn't intend, and the client can do acceptance test - does the code do what what the client paid for it to do)
The main difference of unit testing, as opposed to "just opening a new project and test this specific code" is that it's automated, thus repeatable.
If you test your code manually, it may convince you that the code is working perfectly - in its current state. But what about a week later, when you made a slight modification in it? Are you willing to retest it again by hand whenever anything changes in your code? Most probably not :-(
But if you can run your tests anytime, with a single click, exactly the same way, within a few seconds, then they will show you immediately whenever something is broken. And if you also integrate the unit tests into your automated build process, they will alert you to bugs even in cases where a seemingly completely unrelated change broke something in a distant part of the codebase - when it would not even occur to you that there is a need to retest that particular functionality.
This is the main advantage of unit tests over hand testing. But wait, there is more:
unit tests shorten the development feedback loop dramatically: with a separate testing department it may take weeks for you to know that there is a bug in your code, by which time you have already forgotten much of the context, thus it may take you hours to find and fix the bug; OTOH with unit tests, the feedback cycle is measured in seconds, and the bug fix process is typically along the lines of an "oh sh*t, I forgot to check for that condition here" :-)
unit tests effectively document (your understanding of) the behaviour of your code
unit testing forces you to reevaluate your design choices, which results in simpler, cleaner design
Unit testing frameworks, in turn, make it easy for you to write and run your tests.
I was never taught unit testing at university, and it took me a while to "get" it. I read about it, went "ah, right, automated testing, that could be cool I guess", and then I forgot about it.
It took quite a bit longer before I really figured out the point: Let's say you're working on a large system and you write a small module. It compiles, you put it through its paces, it works great, you move on to the next task. Nine months down the line and two versions later someone else makes a change to some seemingly unrelated part of the program, and it breaks the module. Worse, they test their changes, and their code works, but they don't test your module; hell, they may not even know your module exists.
And now you've got a problem: broken code is in the trunk and nobody even knows. The best case is an internal tester finds it before you ship, but fixing code that late in the game is expensive. And if no internal tester finds it...well, that can get very expensive indeed.
The solution is unit tests. They'll catch problems when you write code - which is fine - but you could have done that by hand. The real payoff is that they'll catch problems nine months down the line when you're now working on a completely different project, but a summer intern thinks it'll look tidier if those parameters were in alphabetical order - and then the unit test you wrote way back fails, and someone throws things at the intern until he changes the parameter order back. That's the "why" of unit tests. :-)
Chipping in on the philosophical pros of unit testing and TDD here are a few of they key "lightbulb" observations which struck me on my tentative first steps on the road to TDD enlightenment (none original or necessarily news)...
TDD does NOT mean writing twice the amount of code. Test code is typically fairly quick and painless to write and is a key part of your design process and critically.
TDD helps you to realize when to stop coding! Your tests give you confidence that you've done enough for now and can stop tweaking and move on to the next thing.
The tests and the code work together to achieve better code. Your code could be bad / buggy. Your TEST could be bad / buggy. In TDD you are banking on the chances of BOTH being bad / buggy being fairly low. Often its the test that needs fixing but that's still a good outcome.
TDD helps with coding constipation. You know that feeling that you have so much to do you barely know where to start? It's Friday afternoon, if you just procrastinate for a couple more hours... TDD allows you to flesh out very quickly what you think you need to do, and gets your coding moving quickly. Also, like lab rats, I think we all respond to that big green light and work harder to see it again!
In a similar vein, these designer types can SEE what they're working on. They can wander off for a juice / cigarette / iphone break and return to a monitor that immediately gives them a visual cue as to where they got to. TDD gives us something similar. It's easier to see where we got to when life intervenes...
I think it was Fowler who said: "Imperfect tests, run frequently, are much better than perfect tests that are never written at all". I interprete this as giving me permission to write tests where I think they'll be most useful even if the rest of my code coverage is woefully incomplete.
TDD helps in all kinds of surprising ways down the line. Good unit tests can help document what something is supposed to do, they can help you migrate code from one project to another and give you an unwarranted feeling of superiority over your non-testing colleagues :)
This presentation is an excellent introduction to all the yummy goodness testing entails.
I would like to recommend the xUnit Testing Patterns book by Gerard Meszaros. It's large but is a great resource on unit testing. Here is a link to his web site where he discusses the basics of unit testing. http://xunitpatterns.com/XUnitBasics.html
I use unit tests to save time.
When building business logic (or data access) testing functionality can often involve typing stuff into a lot of screens that may or may not be finished yet. Automating these tests saves time.
For me unit tests are a kind of modularised test harness. There is usually at least one test per public function. I write additional tests to cover various behaviours.
All the special cases that you thought of when developing the code can be recorded in the code in the unit tests. The unit tests also become a source of examples on how to use the code.
It is a lot faster for me to discover that my new code breaks something in my unit tests then to check in the code and have some front-end developer find a problem.
For data access testing I try to write tests that either have no change or clean up after themselves.
Unit tests aren’t going to be able to solve all the testing requirements. They will be able to save development time and test core parts of the application.
This is my take on it. I would say unit testing is the practice of writing software tests to verify that your real software does what it is meant to. This started with jUnit in the Java world and has become a best practice in PHP as well with SimpleTest and phpUnit. It's a core practice of Extreme Programming and helps you to be sure that your software still works as intended after editing. If you have sufficient test coverage, you can do major refactoring, bug fixing or add features rapidly with much less fear of introducing other problems.
It's most effective when all unit tests can be run automatically.
Unit testing is generally associated with OO development. The basic idea is to create a script which sets up the environment for your code and then exercises it; you write assertions, specify the intended output that you should receive and then execute your test script using a framework such as those mentioned above.
The framework will run all the tests against your code and then report back success or failure of each test. phpUnit is run from the Linux command line by default, though there are HTTP interfaces available for it. SimpleTest is web-based by nature and is much easier to get up and running, IMO. In combination with xDebug, phpUnit can give you automated statistics for code coverage which some people find very useful.
Some teams write hooks from their subversion repository so that unit tests are run automatically whenever you commit changes.
It's good practice to keep your unit tests in the same repository as your application.
LibrarIES like NUnit, xUnit or JUnit are just mandatory if you want to develop your projects using the TDD approach popularized by Kent Beck:
You can read Introduction to Test Driven Development (TDD) or Kent Beck's book Test Driven Development: By Example.
Then, if you want to be sure your tests cover a "good" part of your code, you can use software like NCover, JCover, PartCover or whatever. They'll tell you the coverage percentage of your code. Depending on how much you're adept at TDD, you'll know if you've practiced it well enough :)
Unit-testing is the testing of a unit of code (e.g. a single function) without the need for the infrastructure that that unit of code relies on. i.e. test it in isolation.
If, for example, the function that you're testing connects to a database and does an update, in a unit test you might not want to do that update. You would if it were an integration test but in this case it's not.
So a unit test would exercise the functionality enclosed in the "function" you're testing without side effects of the database update.
Say your function retrieved some numbers from a database and then performed a standard deviation calculation. What are you trying to test here? That the standard deviation is calculated correctly or that the data is returned from the database?
In a unit test you just want to test that the standard deviation is calculated correctly. In an integration test you want to test the standard deviation calculation and the database retrieval.
Unit testing is about writing code that tests your application code.
The Unit part of the name is about the intention to test small units of code (one method for example) at a time.
xUnit is there to help with this testing - they are frameworks that assist with this. Part of that is automated test runners that tell you what test fail and which ones pass.
They also have facilities to setup common code that you need in each test before hand and tear it down when all tests have finished.
You can have a test to check that an expected exception has been thrown, without having to write the whole try catch block yourself.
I think the point that you don't understand is that unit testing frameworks like NUnit (and the like) will help you in automating small to medium-sized tests. Usually you can run the tests in a GUI (that's the case with NUnit, for instance) by simply clicking a button and then - hopefully - see the progress bar stay green. If it turns red, the framework shows you which test failed and what exactly went wrong. In a normal unit test, you often use assertions, e.g. Assert.AreEqual(expectedValue, actualValue, "some description") - so if the two values are unequal you will see an error saying "some description: expected <expectedValue> but was <actualValue>".
So as a conclusion unit testing will make testing faster and a lot more comfortable for developers. You can run all the unit tests before committing new code so that you don't break the build process of other developers on the same project.
Use Testivus. All you need to know is right there :)
Unit testing is a practice to make sure that the function or module which you are going to implement is going to behave as expected (requirements) and also to make sure how it behaves in scenarios like boundary conditions, and invalid input.
xUnit, NUnit, mbUnit, etc. are tools which help you in writing the tests.
Test Driven Development has sort of taken over the term Unit Test. As an old timer I will mention the more generic definition of it.
Unit Test also means testing a single component in a larger system. This single component could be a dll, exe, class library, etc. It could even be a single system in a multi-system application. So ultimately Unit Test ends up being the testing of whatever you want to call a single piece of a larger system.
You would then move up to integrated or system testing by testing how all the components work together.
First of all, whether speaking about Unit testing or any other kinds of automated testing (Integration, Load, UI testing etc.), the key difference from what you suggest is that it is automated, repeatable and it doesn't require any human resources to be consumed (= nobody has to perform the tests, they usually run at a press of a button).
I went to a presentation on unit testing at FoxForward 2007 and was told never to unit test anything that works with data. After all, if you test on live data, the results are unpredictable, and if you don't test on live data, you're not actually testing the code you wrote. Unfortunately, that's most of the coding I do these days. :-)
I did take a shot at TDD recently when I was writing a routine to save and restore settings. First, I verified that I could create the storage object. Then, that it had the method I needed to call. Then, that I could call it. Then, that I could pass it parameters. Then, that I could pass it specific parameters. And so on, until I was finally verifying that it would save the specified setting, allow me to change it, and then restore it, for several different syntaxes.
I didn't get to the end, because I needed-the-routine-now-dammit, but it was a good exercise.
What do you do if you are given a pile of crap and seem like you are stuck in a perpetual state of cleanup that you know with the addition of any new feature or code can break the current set because the current software is like a house of cards?
How can we do unit testing then?
You start small. The project I just got into had no unit testing until a few months ago. When coverage was that low, we would simply pick a file that had no coverage and click "add tests".
Right now we're up to over 40%, and we've managed to pick off most of the low-hanging fruit.
(The best part is that even at this low level of coverage, we've already run into many instances of the code doing the wrong thing, and the testing caught it. That's a huge motivator to push people to add more testing.)
This answers why you should be doing unit testing.
The 3 videos below cover unit testing in javascript but the general principles apply across most languages.
Unit Testing: Minutes Now Will Save Hours Later - Eric Mann - https://www.youtube.com/watch?v=_UmmaPe8Bzc
JS Unit Testing (very good) - https://www.youtube.com/watch?v=-IYqgx8JxlU
Writing Testable JavaScript - https://www.youtube.com/watch?v=OzjogCFO4Zo
Now I'm just learning about the subject so I may not be 100% correct and there's more to it than what I'm describing here but my basic understanding of unit testing is that you write some test code (which is kept separate from your main code) that calls a function in your main code with input (arguments) that the function requires and the code then checks if it gets back a valid return value. If it does get back a valid value the unit testing framework that you're using to run the tests shows a green light (all good) if the value is invalid you get a red light and you then can fix the problem straight away before you release the new code to production, without testing you may actually not have caught the error.
So you write tests for you current code and create the code so that it passes the test. Months later you or someone else need to modify the function in your main code, because earlier you had already written test code for that function you now run again and the test may fail because the coder introduced a logic error in the function or return something completely different than what that function is supposed to return. Again without the test in place that error might be hard to track down as it can possibly affect other code as well and will go unnoticed.
Also the fact that you have a computer program that runs through your code and tests it instead of you manually doing it in the browser page by page saves time (unit testing for javascript). Let's say that you modify a function that is used by some script on a web page and it works all well and good for its new intended purpose. But, let's also say for arguments sake that there is another function you have somewhere else in your code that depends on that newly modified function for it to operate properly. This dependent function may now stop working because of the changes that you've made to the first function, however without tests in place that are run automatically by your computer you will not notice that there's a problem with that function until it is actually executed and you'll have to manually navigate to a web page that includes the script which executes the dependent function, only then you notice that there's a bug because of the change that you made to the first function.
To reiterate, having tests that are run while developing your application will catch these kinds of problems as you're coding. Not having the tests in place you'd have to manually go through your whole application and even then it can be hard to spot the bug, naively you send it out into production and after a while a kind user sends you a bug report (which won't be as good as your error messages in a testing framework).
It's quite confusing when you first hear of the subject and you think to yourself, am I not already testing my code? And the code that you've written is working like it is supposed to already, "why do I need another framework?"... Yes you are already testing your code but a computer is better at doing it. You just have to write good enough tests for a function/unit of code once and the rest is taken care of for you by the mighty cpu instead of you having to manually check that all of your code is still working when you make a change to your code.
Also, you don't have to unit test your code if you don't want to but it pays off as your project/code base starts to grow larger as the chances of introducing bugs increases.
Unit-testing and TDD in general enables you to have shorter feedback cycles about the software you are writing. Instead of having a large test phase at the very end of the implementation, you incrementally test everything you write. This increases code quality very much, as you immediately see, where you might have bugs.