<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>andrew tobin @ grr, argh!</title><link>http://grrargh.com/</link><description>The daily frustration that is my life.</description><generator>Graffiti CMS 1.0 (build 1.0.1.963)</generator><lastBuildDate>Wed, 30 Apr 2008 22:00:00 GMT</lastBuildDate><image><link>http://www.grrargh.com/</link><url>http://www.grrargh.com/sitefiles/1000/mutant%20enemy%20no%20bkgrnd.png</url><title>Grr, Argh!</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/crucibleau" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Test Driven Development - Writing Crappy Tests</title><link>http://feedproxy.google.com/~r/crucibleau/~3/KQpd7EbcA44/</link><pubDate>Wed, 30 Apr 2008 23:00:00 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/test-driven-development-writing-crappy-tests/</guid><dc:creator>Andrew Tobin</dc:creator><slash:comments>2</slash:comments><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;Okay, so this is another follow on point from the &lt;a href="http://grrargh.com/blog/code-camp-oz-2008/"&gt;TDD session at Code Camp Oz&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;So the question was around what happens if I write crappy tests, does writing tests matter if I write crappy tests?&lt;/p&gt; &lt;p&gt;As with anything it's garbage in -&amp;gt; garbage out.&lt;/p&gt; &lt;p&gt;And if you write crappy tests, chances are you're going to write crappy code.&lt;/p&gt; &lt;p&gt;And that's a great thing!&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Have I lost you yet?&lt;/p&gt; &lt;p&gt;Okay, so most of you probably know that you write the test, write the smallest possible test, to test a unit of work - and prior to writing your code.&lt;/p&gt; &lt;p&gt;You are keeping your methods small right?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;So, you've written your small test, and it's crappy, and you don't think it's doing things the right way, so you hit go and it fails - red.&lt;/p&gt; &lt;p&gt;Well, that's expected, you haven't written any code.&lt;/p&gt; &lt;p&gt;So you write the code to pass the test, run it again and it's green.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;But you &lt;em&gt;know &lt;/em&gt;it's a crappy test... I mean look at it, it barely covers all the reasoning, maybe you haven't mocked, I mean - you're a &lt;strong&gt;professional developer.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;So pop quiz, hot shot, what do you do?&lt;/p&gt; &lt;p&gt;Think further about the test and refactor the test!&lt;/p&gt; &lt;p&gt;And surprise, it might turn red - your code smells again!&lt;/p&gt; &lt;p&gt;So you go back and refactor your code.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;So why is it great to write crappy tests?&amp;nbsp; Because at least you're writing tests.&lt;/p&gt; &lt;p&gt;What were you doing before that?&amp;nbsp; Well, most people would probably run the program, and it works on their computer, under this instance, if all the data is right and.... many, many crappy ways to do this and you won't get the same degree of confidence.&lt;/p&gt; &lt;p&gt;Because if you're relying on running something, or having some folks out there test it, then when you come to maintain your code you're not in a place where you are &lt;em&gt;confident that you haven't broken code you have written in the past&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;TDD isn't about trying to save you work as far as what I believe - it's about doing the work up-front so you have more confidence in what you are shipping, rather than doing a lot more work maintaining it after it's shipped.&amp;nbsp; It's about having confidence in the product you're shipping.&amp;nbsp; It's about thinking about the methods you are designing prior to jumping in and coding them.&lt;/p&gt; &lt;p&gt;And it's really not about never doing anything wrong - it happens, you &lt;em&gt;refactor it and try again&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Does TDD save you development time?&amp;nbsp; Absolutely not.&lt;/p&gt; &lt;p&gt;Does it cost you twice the time, because you have to write tests and then code? Absolutely not, because when else are you testing and are you really ever testing?&amp;nbsp; Plus there's the benefit that you really sit there and work out exactly what you are trying to achieve (the expectations of the test) prior to going in and coding.&amp;nbsp; It helps you a lot in thinking about the flow of your program.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Should I write crappy tests? Well, it'd be perfect if you wrote great tests, but writing crappy tests isn't the end of the world, as long as you recognise that your tests may not be perfect, and you refactor and fix them as needed. Practice makes perfect after all, right?&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;There's a lot of talk out there that says basically, your tests will never prove that your program works or that it does what you want it to.&amp;nbsp; Your tests prove that your code that you have written, that the tests cover, passes those tests, and should work the way you have tested them to work.&amp;nbsp; &lt;/p&gt; &lt;p&gt;And it gives you the confidence that in the future you can run your tests and prove that you haven't changed your code so they're broken.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Disagree?&amp;nbsp; You know where to flame me! :)&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=KQpd7EbcA44:uC1HUDi-Syc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=KQpd7EbcA44:uC1HUDi-Syc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/KQpd7EbcA44" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/test-driven-development-writing-crappy-tests/</feedburner:origLink></item><item><title>Code Camp Oz 2008</title><link>http://feedproxy.google.com/~r/crucibleau/~3/tsl58Sp5ojY/</link><pubDate>Tue, 29 Apr 2008 23:56:00 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/code-camp-oz-2008/</guid><dc:creator>Andrew Tobin</dc:creator><slash:comments>1</slash:comments><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;So this post might be a few days late and a few days past people caring or searching for information, but there was part of me that has been a bit unmotivated on the blogging front - and instead I'm twittering a bunch more, and there was part of me that just wanted to collect some thoughts before I actually went ahead and blogged about it.&lt;/p&gt;
&lt;p&gt;As you no doubt have seen, our tweets for the weekend can be found on &lt;a href="http://www.hashtags.org/tag/ccoz/"&gt;Hashtags&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So basically, I guess I'll just go ahead and break it down by the sessions we attended.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Day 1:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pimp my App - Shane Morris&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We first got there for Shane's presentation on User Experience (UX) design and it was pretty straight forward, and a lot of common sense on presentation and screen layouts and usability... nothing really mind-blowing, but like I was saying to the guys on the way home, some times you really need to be knocked on the head over common sense issues regularly to keep it in mind.&lt;/p&gt;
&lt;p&gt;I've seen my share of terrible user interfaces, and to be fair, there's a few that I've been involved with that I've slapped together because getting the functionality out there has been more important than the user experience.&amp;nbsp; And yes, the user has been thrilled to have the functionality, but usually has had to nut out what exactly their doing, or have me come explain it, or... and it doesn't make me proud of what I achieved.&lt;/p&gt;
&lt;p&gt;So I got what the session was about, and it was probably a good thing to have... at the same time, it wasn't code, and didn't hold my interest a great deal because of that... but again, a good thing to have because you honestly do need a good reminder.&lt;/p&gt;
&lt;p&gt;I think &lt;a href="http://www.codinghorror.com/blog/archives/001058.html"&gt;Jeff Atwood's post about Perceived Performance in Vista's file copy&lt;/a&gt; is another short and quick statement on the same ideas (not so much in quality of interface, but in user perception).&amp;nbsp; It doesn't matter if you're doing something better behind the scenes, if the user doesn't see it as being better.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Taking App Design to the Next Level with Data Mining - Peter Myers&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It's an interesting session, and Peter is a great presenter and a really good guy - I've met him before at previous code camps and even sat with him and had a talk through some of the presentations and he's come off as a really cool guy who knows his stuff.&lt;/p&gt;
&lt;p&gt;That said, the session had no interest for me because it was what he presented at SQL Code Camp two years ago, verbatim.&lt;/p&gt;
&lt;p&gt;Loved it then, would have loved it now.&amp;nbsp; If I hadn't already seen it.&lt;/p&gt;
&lt;p&gt;Although to be fair, I'd gather that there was a large part of the audience who hadn't seen it, which makes me wonder how much crossover there is between Code Camp and SQL Code camp.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Binding Oriented Programming - SyncLINQ - Paul Stovell&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It's hard not to be starstruck by Paul.&amp;nbsp; I pointed out to one of the guys we were with that he's only turned 21 this year(?), and he's achieved so much and become an incredible developer.&lt;/p&gt;
&lt;p&gt;And I am convinced that he's learned the art of touch typing with his feet from cyber monks in a techno monastery in Nepal and is co-ordinated to type with all four limbs at once.&lt;/p&gt;
&lt;p&gt;That or there is some truth to the &lt;a href="http://www.paulstovell.com/blog/paul-stovell-software-agent"&gt;post he made that he's really just the embodiment of a Software Agent&lt;/a&gt; and they spin up more instances of him as required.&lt;/p&gt;
&lt;p&gt;Either way he's achieved a lot more, and gotten a lot more software written than I think most of us does, and it's amazing what he's achieved in basically what is a hobby project in his own time.&lt;/p&gt;
&lt;p&gt;SyncLINQ should be part of the framework - period, and I think that the entire room was blown away with it.&lt;/p&gt;
&lt;p&gt;Later he was overheard talking about having to fly home, and was never spotted anywhere near an airport.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In The Trenches with Test Driven Development - Philip Beadle&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This was about the most controversial session for me.&lt;/p&gt;
&lt;p&gt;And it got a heck of a lot of buzz and discussion on twitter.&lt;/p&gt;
&lt;p&gt;And I am totally not an expert on TDD, but have done it for a short while.&lt;/p&gt;
&lt;p&gt;On twitter I mentioned that I thought this session was flawed because it ended up being about Test Driven Development of the DotNetNuke system.&amp;nbsp; Bringing in DNN in the conversation complicated and made a conversation that should have introduced TDD to the group a lot harder for Philip I think.&lt;/p&gt;
&lt;p&gt;Although I was surprised that there wasn't more hands up when asked who did TDD.&lt;/p&gt;
&lt;p&gt;&lt;strike&gt;So basically I would have been happier with a more introductory session, and again I didn't pay a whole lot of attention, but at one point a member of the audience asked about Red-Green refactoring.&lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;&lt;strike&gt;Philip explained that there wasn't a whole lot to refactor in the two lines the code was testing - and the code was already written so the test went green.&lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;&lt;strike&gt;At this point I really tuned out.&lt;/strike&gt;&lt;/p&gt;
&lt;p&gt;[Update: I must have already been a bit tuned out, apparently I misinterpretted what Philip was saying and he was making the point about the word &amp;quot;refactor&amp;quot; and he did in fact use red/green testing. Apologies for the error.]&lt;/p&gt;
&lt;p&gt;Having tests go red and fail is pretty critical to TDD, and the code should not have been written before the test - this is Test DRIVEN Development after all - but again probably difficult since it was being discussed in the context of an existing software framework.&lt;/p&gt;
&lt;p&gt;The member of the audience was entirely correct on this though, and even if it was two lines there is a procedure - the test fails, you write the code, the test passes.&lt;/p&gt;
&lt;p&gt;And sure, it's okay to cheat, especially when you know what you're doing - but saying that it doesn't matter to someone you're introducing to the whole concept?&lt;/p&gt;
&lt;p&gt;Yeah... anyway, it also suffered because he made his own mocking classes and did it all hand rolled... which is fine for his project, and it's the way he wanted to go with it.&lt;/p&gt;
&lt;p&gt;But if you're introducing a concept like mocking to the general community, for the love of god, use an existing framework, or at least reference the existence of them!&lt;/p&gt;
&lt;p&gt;People need to know that they don't have to write their own, there are Rhino.Mocks, TypeMock, Moq, and probably others out there.&lt;/p&gt;
&lt;p&gt;And the best thing is, they're much more capable at being tested by setting expectations, and actually failing unit tests for you.&lt;/p&gt;
&lt;p&gt;Anyway, I don't think it was a terrible session and I think that it was probably fine for what it was (I just switched off at a point), but I think it was hamstrung by the scenario it was in (DNN).&lt;/p&gt;
&lt;p&gt;I think that at a point that decision was made, and the choices around that scenario made the presentation great for people who were also in that exact same scenario, but not great to introduce TDD to a new audience, and maybe that isn't what Philip was trying to achieve - but I wish it was.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Silverlight 2.0 and WPF - What's the same, What's different - Joseph Cooney&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Good for what it was, I guess.&lt;/p&gt;
&lt;p&gt;It was a bit too much slides and comparing lists of what's the same and what is different.&amp;nbsp; Which now that I say that is exactly what it was billed as.&lt;/p&gt;
&lt;p&gt;I would have actually liked to see a migration from WPF to Silverlight if time had permitted, even just a simple app - just to say &amp;quot;hey look guys, it can be this simple&amp;quot; or &amp;quot;this is how much you need to change in a basic application&amp;quot;.&lt;/p&gt;
&lt;p&gt;Actually I think a lot of the Code Camp was Powerpoint Driven Design, but hey that might just be me (and I so couldn't do any better!).&lt;/p&gt;
&lt;p&gt;Anyway, it was a fine presentation and Joseph is a great presenter.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ORM Smackdown - ADO.NET Entities and NHibernate - Adam Cogan and Justin King&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We left during this one but it seemed to me NHibernate was getting thrown to the wolves by that point anyway.&lt;/p&gt;
&lt;p&gt;I don't know - I think there's a point at which you really have to try these things out for yourself and see what's more comfortable rather than following two guys even if they don't have an agenda in regards to recommending a product.&lt;/p&gt;
&lt;p&gt;And in fact I would have liked to have stuck around to see more of them building up and debugging things to see how it would actually go to make up my mind about this session.&lt;/p&gt;
&lt;p&gt;I would actually like to see other sessions like this and maybe not by two guys in the same company, even though I guess it's a helluvalot easier to co-ordinate a session that way.&lt;/p&gt;
&lt;p&gt;I'd love to see something like a Resharper vs Refactor! live code-off!&lt;/p&gt;
&lt;p&gt;Because a lot of us hear about these tools but haven't actually gone and looked at them, and the choice is pretty up in the air, and it'd be good to see someone who uses them daily show what they're capable of in a live and not canned situation.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Day 2:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WPF And Business Applications - Scott Berry&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Or, Introduction to WPF - Scott Berry.&lt;/p&gt;
&lt;p&gt;We were so keen on this presentation that we woke up at 5am and drove in early to catch it, and it was so incredibly basic that we went a bit mean on Scott on twitter.&lt;/p&gt;
&lt;p&gt;Which totally wouldn't have been the case if it was billed as what it was (please, can has blurb about session on site?)&lt;/p&gt;
&lt;p&gt;I really think if expectations were set, if there was a quick paragraph blurb, or rundown on what was going to be covered, we'd have been happier - and slept in.&lt;/p&gt;
&lt;p&gt;What we would have loved to have seen was: specific business UI discussion, validation, reusability, decisions that a business should make, emphasis on business.&lt;/p&gt;
&lt;p&gt;What we got: Blend, a UI that looks more hobby app or prototype than anything I'd associate with business, gradient fills on buttons.&lt;/p&gt;
&lt;p&gt;Maybe a little unfair, but when I think business app I don't think about gold titles, and getting the right charcol gradient on button - I think about making my app look like every other basic business app on the market - ie Outlook and Office, etc.&lt;/p&gt;
&lt;p&gt;So you want to sexy your business apps up? That's fine... but again, after Shane Morris' great presentation on UX, I half expected to see the same concepts at play in this session - to create an application with a business feel to it.&lt;/p&gt;
&lt;p&gt;Plus the scenes of Star Wars totally blew any momentum you had in your talk and got a little old quick, man.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rapid Fire: How Well do you know your IDE? - Mahesh Krishnanm&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Loved, loved, loved this session.&amp;nbsp; Let me know how much I don't know about navigating around VS.&lt;/p&gt;
&lt;p&gt;Would have been cool if he had &lt;a href="http://weblogs.asp.net/rosherove/archive/2007/06/03/train-to-be-a-keyboard-master-with-keyboard-jedi.aspx"&gt;Keyboard Jedi&lt;/a&gt; going so we could see the shortcuts in action as he was going.&lt;/p&gt;
&lt;p&gt;And a microphone - I don't know the first couple of sessions were hard to hear.&lt;/p&gt;
&lt;p&gt;Anyway, this was a fantastic little session that just really made it worth showing up for.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rapid Fire: Do you want a connection with that? - Nick Randolph&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Great session on Occasionally Connected systems, and given I have a few systems like CCNET and Witty that throw errors every time I lose a connection, more people need to go through it! :P&lt;/p&gt;
&lt;p&gt;Uh, apologies to the Witty guys there, it is free, and if it was that much of a pain I could go in and try and fix it - it is open source after all.&lt;/p&gt;
&lt;p&gt;But still!&lt;/p&gt;
&lt;p&gt;Anyway, it's a shame that it wasn't a full session as Nick's presentation was really interesting and could have easily kept going and held our interest.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lessons learned while tuning Database systems - Fernando Guerrero&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Fantastic presentation and full of stuff that is probably beyond what we'll ever need, given we don't deal with bajillion row tables, and probably not something that we'll take into huge account on existing systems, but definitely something that I think will weigh on our minds when we start architecting new systems.&lt;/p&gt;
&lt;p&gt;Just really interesting the little tweeks you can do to get major performance out of your backend.&lt;/p&gt;
&lt;p&gt;And Fernando was just so entertaining and really great at keeping the interest and throwing in anecdotes and tips that had you entertained along the way.&lt;/p&gt;
&lt;p&gt;Completely loved it.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And at that point, basically we skipped out of Dodge, before Mitch's presentation.&lt;/p&gt;
&lt;p&gt;We're not going to go with Team Foundation any time soon and Facebook doesn't really hold any interest for us as a hobby or for work.&lt;/p&gt;
&lt;p&gt;Luke's sounded like it would have been interesting, but we just didn't want to hang around.&lt;/p&gt;
&lt;p&gt;Anyway, it was a great weekend and we did learn quite a bit - and there was a lot that showed that we were kind of on the right track at work with what's going on out there... so that was fun.&lt;/p&gt;
&lt;p&gt;And like &lt;a href="http://www.madprops.org/cs/blogs/mabster/archive/2008/04/27/code-camp-oz-2008.aspx"&gt;Mabster&lt;/a&gt; mentioned, we had quite a bit of fun on twitter, like it's own little mini-conference there as an extra layer to Code Camp, and learnt a bit off that and actually met some folks where we would usually stay in our own little corner :)&lt;/p&gt;
&lt;p&gt;So we had a lot of fun for the weekend and huge thanks to &lt;a href="http://notgartner.wordpress.com/"&gt;Mitch Denny&lt;/a&gt;, &lt;a href="http://sqlblog.com/blogs/greg_low"&gt;Greg Low&lt;/a&gt;, Mai Low, CSU and everyone else involved.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=tsl58Sp5ojY:PdiuCLYiiDY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=tsl58Sp5ojY:PdiuCLYiiDY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/tsl58Sp5ojY" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/code-camp-oz-2008/</feedburner:origLink></item><item><title>AWDNUG April - Unit Testing and Mocking</title><link>http://feedproxy.google.com/~r/crucibleau/~3/2O9CpzK33bs/</link><pubDate>Tue, 08 Apr 2008 22:39:04 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/awdnug-april-unit-testing-and-mocking/</guid><dc:creator>Andrew Tobin</dc:creator><slash:comments>0</slash:comments><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;So last night we had a slightly earlier AWDNUG meeting, due to some changes the guys wanted... unfortunately not bringing more people in, like we had hoped (a few people mentioned a change in night would make it easier for them to attend).&lt;/p&gt; &lt;p&gt;There was however, a fantastic presentation by &lt;a href="http://madprops.org/"&gt;Mabster&lt;/a&gt; about Unit Testing, specifically using the NUnit framework and how to go about the process of Test Driven Development.&lt;/p&gt; &lt;p&gt;He provided instructions from the basic setup and it was a great session that gave me a bit more of an idea, because for the moment TDD is kind of an abstract thought to my day-to-day process, and I think it's a hard sell to say to the boss that a 6 month project could be an 8 month project, to allow you time to write the tests... but then I don't think we test adequately at all - there's a lot of faith, and hoping users pick up mistakes before they cost us.&lt;/p&gt; &lt;p&gt;So I was incredibly interested in this session and Mabs happens to be my boss at my work and slowly we're trying to change the thinking of the department and the company, to provide more reliable and solid development.&lt;/p&gt; &lt;p&gt;So I'm hoping the group as a whole got something out of it too.&lt;/p&gt; &lt;p&gt;The other thing we covered was Mocking frameworks, specifically Moq, and that went down a little harder than Unit Testing.&amp;nbsp; Although people got the concept, the verbosity in setting one up (you're more or less replicating what you would code line for line) made them a little reluctant.&lt;/p&gt; &lt;p&gt;It is interesting to think how you would mock an interface without first having written your code to use that interface - because you are kind of copying that code, but providing mock objects... so it's an interesting thought how to do the mocking first, in a TDD scenario, without knowing exactly how your end code works.&lt;/p&gt; &lt;p&gt;Anyway, so that's what we covered.&amp;nbsp; Hopefully next month we'll be doing a Heroes Happen Here launch event with some giveaways, thanks to Microsoft.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=2O9CpzK33bs:Qx60Tz2_ZiA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=2O9CpzK33bs:Qx60Tz2_ZiA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/2O9CpzK33bs" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/awdnug-april-unit-testing-and-mocking/</feedburner:origLink></item><item><title>Playing with Extension Methods: .ToDataTable();</title><link>http://feedproxy.google.com/~r/crucibleau/~3/8voFI1pTaTI/</link><pubDate>Wed, 19 Mar 2008 09:09:00 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/playing-with-extension-methods-todatatable/</guid><dc:creator>Andrew Tobin</dc:creator><slash:comments>0</slash:comments><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;Today at work &lt;a href="http://www.madprops.org/cs/blogs/mabster/"&gt;Mabster&lt;/a&gt; and I were discussing Mocking Frameworks after viewing &lt;a href="http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx"&gt;Scott Hanselman's MVC&lt;/a&gt; videos.&lt;/p&gt;
&lt;p&gt;Then Matt brought up that he had heard about this &lt;a href="http://code.google.com/p/moq/"&gt;Moq framework&lt;/a&gt; that uses Lambdas to do some mocking and wanted to try it out.&lt;/p&gt;
&lt;p&gt;So he played with it for a while and was trying to get an SqlReader mocked up completely so he could mock a call back to a database, obviously without a database.&lt;/p&gt;
&lt;p&gt;He ran into a bit of trouble trying to mock up an IDataReader the way he wanted and asked around online for a bit of a hand, he needed a way to get a sample DataTable set up easily.&lt;/p&gt;
&lt;p&gt;Anyway, I thought why couldn't he just somehow define one from a List?&amp;nbsp; Being fairly new to the world of .NET, but having read a bit, I thought it wouldn't be too hard - until he mentioned there wasn't a straightforward way to do that.&lt;/p&gt;
&lt;p&gt;So I started playing around thinking that maybe there could be an easy way to make an extension method to convert a List to a DataTable, and ended up getting all into Generics and Reflection to get it sorted.&lt;/p&gt;
&lt;p&gt;I got a fairly basic version to prove the concept and tonight Matt and I have had another dig into it, and with Matt's help we've got a fairly good implementation for a .ToDataTable() with lambdas, and things doing most of the work for us.&lt;/p&gt;
&lt;p&gt;This won't work with nested tables at the moment, but should allow anything that implements IEnumerable to change into a DataTable, if you ever feel the need!&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
       &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataTable ToDataTable&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; list)
       {
           var table = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataTable();

           &lt;span class="kwrd"&gt;if&lt;/span&gt; (list.Count() == 0) &lt;span class="kwrd"&gt;return&lt;/span&gt; table;

           var objectType = list.First().GetType();

           &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var t &lt;span class="kwrd"&gt;in&lt;/span&gt; objectType.GetProperties().Where(p =&amp;gt; p.CanRead &amp;amp;&amp;amp; p.GetIndexParameters().Length == 0))
           {
               var col = table.Columns.Add(t.Name);
               col.ExtendedProperties[&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;] = &lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;;
               col.DataType = t.PropertyType; 
           }

           &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var t &lt;span class="kwrd"&gt;in&lt;/span&gt; objectType.GetFields().Where(f =&amp;gt; f.IsPublic))
           {
               var col = table.Columns.Add(t.Name);
               col.ExtendedProperties[&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;] = &lt;span class="str"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;;
               col.DataType = t.FieldType;
           }

           &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var listRow &lt;span class="kwrd"&gt;in&lt;/span&gt; list)
           {
               var tableRow = table.NewRow();
               &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (DataColumn col &lt;span class="kwrd"&gt;in&lt;/span&gt; table.Columns)
               {
                   &lt;span class="kwrd"&gt;if&lt;/span&gt; (col.ExtendedProperties[&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;].ToString() == &lt;span class="str"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;)
                   {
                       var p = objectType.GetField(col.ColumnName);
                       &lt;span class="kwrd"&gt;if&lt;/span&gt; (p != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                       {
                           tableRow[col.ColumnName] = p.GetValue(listRow);
                       }
                   }
                   &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (col.ExtendedProperties[&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;].ToString() == &lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;)
                   {
                       var p = objectType.GetProperty(col.ColumnName);
                       &lt;span class="kwrd"&gt;if&lt;/span&gt; (p != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                       {
                           tableRow[col.ColumnName] = p.GetValue(listRow, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
                       }
                   }
               }
               table.Rows.Add(tableRow);
           }

           &lt;span class="kwrd"&gt;return&lt;/span&gt; table;
       }
&lt;/pre&gt;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;/p&gt;
&lt;p&gt;This will even work with Anonymous Type list being passed into it like the following:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
            var myTable = (
                &lt;span class="kwrd"&gt;new&lt;/span&gt;[] { 
                    &lt;span class="kwrd"&gt;new&lt;/span&gt; { FirstName = &lt;span class="str"&gt;&amp;quot;Bob&amp;quot;&lt;/span&gt;, LastName = &lt;span class="str"&gt;&amp;quot;Smith&amp;quot;&lt;/span&gt;, Stuff = &lt;span class="kwrd"&gt;new&lt;/span&gt; { Age = 80 } }, 
                    &lt;span class="kwrd"&gt;new&lt;/span&gt; { FirstName = &lt;span class="str"&gt;&amp;quot;John&amp;quot;&lt;/span&gt;, LastName = &lt;span class="str"&gt;&amp;quot;Doe&amp;quot;&lt;/span&gt;, Stuff = &lt;span class="kwrd"&gt;new&lt;/span&gt; { Age = 32 } }             
                }).ToDataTable();&lt;/pre&gt;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;/p&gt;
&lt;p&gt;We also got one working that you can pass the columns that you want returned, if you only want a few columns from your class list back:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; DataTable ToDataTable&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; IEnumerable&amp;lt;T&amp;gt; list, &lt;span class="kwrd"&gt;params&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] columns)
        {
            var table = &lt;span class="kwrd"&gt;new&lt;/span&gt; DataTable();

            &lt;span class="kwrd"&gt;if&lt;/span&gt; (list.Count() == 0) &lt;span class="kwrd"&gt;return&lt;/span&gt; table;

            var objectType = list.First().GetType();

            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var column &lt;span class="kwrd"&gt;in&lt;/span&gt; columns)
            {
                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var t &lt;span class="kwrd"&gt;in&lt;/span&gt; objectType.GetProperties().Where(p =&amp;gt; p.CanRead &amp;amp;&amp;amp; p.GetIndexParameters().Length == 0 &amp;amp;&amp;amp; p.Name == column))
                {
                    var col = table.Columns.Add(t.Name);
                    col.ExtendedProperties[&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;] = &lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;;
                    col.DataType = t.PropertyType;
                }

                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var t &lt;span class="kwrd"&gt;in&lt;/span&gt; objectType.GetFields().Where(f =&amp;gt; f.IsPublic &amp;amp;&amp;amp; f.Name == column))
                {
                    var col = table.Columns.Add(t.Name);
                    col.ExtendedProperties[&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;] = &lt;span class="str"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;;
                    col.DataType = t.FieldType;
                }
            }
            &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var listRow &lt;span class="kwrd"&gt;in&lt;/span&gt; list)
            {
                var tableRow = table.NewRow();
                &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (DataColumn col &lt;span class="kwrd"&gt;in&lt;/span&gt; table.Columns)
                {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (col.ExtendedProperties[&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;].ToString() == &lt;span class="str"&gt;&amp;quot;F&amp;quot;&lt;/span&gt;)
                    {
                        var p = objectType.GetField(col.ColumnName);
                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (p != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                        {
                            tableRow[col.ColumnName] = p.GetValue(listRow);
                        }
                    }
                    &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (col.ExtendedProperties[&lt;span class="str"&gt;&amp;quot;Type&amp;quot;&lt;/span&gt;].ToString() == &lt;span class="str"&gt;&amp;quot;P&amp;quot;&lt;/span&gt;)
                    {
                        var p = objectType.GetProperty(col.ColumnName);
                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (p != &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                        {
                            tableRow[col.ColumnName] = p.GetValue(listRow, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
                        }
                    }
                }
                table.Rows.Add(tableRow);
            }

            &lt;span class="kwrd"&gt;return&lt;/span&gt; table;
        }&lt;/pre&gt;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;/p&gt;
&lt;p&gt;And you can call that like this:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
            var myTable = (
                &lt;span class="kwrd"&gt;new&lt;/span&gt;[] { 
                    &lt;span class="kwrd"&gt;new&lt;/span&gt; { FirstName = &lt;span class="str"&gt;&amp;quot;Bob&amp;quot;&lt;/span&gt;, LastName = &lt;span class="str"&gt;&amp;quot;Smith&amp;quot;&lt;/span&gt;, Stuff = &lt;span class="kwrd"&gt;new&lt;/span&gt; { Age = 80 } }, 
                    &lt;span class="kwrd"&gt;new&lt;/span&gt; { FirstName = &lt;span class="str"&gt;&amp;quot;John&amp;quot;&lt;/span&gt;, LastName = &lt;span class="str"&gt;&amp;quot;Doe&amp;quot;&lt;/span&gt;, Stuff = &lt;span class="kwrd"&gt;new&lt;/span&gt; { Age = 32 } }             
                }).ToDataTable(&lt;span class="str"&gt;&amp;quot;Stuff&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;p&gt;I'm not sure how much use a DataTable might be for most people, but it was a great little skills project to learn a bit more about C# and it may help us out mocking some more projects in the future!&lt;/p&gt;
&lt;p&gt;Anyway, thanks to Matt for the help, and I hope someone gets something out of this!&lt;/p&gt;
&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=8voFI1pTaTI:S6Ufw9lUHWw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=8voFI1pTaTI:S6Ufw9lUHWw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/8voFI1pTaTI" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/playing-with-extension-methods-todatatable/</feedburner:origLink></item><item><title>Tom Cruise cut scene from Starship Troopers</title><link>http://feedproxy.google.com/~r/crucibleau/~3/ZTu9wIIiHmQ/</link><pubDate>Thu, 24 Jan 2008 01:15:25 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/tom-cruise-cut-scene-from-starship-troopers/</guid><dc:creator>Andrew Tobin</dc:creator><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;Seriously, watch the Scientology video that he is in, skip through the parts with Tom Cruise and just watch the voice over and graphics at the start, the logo, and the end voice over and graphics at 8:50 and tell me that it isn't just totally the same as the ads and tv news segments from the movie Starship Troopers!&lt;/p&gt; &lt;p align="center"&gt;&lt;embed src="http://www.youtube.com/v/UFBZ_uAbxS0&amp;amp;rel=1" width="425" height="355" type="application/x-shockwave-flash" wmode="transparent"&gt;&lt;/embed&gt;&lt;/p&gt; &lt;p&gt;Especially with the "Examiner" desk, reminding you of the psychic recruiting, and the "1 billion people!" dedicating their lives to eradicating the bug invasion... or something.&lt;/p&gt; &lt;p&gt;I guess the only difference is, although they're both to do with science, there's nothing fictional about Scientology, right?&lt;/p&gt; &lt;p align="center"&gt;&lt;embed src="http://www.youtube.com/v/faFuaYA-daw&amp;amp;rel=1" width="425" height="355" type="application/x-shockwave-flash" wmode="transparent"&gt;&lt;/embed&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=ZTu9wIIiHmQ:94wz_wJh9VM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=ZTu9wIIiHmQ:94wz_wJh9VM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/ZTu9wIIiHmQ" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/tom-cruise-cut-scene-from-starship-troopers/</feedburner:origLink></item><item><title>In the land of Continuous Integration</title><link>http://feedproxy.google.com/~r/crucibleau/~3/vhB7fKliwcE/</link><pubDate>Tue, 15 Jan 2008 10:34:41 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/in-the-land-of-continuous-integration/</guid><dc:creator>Andrew Tobin</dc:creator><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;So I've been keeping pretty quiet lately, mostly from a lack of anything too exciting in my life, but I thought it might be interesting to discuss what I've been doing at work on and off for the last month.&lt;/p&gt; &lt;p&gt;Basically, a while ago I got our support guys to make me a Build Server on our Virtual Server farm, and I've finally gotten to the point I have found a few hours here and there to have a play with it.&lt;/p&gt; &lt;p&gt;So at work we have &lt;a href="http://www.sourcegear.com/"&gt;Sourcegear's Vault Source Control&lt;/a&gt; which works beautifully for what we need. We're a pretty small team that can't spend a lot of time going out and maintaining our tools and Vault seems to manage us way more than we manage it.&lt;/p&gt; &lt;p&gt;So we have our code safely locked away and under control, and we have fairly good standards as far as our internal frameworks and coding standards, but we're pretty slow on the uptake of anything agile or in the realm of Test Driven Development - and not because we're not interested, but more the fact that our dev team is split between our business units and we're developing for our own sections, and there's really one or two guys working their area - to remain quick we haven't really been agile (if that makes sense).&lt;/p&gt; &lt;p&gt;Right now we're going through a bit of a period where we're really taking a look at how we can do things smarter, build a system that manages us a little bit more, so we can spend the time actually making things that just work.&lt;/p&gt; &lt;p&gt;So Unit Tests are one thing we'll be trying to do better at over time, but since I had the time I got &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;Cruise Control .NET&lt;/a&gt; up and going on our build server so we can work across the groups a little, work on the same projects a little more, and automate our tests and code checkups a little to make it quicker for us to develop, but still maintain complete coverage of our testing.&lt;/p&gt; &lt;p&gt;It's integrating fine with Vault, and we have it building great - however, I was finding it hard to get FxCop to run without causing a build failure.&amp;nbsp; Even though I'm using MSBuild for build tasks, I have ended up installing NAnt and using similar code to the &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Using+CruiseControl.NET+with+FxCop"&gt;block found on the Cruise Control .NET website to run FxCop&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;We're using MsTest to do our testing due to the great integration with Visual Studio 2008, however, it doesn't integrate as well with Cruise Control .NET as far as showing results - it might be a case of having to dig into the XSL templates to better understand how the results and statistics are being displayed.&lt;/p&gt; &lt;p&gt;Currently we're running MsTest as advised with a batch file, again from the Cruise Control .NET documentation, but since we've started using NAnt for FxCop, I might swap that over to be run from NAnt as well.&lt;/p&gt; &lt;p&gt;The other thing I'd love to check out is &lt;a href="http://www.ndepend.com/"&gt;NDepend&lt;/a&gt;, however, I think the cost might be a barrier - at the moment the company is sticking to a needs only purchase scheme, and this is just a nice to have.&amp;nbsp; There's a good mini-review over on &lt;a href="http://nayyeri.net/blog/code-analysis-with-ndepend/"&gt;Keyvan Nayyeri's blog&lt;/a&gt; and he recommends, so I might give the trial version a run and see if the other guys on the team find it valuable.&lt;/p&gt; &lt;p&gt;So what do we get for all this?&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The ability to have a build run automatically after a check-in to the source control, so if someone doesn't "Get Latest Version" or if we have a few guys covering the same code and something arises, we find out straight away.&lt;/li&gt; &lt;li&gt;We get our tests run every time we check-in updates - and we don't have to spend the cycles waiting for our development machines to do them.&lt;/li&gt; &lt;li&gt;We get FxCop, and maybe NDepend, coverage information on where we're not adhering to standards, and again we're not spending the cycles on our own machines.&lt;/li&gt; &lt;li&gt;We get to find out who checked in the code who broke the build, and which files, so we can go into Vault straight away to do a compare and find out what's new, and what is the probable cause.&lt;/li&gt; &lt;li&gt;A simple dashboard tool that can show where all our projects are up to - no matter who is adding to it.&lt;/li&gt; &lt;li&gt;Better statistic, testing, and reporting whenever we update our codebases.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;I know this post has been a bit of a rant, and more of a "where I'm up to" rather than a helpful post... but I'd definitely recommend having the build server - if you don't have a build server, and even a small team that's working across the same code... even if you can't build a server, find a spare slower PC and just use that.&lt;/p&gt; &lt;p&gt;Remember, the build server won't be doing much other than waiting and then spending a bit of time now and then compiling and testing your code - so it doesn't need to be a beast.&lt;/p&gt; &lt;p&gt;It really is a simple matter to set up the software, and the build scripts are fairly simple at their basic levels - the only thing I'd like to see is the ability to separate projects into their own configuration files (at the moment they share one for Cruise Control).&lt;/p&gt; &lt;p&gt;Anyway, I might do a more helpful post later on - but if you want to contact me to ask any questions about this configuration, or some help setting it up - feel free to drop a comment!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=vhB7fKliwcE:-gYRF20bOWY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=vhB7fKliwcE:-gYRF20bOWY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/vhB7fKliwcE" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/in-the-land-of-continuous-integration/</feedburner:origLink></item><item><title>I have something in common with a Republican Presidential Candidate?</title><link>http://feedproxy.google.com/~r/crucibleau/~3/BEuShrgQAqg/</link><pubDate>Tue, 08 Jan 2008 13:12:27 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/i-have-something-in-common-with-a-republican-presidential-candidate/</guid><dc:creator>Andrew Tobin</dc:creator><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;So I'm watching Mike Huckabee on Letterman and he just told a story about when he was running a radio show in Arkansas and had been on the radio show from 5am and talking and playing music for two hours, and then someone called in asking why they weren't on the air.&lt;/p&gt; &lt;p&gt;He had left the transmitter turned off!&lt;/p&gt; &lt;p&gt;Strange thing - when I was 18 a friend of mine ran a radio show on the local station here, and we'd all go in - we weren't all that trustworthy so we weren't allowed access to the stations cd library, so we'd bring our own in.&lt;/p&gt; &lt;p&gt;And being 18 and paying rent and our own fuel and what not we didn't have huge record libraries between us.&lt;/p&gt; &lt;p&gt;Anyway, my mate spent most of the time hooking up with his girlfriend in a back room, and so I would be alone doing the show almost every Saturday night - the 10pm - 6am shift.&lt;/p&gt; &lt;p&gt;This was between High School and University, so I wasn't too worried, it was a fairly good run, had a lot of fun playing tracks... and we'd hang out, smoke, get some phone calls from local pubs and the golf club and stuff like that.&lt;/p&gt; &lt;p&gt;We got a bit of a following, some of the local teens would start listening to us because we were playing a lot of different stuff that they'd listen to... and occasionally, as we knew not a whole lotta folk listened, we'd play anything - swearing, prank call cds, whatever.&amp;nbsp; Even guys from our school would call in with no real idea who we were.&lt;/p&gt; &lt;p&gt;Anyway, one night I got a phone call after I was having a pretty good night, two hours in, from one of the guys on the show before us - I had left the master volume all the way down and had been broadcasting empty air the whole night.&lt;/p&gt; &lt;p&gt;Yeah... that night was pretty embarrassing - but I kind of miss hanging out like that, chilling with the boys, rockin out.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=BEuShrgQAqg:uUC6Q3BRGFQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=BEuShrgQAqg:uUC6Q3BRGFQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/BEuShrgQAqg" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/i-have-something-in-common-with-a-republican-presidential-candidate/</feedburner:origLink></item><item><title>Gotta do it more than once? Script it!</title><link>http://feedproxy.google.com/~r/crucibleau/~3/zOJU2Lz6Ezk/</link><pubDate>Thu, 13 Dec 2007 03:33:58 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/gotta-do-it-more-than-once-script-it/</guid><dc:creator>Andrew Tobin</dc:creator><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;Yesterday I spent quite a bit of time scripting up in SQL and into a stored proc some code that I tend to rewrite a bit.&amp;nbsp; What it does is shifts a lot of product from one order to another, or back into stock.&lt;/p&gt; &lt;p&gt;This was something that probably should have been in the system from the start, but somehow had been avoided for a long, long time.&lt;/p&gt; &lt;p&gt;Anyway, over the past year I was asked to move stock now and then, but my grumblings usually made them avoid the need :)&lt;/p&gt; &lt;p&gt;It had started to get more and more common again though, and I had a script on hand, but then rebuilt my pc forgetting one directory - the SQL Projects directory that contained my helper scripts!&lt;/p&gt; &lt;p&gt;Well, that convinced me and given the other day I had to redo it all over again, I made sure I turned it into a stored proc and saved it, and then added it to the application.&lt;/p&gt; &lt;p&gt;And one day later? They had to use it 4 times, possibly saving me a good hour of shifting things and making sure they went through okay.&lt;/p&gt; &lt;p&gt;And that was a saving of half a day that used to occur before I scripted it in the first place (they used to move things row by row, or copy and paste data between tables *shudders*).&lt;/p&gt; &lt;p&gt;Anyway, I just heard from the users that they used the new screen and it was all done in 5 minutes - no relying on me being around and doing it for them, and I can go on holidays at the end of the month without that manual procedure bothering me!&lt;/p&gt; &lt;p&gt;If you have to do it more than once, you really need to see if you can script it out of your way!&lt;/p&gt; &lt;p&gt;NB: I'm a firm believer in the fact that I should be working on the system, not in the system, so I aint doing your job for you Mr Co-Worker! ;)&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=zOJU2Lz6Ezk:vCnrzzCyKL4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=zOJU2Lz6Ezk:vCnrzzCyKL4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/zOJU2Lz6Ezk" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/gotta-do-it-more-than-once-script-it/</feedburner:origLink></item><item><title>Always Happy to Help!</title><link>http://feedproxy.google.com/~r/crucibleau/~3/8NQYi-2vgnQ/</link><pubDate>Thu, 13 Dec 2007 03:25:29 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/always-happy-to-help/</guid><dc:creator>Andrew Tobin</dc:creator><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;So earlier this week I had my first contact via Live Messenger from my blog (you can contact me via my bio page!).&lt;/p&gt; &lt;p&gt;Basically a guy wanted some help extending Graffiti, and wanted some advice.&lt;/p&gt; &lt;p&gt;The most I could do in this instance was point him back to the graffiti-beta mail address at Telligent, but if anyone does want some help or someone to help test a widget or plugin or anything just give me a yell.&lt;/p&gt; &lt;p&gt;Basically, I think the story with Graffiti CMS is that you'll be able to provide some small plugins that work site-wide but items to work on one page would be more difficult.&lt;/p&gt; &lt;p&gt;One way to do it would be to make a Chalk app that does a test on the post url and only renders for one url.&lt;/p&gt; &lt;p&gt;As far as building a full application - well I think Graffiti is probably a good launch point, or a good blog/documentation interface.. but I don't think there's a story to use it as a framework to develop your app into it like there was with Community Server.&lt;/p&gt; &lt;p&gt;Any of the Telligent guys who wants to talk about that, we're happy to listen, but I think that's basically the point at which you may want to get onboard a larger framework like CS, plus there's the forums and all the other features built in, plus &lt;a href="http://dbvt.com/"&gt;Dave Burke&lt;/a&gt; out there who provides excellent tutorials on how to build on top of it!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=8NQYi-2vgnQ:sWp7dtCLT6w:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=8NQYi-2vgnQ:sWp7dtCLT6w:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/8NQYi-2vgnQ" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/always-happy-to-help/</feedburner:origLink></item><item><title>Technorati Trackbacks and Graffiti CMS</title><link>http://feedproxy.google.com/~r/crucibleau/~3/jvWkfgvoedo/</link><pubDate>Fri, 07 Dec 2007 11:25:56 GMT</pubDate><guid isPermaLink="false">http://grrargh.com/blog/technorati-trackbacks-and-graffiti-cms/</guid><dc:creator>Andrew Tobin</dc:creator><category domain="http://grrargh.com/blog/">Blog</category><description>&lt;p&gt;I think I'm getting a little addicted to playing with Graffiti's Chalk system.&amp;nbsp; Well, not really, but I wanted another go, so I decided to do something else that I thought Graffiti was missing.&lt;/p&gt; &lt;p&gt;A while ago @ScottW asked the question &lt;a href="http://simpable.com/technology/trackback-spam/"&gt;Are Trackbacks (still) Worth It?&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Well I think they are to some degree - but at the same point in time you don't want to go wading through your comments or spam for trackbacks.&amp;nbsp; Luckily Technorati will keep track of your trackbacks for you!&lt;/p&gt; &lt;p&gt;So here's a little Chalk plug-in to link to your blogs Technorati page.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Step 1: Add the plug-in file to your ~/bin/ directory&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a title="http://grrargh.com/files/media/file/AndrewTobin.Graffiti.TechnoratiPlugin.dll" href="http://grrargh.com/files/media/file/AndrewTobin.Graffiti.TechnoratiPlugin.dll"&gt;http://grrargh.com/files/media/file/AndrewTobin.Graffiti.TechnoratiPlugin.dll&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Step 2: Alter your index.view theme file in your ~/files/themes/&amp;lt;THEME&amp;gt; directory&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Find your comment line:&lt;/p&gt; &lt;p&gt;Graffiti:&amp;nbsp; $macros.CommentUrl($post, "%{anchor='comments', class='comments'}")&lt;br&gt;Disqus: $disqus.CommentsCount("&amp;lt;DISQUSFORUM&amp;gt;", $post)&lt;/p&gt; &lt;p&gt;After it place the following spacer if necessary to match the space between your "Read More" link and comments: &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; &lt;/p&gt; &lt;p&gt;Then place a Technorati link:&amp;nbsp; $technorati.Link($post, "", " Trackbacks")&lt;/p&gt; &lt;p&gt;What the three parameters are:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;$post - required to tell it which post to get the url from.&lt;/li&gt; &lt;li&gt;Text to the left of the link.&lt;/li&gt; &lt;li&gt;Text to the right of the link.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Obviously the text to either side isn't required and only there to match whatever you may want inside the link.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Step 3: Alter your post.view theme file in your ~/files/themes/&amp;lt;THEME&amp;gt; directory&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Find your comment line:&lt;/p&gt; &lt;p&gt;Graffiti:&amp;nbsp; $macros.CommentUrl($post, "%{anchor='comments', class='comments'}")&lt;br&gt;Disqus: Is blank if you followed my instructions.&lt;/p&gt; &lt;p&gt;After it place the following spacer if necessary to match the space between your "Read More" link and comments: &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; &lt;/p&gt; &lt;p&gt;Then place a Technorati link:&amp;nbsp; $technorati.Link($post, "", " Trackbacks")&lt;/p&gt; &lt;p&gt;And that'll do it, instant trackbacks that you don't really have to maintain to see who is linking to your site!&lt;/p&gt; &lt;p&gt;Any questions or things you'd like to see different, please just leave a comment!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/crucibleau?a=jvWkfgvoedo:q9EF6Ew5N-M:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/crucibleau?i=jvWkfgvoedo:q9EF6Ew5N-M:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/crucibleau/~4/jvWkfgvoedo" height="1" width="1"/&gt;</description><feedburner:origLink>http://grrargh.com/blog/technorati-trackbacks-and-graffiti-cms/</feedburner:origLink></item></channel></rss>
