Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Soon I will be involved in a project that will be using the agile project management/development approach, with 5 (or so) 2 week sprints. The project will be using a DDD design pattern which I have found in the past works great with unit testing, hence I have enthusiasim to use it for this project as well. The only problem is given the following factors I am unsure as to whether unit testing can be successfully implemented with agile development:
Potential for constantly changing requirements (requirements change, tests break, tests need to be updated too).
Time factor (unit tests can make dev take a fair bit longer and if requirements change towards the end of a sprint there may be too little time to update tests and production code at the best quality).
I have a feeling that if/when requirements change (especially if towards the end of a sprint) and given the tight deadlines unit tests will become a burden. Anyone have any good advice on the matter?
I think it cuts both ways. On one hand, yes, unit tests are extra code which requires extra maintenance, and will slow you down a bit. On the other hand, if requirements start evolving, having unit tests in place will be a life saver in making sure what you are changing still works.
Unless you have unit tests with high coverage, the cost of change will grow exponentially as the projects moves forward. So basically, the more change you anticipate the MORE you will actually need your unit tests.
Secondly, good unit tests depend on very few and small feature pieces in your production code. When this is true, only a few tests will be impacted when a feature changes. Basically, each test tests just one thing and small piece of production code. The key to writing unit tests that follow this principle is to decouple your code and test in isolation.
Thirdly, you need to get a better understanding of the concept of DONE and why its definition is so important in terms of sustainable development. Basically, you can't go fast over time in a sustainable fashion if your team compromizes the concept of DONE in the short term.
Considering 10+ weeks worth of code with no test coverage makes me cringe. When will you have time to manually test all that code? And under evolving requirements, you will use a lot more time tracking down impacts the changes will have throughout your code base.
I cannot advice strongly enough to use unit testing. Even when doing DDD, let unit tests drive implementation. Coupled with good patterns like DI/IoC and SRP, you should find both your code base and tests to be more resilient to change, and thus save you a lot of time throughout those sprints.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
My team is working on the development of an application running for several years already, but no unit test has ever been coded. Now that we wish starting doing so, we realise we cannot possibly go over all the existing methods to test them because that would take years of work.
The question is : how can one decide which method absolutely need unit testing, and which doesn't?
Would you rather unit test a method that is often called or a method that is often modified?
I read that Unit Testing is rather inefficient on DAO classes. Should I restrain the tests to methods containing logic?
Most important : Will the tests put in place any useful as far as only part of the application is unit tested?
how can one decide which method absolutely need unit testing, and which doesn't?
This is a difficult question to answer without knowing about your code base and what its history and future are. But in general, write tests for the parts of the code that are hard to understand, will get modified in the near future or are known to have bugs. When testing legacy applications, the best bang for your buck is to have tests make the program both easier to maintain going forward, to fix bugs and to keep old bugs from coming back.
Would you rather unit test a method that is often called or a method that is often modified?
As stated above, it depends. Is the method that is called often trivial? Easy to understand? I would probably lean towards "often modified" just to make future development easier. But ideally both should get tested.
I read that Unit Testing is rather inefficient on DAO classes.
I don't know where you read that. Unit testing can be very efficient with DAOs if you use mock objects.
Will the tests put in place any useful as far as only part of the application is unit tested?
Any tests are useful. A program that is only 10% covered by tests is better than a program with 0% coverage. Especially if that 10% is the most important or trickiest part of the program.
If you haven't read it yet, I highly recommend Michael Feather's Working Effectively with Legacy Code where "legacy code" means code that doesn't have tests.
Some people create unit tests for getters and setters and insist on 100% code coverage.
Practical people will test those methods that need testing. What this means will depend on your intelligence and discernment of what constitutes a method that needs testing.
Some people however consider the minimum size of a unit is the class and that tests should be created to test a class (and sometimes its associated classes).
In short, forget any kind of dogmatic principle about unit testing, what matters is the quality of your code. Like agile development, its what helps you to achieve that goal that is important. So if you feel your DAO objects will not benefit from testing, then don't bother - spend that time you would have spent doing something more productive instead.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm in a project where we don't do TDD, because our bosses and the cliente are very "old styled" people. Because I can't do design through TDD but I feel fear to changes, I would like to write unit tests for my own safety. But, how those unit test would be? Do I have to write a test for each method specification for test that they do what it's supposed they do? Do I have to test for each new functionality like TDD but without design? I have a mess in my mind.
Thanks in advance.
You probably can't hurt anything by doing unit tests - regardless of how well they're done - except for one possible side-effect, and that is false confidence.
We tend not to do hardcore TDD, nevertheless the unit test coverage ranges from non-existent to moderate depending on project, and is becoming increasingly valuable as the idea settles in.
For general pointers, I'd say the following are key priorities for you right now:
Test what you know to be important
Test what you know to be fragile
Write tests to expose any new bugs, then solve the bug by making modifications that pass the test
Apply TDD where possible to any new features
Acknowledge that you can't TDD an existing project. By its nature, TDD only applies to new ground, whether that's a new product, or a new feature for a legacy product. Don't let this fact dishearten you.
Yes. TDD is yet another software development technique which happens to utilize unit testing heavily. Unit testing as a process is fine on its own without TDD behind. Not to mention, sometimes it's not even possible to do TDD yet you do write tests (think legacy systems/existing untested code testing).
But as for what you should test. Depending how deep with testing you want (can) go, you can start with end user oriented functionality, through system components testing (ie. class contracts) up to simply assuring your code does what you claim it does - that's pretty much the final, most fine-grained unit test which you'll most likely have a lot of.
In general, what to test is not an easy question, I've happened to answer several variants of that question already, to give you few tips:
test what your code does, not what it does not
if you got certain requirement, have a test covering it
test single feature at time
focus on public contract, skip private bits
Also, reading few of the top voted unit testing questions might give you some ideas on why you will benefit from testing, regardless of using TDD or not.
When you say "we don't do TDD", do you mean that others don't practise TDD or that your bosses forbid you from practising TDD? If it's the first one, then you can practise TDD as much as you want, as long as you don't try to force other people to do it. If it's the other one, then tell your bosses that they pay you to write code the best way you know how, and TDD is part of how you do that.
You can certainly write tests without practising TDD. People do it all the time. Use the old saying, "Test until fear turns to boredom". Write tests for whatever you fear might not work correctly.
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 6 years ago.
Improve this question
I'm in the process of pushing my company towards having unit tests as a major part of the development cycle. I've gotten the testing framework working with our MVC framework, and multiple members of the team are now writing unit tests. I'm at the point, though, where there's work that needs to be done to improve our hourly build, the ease of figuring out what fixtures you need to use, adding functionality to the mock object generator, etc., etc., and I want to be able to make the case for this work to management. In addition, I'd like us to allocate time to write unit tests for the most critical pieces of existing code, and I just don't see that happening without a more specific case than "everyone knows unit tests are good".
How do you quantify the positive impact of (comprehensive and reliable) unit tests on your projects? I can certainly look at the number and severity of bugs filed and correlate it with our increases in code coverage, but that's a rather weak metric.
Sonar is a company that makes a very interesting code inspection tool, they actually try to measure technical debt programaticaly, which correlates untested code and developer price per hour.
Quantification of test-quality is very difficult.
I see code-coverage only as guidance not as test-quality metric. You can literally write test of 100% code-coverage without testing anything (e.g. no asserts are used at all). Also have a look at my blog-post where I warn against metric-pitfalls.
The only sensible quantitative metric I know of and which counts for business is really reduced effort of bug-fixes in production-code. Also reduced bug-severity. Still it is very difficult to isolate that unit-tests are the only source of this success (it could also be improvement of process or communication).
Generally I would focus on the qualitative approach:
Do developers feel more comfortable changing code (because tests are a trustworthy safety net)?
When bugs occur in production analysis really shows that it was untested code (vice versa a minor conlusion that it wouldn't have occurred if there had been unit test)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Jimmy Bogard, wrote an article: Getting value out of your unit tests, where he gives four rules:
Test names should describe the what and the why, from the user’s perspective
Tests are code too, give them some love
Don’t settle on one fixture pattern/organizational style
One Setup, Execute and Verify per Test
In your opinion these guidelines are complete? What are your guidelines for unit tests?
Please avoid specific language idioms, try to keep answers language-agnostic .
There's an entire, 850 page book called xUnit Test Patterns that deal with this topic, so it's not something that can be easily boiled down to a few hard rules (although the rules you mention are good).
A more digestible book that also covers this subject is The Art of Unit Testing.
If I may add the rules I find most important, they would be:
Use Test-Driven Development. It's the by far the most effective road towards good unit tests. Trying to retrofit unit tests unto existing code tend to be difficult at best.
Keep it simple: Ideally, a unit test should be less than 10 lines of code. If it grows to much more than 20 lines of code, you should seriously consider refactoring either the test code, or the API you are testing.
Keep it fast. Unit test suites are meant to be executed very frequently, so aim at keeping the entire suite under 10 s. That can easily mean keeping each test under 10 ms.
Writing unit-tests is simple, it is writing unit-testable code that is difficult.
The Way of Testivus
If you write code, write tests.
Don’t get stuck on unit testing dogma.
Embrace unit testing karma.
Think of code and test as one.
The test is more important than the unit.
The best time to test is when the code is fresh.
Tests not run waste away.
An imperfect test today is better than a perfect test someday.
An ugly test is better than no test.
Sometimes, the test justifies the means.
Only fools use no tools.
Good tests fail.
Break the code in test regularly to see the effectiveness of the unit tests
Take a look at the code coverage of your tests, and try to make it reasonably complete (for error cases I'd use some discretion whether to test them or not).
For many more good ideas to write unit tests, search stackoverflow.com.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
People at my company see unit testing as a lot of extra work, that offers fewer benefits than existing functional tests. Are unit and integration tests worth it? Note a large existing codebase that wasn't designed with testing in mind.
Most people are unaware what automated unit tests are for:
To experiment with a new technology
To document how to use a part of the code
To make sure a dead bug stays dead
To allow you to refactor the code
To allow you to change any major parts of the code
Create a lower watermark below which the quality of your product cannot possibly drop
Increase development speed because now, you know that something works (instead of hoping it does until a customer reports a bug).
So if any of these reasons bring you a benefit, automated unit tests are for you. If not, then don't waste your time.
(I'm assuming that you're using "functional test" to mean a test involving the whole system or application being up and running.)
I would unit test new functionality as I wrote it, for three reasons:
It helps me get to working code quicker. The turnaround time for "unit test failed, fix code, unit test passed" is generally a lot shorter than "functional test failed, fix code, functional test passed".
It helps me to design my code in a cleaner way
It helps me understand my code and what it's meant to be doing when I come to maintain it. If I make a change, it will give me more confidence that I haven't broken anything.
(This includes bug fixes, as suggested by Epaga.)
I would strongly recommend Michael Feathers' "Working Effectively with Legacy Code" to give you tips on how to start unit testing a codebase which wasn't designed for it.
It depends on whether your functional tests are automated or done manually. If it's the latter, then any kind of automated test suite is useful since the cost of running those unit / integration tests is far lower than running manual functional tests. You can show real ROI there. I would recommend starting with writing some integration tests and if time / budget allows in the future, take a look at unit testing then.
Retroactively writing unit tests for legacy code can very often NOT be worth it. Stick with functional tests, and automate them.
Then what we've done is have the guideline that any bug fixes (or new features) must be accompanied by unit tests at least testing the fix. That way you get the project at least going in the right direction.
And I have to agree with Jon Skeet (how could I not?) in recommending "Working Effectively With Legacy Code", it really was a helpful skim/read.
As it happens, I read a paper last night on this very subject. The authors compare projects within four groups at Microsoft and IBM, contrasting, in hindsight, projects which used both unit testing and functional testing and projects which used functional testing alone. To quote the authors:
"The results of the case studies
indicate that the preview release
defect density of the four products
decreased between 40% and 90% relative
to similar projects that did not use
the TDD practice. Subjectively, the
teams experienced a 15 to 35% increase
in initial development time after
adopting TDD."
This indicates that it is certainly worth doing unit testing when you add new functionality to your project.
Yes they are worth it, I am now faster at coding since I started unit testing my code. I spend less time fixing bugs and more time thinking about what my code should do.
One application I was bought in to consult on the FAT (test)ing of consisted of a 21,000 lines switch statement. Most units of functionality were a few dozen to a couple of hundred lines in a case statement. The application was built in several variants, so there were many #ifdef sections of the switch.
It was not designed for unit testing - it was not factored at all.
( It was designed in the sense there was a definite, easy to comprehend architecture - malloc a struct, send the main loop a user message with the pointer to the struct as the lparam and then free it when the message is processed. But form did not follow function, which is the central tenet of good design. )
To add unit testing to new functionality would mean a major break with the pattern; either you would need to put your code somewhere other than the big switch, and double the complexity of the variant selection mechanism, or make a large amount of scaffolding to put the messages in the queue to trigger the new functionality.
So though it's certainly desirable to unit test new functionality, it's not always practical if a system isn't already well factored. Either there's a significant amount of work to refactor the system to allow unit testing, or you end up bench-testing the code and cut and pasting it into the existing framework - and a copy of unit tested code isn't unit tested code.
You test when you want to know something about something. If you know that your product (system, unit, service, component...) is going to work, then there's no need to test it. If you're uncertain as to whether it will work, you probably have some questions about it. Whether those questions are worth answering is a matter of risk and priorities.
If you're sure that your product will work, and you don't have any questions about it, there is still one question that's worth asking: why don't I have any questions?
---Michael B.
Unit testing indeed is extra work but it pays off in the long run. Here are the
advantages over integration testing :
you get a regression suite that acts as a safety net in case of refactoring - the same can be said of integration tests, although it can be tough to say if
the test covers a piece of code.
unit tests give an immediate feedback when modifying the code - and this
feedback can be very accurate, pointing to the method where the anomaly
is.
those tests are cheap to run : they run very fast (a few seconds typically),
without any installation or deployment, just compile and test. So they can be run often.
it is easy to add a new test to reproduce a problem once it is identified,
and it augments the regression suite, or to answer a question ("what happen if
this function is not called with a null parameter ...").
There clearly is some overlap between the two, but they are complementary as they both offer advantages.
Now, like any software engineering process, testing has to be taylored according
to the project needs.
With a large legacy codebase, legacy in the sense of not unit tested, I would
recommend to restrict unit tests to new features added to the code as
unit tests can be hard to introduce. In this regard,
I can only second (third ?) the recommendation of the "Working
Effectively with legacy code" book to help bringing unit testing in an existing
codebase.