C++ & proper TDD - c#

Hi! I recently tried developing a small-sized project in C# and during the whole project our team used the Test-Driven-Development (TDD) technique (xunit, moq).
I really think this was awesome, because (when paired with C#) this approach allowed to relax when coding, relax when projecting and relax when refactoring. I suspect that all this TDD-stuff actually simplifies the coding process and, well, it allowed (eventually, for me) to get the same result with fewer brain cells working.
Right after that I tried using TDD paired with C++ (I used Google Test and Google Mock libraries), and, I don't know why but I actually think that TDD here was a step back in terms of rapid application development.
I had some moments when I had to spend huge amounts of time thinking of my tests, building proper mocks, rebuilding them and swearing at my monitor.
And, well, I obviously can't ask something like "what I did wrong?" or "what was wrong in my approach?", because I don't know what to describe. But if there are any people who are used to TDD in C++ (and, probably C#) too, could you please advise me how to do this properly.
Framework recommendations, architecture approaches, plain coding advices - if you are experienced in TDD & C++, please respond.

I think TDD is much harder to do in C++ than C#. The lack of reflection, and the common (and often well-justified) reluctance to rely on dynamic polymorphism (interfaces and in heritance) compared to static polymorphism does make it harder to mock out many classes.
There are some extremely clever unit test frameworks for C++, but the thing that's so clever about them is mainly that they try to bypass the language limitations.
TDD works best in dynamic languages. It's a great way to work in Python. It's doable in C# (which isn't dynamic, but has comprehensive reflection capabilities)
In C++, it's often problematic. That doesn't mean it can't, or shouldn't, be done, but when you do it, expect to have to work a bit harder at it. And sometimes, you may be better off using another approach entirely.

TDD is something that takes some practice to get right, regardless of the platform. What some people don't seem to realize is that the nature of the problem your trying to solve can have a big impact on how easily you can apply TDD to the solution. I've had problems in the past where I knew the solution I wanted to move towards, but it was extremely difficult to figure out how to break the problem up in a way that seemed to fit the TDD model. Now there are several reasons why this may happen, and it's impossible to say what the "right" way to handle that situation is.
At this point my first reaction to running into this sort of problem is to re-examine my original assumptions about the problem. Am I making it more complex than it needs to be? Am I trying to write tests to arrive at a design I've already decided on instead of letting the tests guide the design? Is it just a funky problem, and I need to accept that the typical TDD approach isn't going to work in this case?
For an interesting discussion of this you can look at this blog post from Uncle Bob Martin, where he talks about an attempt by Ron Jeffries to create a Sudoku Solver using TDD, and it doesn't really work. Now because this attempt did not produce a good solution doesn't mean that TDD is useless, it just means that the problem being solved is more complex, and does not lend itself to the emergent design approach of TDD.

Try the easiest - CxxTest.

I find test driven development very hard to do properly all the time; sometimes the tests just flow, sometimes a bit of a jump is required. To keep things fast I frequently step away from the TDD approach. That isn't a problem for me as I maintain a full set of unit tests for all the code I've 'completed' (allowing the relaxation while coding the new bits and refactoring) .

Related

Why is mixing VB.Net and C# in the same solution not recommended?

I was reading this question when I noticed a curious comment underneath:
not sure what the question is: you can use VB.NET and C# projects in one solution (though I wouldn't recommend doing so).
I do this quite a bit, as we have legacy VB.Net code, and new code is written in C#. Is this really not recommended? Why not?
There is no real reason to avoid this, other than adding complexity from having two languages in one "solution".
Your scenario (working with a legacy product, but adding new features) is a valid reason to have both languages used in a single solution, in my opinion.
The only reason that it wouldn't be recommended is consistency. Most developers prefer to deal with a single language when working on an application. Having a single language also means that your developers only need to know a single language rather than knowing both VB.NET and C# (even though the two are extremely similar).
If you need to mix legacy VB.NET and C#, there's no reason not to.
It's a matter of "use the best tools available to you for what you're building". Mixing C# and VB within a project isn't recommended (for obvious "it won't compile" reasons), but there's no point in continuing to write old code in VB if you feel your development team can operate faster and in a more maintainable fashion using C#.
We've been doing this at my office for the past few months (in a similar legacy code situation) and have yet to run into any major issues (beyond potential lost dev time due to context switching), and we've gained incredibly from working with a language that we all feel more comfortable with.
More information on task switching here. I really do feel like the benefits we see on a daily basis from our level of comfort with C# outweighs the cost of occasionally having to dip back into the legacy pool.
Its just a matter of person choice. if you are comfortable with both the languages, You surely can use them in same solution.
Using a single language in a solution seems easily maintainable. hence it is preferred.
Mixing code in solutions can get real messy real quickly, its never clear what method you are calling from where, to keep it nice. Develop in separate Solutions, it will keep your projects easier to track and make sure you are not confusing languages inside projects
Why would you want to do that? If you have legacy code what you want to use, you keep that code in its own components, you don't mix it with the new code. It is not recommended because it does not promote "Clean Code". It can lead you to have a solution that is difficult to read and maintain.

How can i rush the product to the market to meet deadline

I client of mines do not care about elegant and well structured code. I am writing the applications from scratch with minimal 3rd party tools. I am using l2s, Recatcha, tinymce, lucene, and structure map.
I would like to quickly get the clients product to the market as fast as possible while sacrificing elegant code. Are there any tools out there that will enable me to rush the product to the market?
No client ever cares about elegant and well structured code. That's not why you write elegant and well structured code. You write it because it's shorter, simpler, it's faster to write, contains fewer bugs and it is easier to find those bugs.
ADD: I know what I wrote above sounds contradictory. When I started working, I didn't believe that either. I had to learn the hard way. So to make the point clearer: This is what typically happens when you don't try to write elegant, well structured code:
You'll introduce subtle bugs that lead to weird, unreproducible behavior and take 10 times more time to find than writing the code in the first place
You'll solve the same problem multiple times. Or, the other way round: The elegant solution would have solved a set of problems while the ugly solution will only solve one problem. Or part of one problem.
You'll repeat yourself a lot. That means more code to write, more code to maintain, more bugs.
You'll write code that you don't understand a week later. So instead of adding new features/solving bugs you'll waste your time trying to figure out why some piece of code works (or doesn't work)
You'll solve the wrong problems. This is by far the worst danger, and it happens too often if you try to save the time you need to plan the thing properly.
Good code is for you and not your client.
I don't think there exists such a magic pill.
But I would rather recommend you checkout Joel's 12 Steps to Better Code. Not all principles may apply to you (if you are not working with at least a certain number of people) but things like version control, how you deal with bugs, testing and others will help more than what you think.
Assuming that adding more team members is not an option, you can either:
work longer hours (live of coffee and pizza until either you or the project is finished)
defer some features for version 2.
sacrifice quality.
deliver late.
the choice is yours but option 2 would be my recommendation. A program with fewer features that works is better than a feature laden product that can't be relied on.
Bit of a cliché, but there are no tools that can get you the result you're looking for, only people. For that matter, there are no tools that can guarantee you robust, reliable, well-designed and appealing products that people will actually want to use – those are all problems that can only be tackled by meatware. Respectfully, I'd be careful about the whole concept of "rushing a product to market", if I were you: I'm sure you have your reasons for taking that approach, but more haste really does often make for less speed, and less desirable results.
When you don't have time to build a product to reasonable standards then it's important to know which parts you can cut corners on and which you can't.
The most important thing to get right is the interfaces between components. Make sure that they are correct and that coupling between components is as little as you can make it.
If for example you have a report generator that sometimes crashes, occasionally generates the wrong results, and has missing and broken features you can repair it later on when you do have time, or even scrap the whole module and do it properly.
If you've hacked the interface though, and it relies on other components storing their data in certain ways, or relies on the internal workings of other modules it becomes significantly harder to rip it out and replace it cleanly.
Don't skimp on the design of the high level modules and the interfaces between them. Keep asking yourself if I have to rip out this module and do it a different way, will it affect any of my other modules... The answer should as much as possible be know. it's "easy" to go and fix code, but not if it's all one big tangled mess. The small compoents don't need to be good as long as you can replace them easily later.
Obligatory comment - I'm not suggesting anyone writes bad code of course. Just that sometimes there are essential business requirements that make deadlines such that you can't do a good job of everything, and it is an important skill to know which things you can fix up later and which you can't.
So anyway to answer your question design tools such as UML drawing tools etc are probably more use than coding tools
Mostly you end up with this:
(source: scottsimmons.tv)
Another one that I heard a project manager once say about adding extra people to a team:
"It's not because you have 9 women that the time to grow a baby will only take one month."
I would recommend using a continuous integration tool such as CruiseControl.NET or hudson and writing many JUnit tests (or the C# equivalent).
This way even if you develop quickly and don't spend enough time working out all the pieces, the CI server should prevent you from producing bugs which will take you an extremely long time to find.
That said, I agree with what the others stated, you write elegant code so you (or your teammates) will understand it and not so your client is satisfied.

oo-spaghettio web architecture

I've noticed that the majority of enterprise web apps I've worked on over the past few years have seemingly mis-used the powers of oo.
That is, what once would have been perhaps 1000 lines of HTML and script, has often now morphed into 10,000 lines of code, 50 classes, and 2000 method calls to do basically the same thing. I.e. oo and layered architecture appears to be over-used and/or ill-used, often leading to longer development times, higher-cost, and often nightmarish maintenance.
How often are other people seeing this happen?
How can oo be effectively utilized to, as the Buddha himself has said: as much as possible try not to harm...as much as possible try to help...
"The road to hell is paved with the best of intentions."
I haven't personally encountered this myself, but all the times I've heard stories it seems to be an issue of architecture astronauts (people who spend too much time thinking) or bad developers (people who spend too little time thinking).
In the earlier days of programming, you didn't see as much of this because of the limits of the hardware, languages, etc.
However, developers are now are trying to focus on writing code that's understandable by humans for loose coupling and higher maintainability by incorporating as many design patterns and OO principles as they can, but just like everything it can be over-done.
On the other hand, some developers might just not be thinking enough about the problems they're attempting to solve and writing extra code just because it gets the job done and not thinking about the bigger picture.
In either case, developers might not be malicious or even incompetent and want the best for the projects their working on, but they still over-do principles simply because they are trying too hard.
So I would say the solution is to remind developers to use OOP principles as guidelines, but just that. There comes a point when you have to find a happy medium between thinking and programming and just stop thinking and start programming.
See: Jeff wrote a good blog post about just this kind of thing: KISS and YAGNI.
I see these all the time :( Basically if people are going to do a mess they will do it trying or not to use oo design. It gets equally awful on either case.
Update 1: it is important to understand how/what will be reused (but not going crazy on it as that would hinder productivity), since we don't want to get tons of classes where every single one of them aren't reused and fulfill tons of different functions.
Basically the main issue is understanding and caring for what is being built, as you could apply oo, tdd, ddd, anything, and if the devs doesn't understand what they are doing it will end up in the same mess ... or worst :(
Bottom line, these things do help, but they aren't magic, they won't replace the developers skills to create maintainable code.
Update 2: Also note that a checklist or some bullet points won't do it. I mean I love SOLID, and plenty things going on and I think they really clear things up, but they usually make the most impact on the people that have been trying to avoid the mess.

Any BDD success stories out there?

Having written a small article on BDD, I got questions from people asking whether there are any cases of large-scale use of BDD (and specifically NBehave).
So my question goes to the community: do you have a project that used BDD successfully? If so, what benefits did you get, and what could have been better? Would you do BDD again? Would you recommend it to other people?
We've used somewhat of BDD at the code level in different scenarios (open source and ND projects).
Telling the view in MVC scenario, what kind of input to accept from user (DDD and Rule driven UI Validation in .NET)
result = view.GetData(
CustomerIs.Valid,
CustomerIs.From(AddressIs.Valid, AddressIs.In(Country.Russia)));
Telling the service layer, about the exception handling behavior (ActionPolicy is injected into the decorators):
var policy = ActionPolicy
.Handle<WebException>()
.Retry(3);
Using these approaches has immensely reduced code duplication, made the codebase more stable and flexible. Additionally, it made everything more simple, due to the logical encapsulation of complex details.
I was on a small team that used BDD on a website.
The way we used it was essentially TDD, but the tests are simply written as behaviors using a DSL. We did not get into large upfront design of behaviors, but we did create a large number of them, and used them exactly as you would tests.
As you might expect, it worked much as TDD, generally good. Phrasing the tests as behaviors was nice when interacting with the customers and made for a pretty decent document, but I kind of wish the behaviors were written in English and the tests programmed instead of trying to come up with some difficult intermediate language that doesn't fit either purpose perfectly.
It would still be BDD, just without this cute trick of trying to twist the language into a language delineated by a random_looking.set of_Punctuation rather_than simple.spaces, but that was only my grumpy-old-programmer attitude, everyone else was 100% happy with it.
The site is available and fully operational, so I'd call it a success: Have a look
I recently used the BDD style of GWT in a high-level requirements document. I didn't get any feedback about the GWT from the customer buy my boss said he liked it as it was very clear and easy to understand. Note he has no knowledge of BDD that I know of. I didn't put in user stories as this would probably have been a bit too airy fairy for people with a traditional waterfall background. Maybe I'll try putting in user stories next time.
By the way this was not a eye ball UI project. It was an integration project syncing data from a web service into a database. So it shows that GWT works even for non-"eye ball" UIs.
I've been using Context-Specification style on several projects (using MSpec) with great success. I am still trying to understand the real benefits of the Scenario style. The more I use the context-specification style, the more I like it, and the tighter my applications feel.

How to Refactor to Generics from Class that Inherits from CollectionBase?

I am working on an application that is about 250,000 lines of code. I'm currently the only developer working on this application that was originally built in .NET 1.1. Pervasive throughout is a class that inherits from CollectionBase. All database collections inherit from this class. I am considering refactoring to inherit from the generic collection List instead. Needless to say, Martin Fowler's Refactoring book has no suggestions. Should I attempt this refactor? If so, what is the best way to tackle this refactor?
And yes, there are unit tests throughout, but no QA team.
Don't. Unless you have a really good business justification for putting your code base through this exercise. What is the cost savings or revenue generated by your refactor? If I were your manager I would probably advise against it. Sorry.
How exposed is CollectionBase from the inherited class?
Are there things that Generics could do better than CollectionBase?
I mean this class is heavily used, but it is only one class. Key to refactoring is not disturbing the program's status quo. The class should always maintain its contract with the outside world. If you can do this, it's not a quarter million lines of code you are refactoring, but maybe only 2500 (random guess, I have no idea how big this class is).
But if there is a lot of exposure from this class, you may have to instead treat that exposure as the contract and try and factor out the exposure.
If you are going to go through with it, don't use List< T >. Instead, use System.Collections.ObjectModel.Collection< T >, which is more of a spirtual succesor to CollectionBase.
The Collection<T> class provides protected methods that can be used to customize its behavior when adding and removing items, clearing the collection, or setting the value of an existing item. If you use List<T> there's no way to override the Add() method to handle when someone ads to the collection.
250,000 Lines is alot to refactor, plus you should take into account several of the follow:
Do you have a QA department that will be able to QA the refactored code?
Do you have unit tests for the old code?
Is there a timeframe that is around the project, i.e. are you maintaining the code as users are finding bugs?
if you answered 1 and 2 no, I would first and foremost write unit tests for the existing code. Make them extensive and thorough. Once you have those in place, branch a version, and start refactoring. The unit tests should be able to help you refactor in the generics in correctly.
If 2 is yes, then just branch and start refactoring, relying on those unit tests.
A QA department would help a lot as well, since you can field them the new code to test.
And lastly, if clients/users are needing bugs fixed, fix them first.
I think refactoring and keeping your code up to date is a very important process to avoid code rot/smell. A lot of developers suffer from either being married to their code or just not confident enough in their unit tests to be able to rip things apart and clean it up and do it right.
If you don't take the time to clean it up and make the code better, you'll regret it in the long run because you have to maintain that code for many years to come, or whoever takes over the code will hate you. You said you have unit tests and you should be able to trust those tests to make sure that when you refactor the code it'll still work.
So I say do it, clean it up, make it beautiful. If you aren't confident that your unit tests can handle the refactor, write some more.
I agree with Thomas.
I feel the question you should always ask yourself when refactoring is "What do I gain by doing this vs doing something else with my time?" The answer can be many things, from increasing maintainability to better performance, but it will always come at the expense of something else.
Without seeing the code it's hard for me to tell, but this sounds like a very bad situation to be refactoring in. Tests are good, but they aren't fool-proof. All it takes is for one of them to have a bad assumption, and your refactor could introduce a nasty bug. And with no QA to catch it, that would not be good.
I'm also personally a little leary of massive refactors like this. Cost me a job once. It was my first job outside of the government (which tends to be a little more forgiving, once you get 'tenure' it's damn hard to get fired) and I was the sole web programmer. I got a legacy ASP app that was poorly written dropped in my lap. My first priority was to get the darn thing refactored into something less...icky. My employer wanted the fires put out and nothing more. Six months later I was looking for work again :p Moral of this story: Check with your manager first before embarking on this.

Categories