0

Three aspects of software projects

by klh 29. november 2009 03:09

The way I see it there are three aspects of a software projects that are worth noting, (or at least that I will focus on in this blog post):

1. The technical aspect

2. The process aspect

3. The meta techincal aspect

The technical aspect are all the aspects that every developer (hopefully) knows, like the programming language, the framework, the application servers etc.

The process aspect is the stuff like scrum, kanban ,lean etc.

The meta technical stuff is what I’ll zoom in on now.

First of all I’m not sure this it the best term, and probably someone has coined a better one…

However the way I see it these three aspects has to be in place for a project to suceed. The first two are usually in place, the first handled by the developer and the second by the project manager or scrum master or someone in similar roles.

However I see the last aspect often being neglected.

The meta technical aspect is about the framework of doing the technical stuff. so I would say it is for instance:

-TDD (BDD)

- SOLID

- IOC

So I would describe it as all the technical stuff that many hardcore developers do not care that much about, but that makes the quality of the code higher, and makes the code more maintainable.

The problem is that many people going into software development care about technical stuff, and care about breaking that small technical problem. But they don’t find the meta technical stuff as interesting.

Tags:

C# | generelt | TDD

0

Khebbie build notifier

by klh 18. oktober 2009 08:04

I created a tool that I use at work for watching my solution, and running the unit tests. It is very much inspired by a tool that I saw for ruby on rails, and can't remember the name of.

The tool is created in boo, and this is my first encounter with boo so probably the code is very C#'ish.

It definetly isn't "Clean code".

With all of this set aside, let me introduce "khebbie build notifier", it's not packaged nicely or anything, so you have to install sharpdevelop in order to use it. 

You also need to install Growl for windows, since this is whats used for notification.

Then you need to have your tests organized so that the tests reside in assemblies called xyx.tests.dll (where xyz.dll is the dll you are testing).

Then install SharpDevelop

Change the source code of khebbie build notifier so that it points to your installation of NUnit (yes it only runs NUnit tests)

Change the source of code khebbie build notifier so that i points to where your source reside

This should all be moved to configuration... someday 

Start khebbie build notifier and whenever you compile a dll or its corresponding test dll, the tests will run. 

 

I have changed Growl for windows so that failures are displayed in red and success are displayed in green.

Growl can not break a long assembly name, but that too will be changed... someday 

Tags:

0

TDD and unit testing is still OK

by klh 9. oktober 2009 13:13

OK there, for a while I was a bit worried about if I should stick with unit testing.

For a while I have been in doubt, for mainly two reasons:

1. I went to ANUG where Martin Olesen presented on BDD and stated that he didn’t always do TDD.

2. Ayende presented on JAOO Danish .Net User Group and stated that he only do unit testing in very few places in NHProf and used TDD even fewer places.

 

This all made me think about TDD and Unit testing, since two really smart guys felt this way about unit testing.

However aften some thought and scrum master training with Jeff Sutherland, where he stated: “All the best teams I see are running XP inside scrum”, meaning the best teams also practice TDD, I now conclude TDD is still OK! - Phew :-)

But OK now why do the two afore-mentioned smart guys not use unit testing intensively?

Well first and foremost these two guys are not new with software development, and since TDD is a design technique, they might not need it.

Ayende actually stated that he still did TDD on the hard parts (as I understand it, where he finds design hard).

Secondly Ayende presented on how he made implementing a feature in NHProf really simple, actuallly so simple it was not designed. And he stille tested it – using integration tests.

Thirdly Martin Olesen stated that his team was still not good enough to drop TDD, he would like to, but it was not possible.

So TDD is still OK!

Tags:

C# | TDD

0

Just did the string calculator kata

by klh 8. oktober 2009 13:55
I just did the string calculator kata, here is the output
 
[TestFixture]
    public class CalculatorTests
    {
        readonly Calculator _calc = new Calculator();
        [Test]
        public void Add_WhenGiven1_ShouldReturn1()
        {
            int result = _calc.Add("1");
            Assert.That(result, Is.EqualTo(1));
        }

        [Test]
        public void Add_WhenGiven15_ShouldReturn15()
        {
            int result = _calc.Add("15");
            Assert.That(result, Is.EqualTo(15));
        }

        [Test]
        public void Add_WhenGiven1comma5_ShouldReturn6()
        {
            int result = _calc.Add("1,5");
            Assert.That(result, Is.EqualTo(6));
        }

        [Test]
        public void Add_WhenGiven115comma23_ShouldReturn138()
        {
            int result = _calc.Add("115,23");
            Assert.That(result, Is.EqualTo(138));
        }

        [Test]
        public void Add_WhenGivenAlphaCharacter_ShouldThrowArgumentException()
        {
            Assert.Throws<ArgumentException>(() => _calc.Add("jens"));
        }

        [Test]
        public void Add_WhenGivenAlphaNumericCharacterWithNumericAtTheEnd_ShouldThrowArgumentException()
        {
            Assert.Throws<ArgumentException>(() => _calc.Add("jens1"));
        }

        [Test]
        public void Add_WhenGivenAlphaNumericCharacterWithNumericAtTheBeginning_ShouldThrowArgumentException()
        {
            Assert.Throws<ArgumentException>(() => _calc.Add("1jens"));
        }
    }

 

 

public class Calculator
    {
        public int Add(string s)
        {
            if(!Regex.IsMatch(s, @"^\d+(,\d+)?$"))
                throw new ArgumentException("s");

            var numbers = s.Split(',');
            int returnValue = 0;
            foreach (var number in numbers)
            {
                returnValue += int.Parse(number);
            }
            return returnValue;
        }
    }

Tags:

C# | generelt

0

Firefox add-ins I could not live without

by klh 22. juni 2009 08:33

Here is a list of firefox add-ins I use every day:

The most important is LOL:

https://addons.mozilla.org/en-US/firefox/addon/1341

This extension has a really bad name, but it’s very good. What it does is when you hit space it puts a number on each visible link on the page – if you hit that number the link is pressed – MouseFree computing here I come!

It is the predecessor to Hit-a-hint, and when googling for lol I always enter hit a hint in order to find it.

Google toolbar for Firefox

http://www.google.com/tools/firefox/toolbar/FT5/intl/da/index.html

Goes without saying, if you use gmail and other google tools, this is an essential.

Ubiquity

http://labs.mozilla.com/2008/08/introducing-ubiquity/

This is a nice concept, that I am trying to implement in my every day use of firefox, it is a tool for doing normal day tasks, like finding a map, or sending an email, with very few keystrokes – go check it out.

Personal Menu

https://addons.mozilla.org/en-US/firefox/addon/3895

Removes the menu bar and gives you three buttons next to the search box, gives you more screen space.

Twitterfox (OK, I can actually live without this one, but it’s good)

http://twitterfox.net/

Twitter embedded into firefox, works very well…

I must say that I do prefer tweetdeck, but twitterfox is good.

 

Edit:

Rasmus Kromann-Larsen pointed out Download statusbar to me.

https://addons.mozilla.org/da/firefox/addon/26

I don’t have much experience with it, but it seems neat. What it does is it lets you get rid of the download dialog, which in my opinion, is always in the way.

Tags:

0

Mail now working

by klh 25. maj 2009 12:46

Somebody told me that the contact form on this blog was not working, well it's working now.

If you tried to get in touch with me through the contact form in the past I did not ignore you - I simply did not receive your message.

So please try again...

Tags:

0

[DK]Misforstået loyalitet

by klh 17. maj 2009 03:53

Jeg husker engang jeg hørte en kollega tale om det at gå på arbejde selvom man er syg.

Indtil da havde jeg altid tænkt på det at gå på arbejde selvom man er syg som at man viste loyalitet overfor sin arbejdsgiver. Men faktisk er det misforstået loyalitet, da man foregiver at være på arbejde og yde en indsats, men faktisk ikke yder som man burde – samtidig kan man risikere at smitte sine kolleger.

På samme måde oplever jeg folk, der ikke mener de har tid til at følge med i teknologi trends indenfor softwareudvikling i deres daglige arbejde, og folk der ikke mener de har tid til at prøve en lille ting af de har overvejet.

Det er på samme måde misforstået loylalitet, da man på den korte bane leverer en lille bitte smule mere, men på den lange bane bliver man en knap så attraktiv arbejdskraft, og kan levere software af knap så høj kvalitet teknisk og strukturelt, som hvis man fulgte med…

Samtidig bør arbejdsgiverer give rum til at deres vidensmedarbejdere udvikler sig fagligt – også i dagligdagen.

Tags:

0

My (Non-thread safe) wrapper for Castle Windsor IoC

by klh 24. marts 2009 03:58

I have a small wrapper API that I use around Castle Windsor, and thought I would share it. You could probably use it to wrap an IoC of your own choice.

First please note that this library is not checked for thread safety, secondly there is nothing original in what I do, it’s just my take on what’s already been done.

Here is how I configure the IoC container:

private static void SetupIOC() { Bind<HTTPClientWithBasicAuth>.To<IHTTPClient>(); Bind<TwitterClient>.ToAbstraction<ITwitterClient>(); }

Here is how I resolve an object:

ITwitterClient twitterClient = ResolveType.Of<ITwitterClient>();

Here is how you bind an instance to an interface or class:

Bind<UsernamePassword>.ToInstance(new UsernamePassword(args[0], args[1]));

 

Here is the class I use to resolve an object. This code is tightly coupled to the Windsor container, and for my pet project it is fine, but you might want to couple loosely to the container.

public static class ResolveType
{
private static readonly IWindsorContainer _container;
static ResolveType()
{
_container = new WindsorContainer();
}
public static T Of<T>() where T : class
{
if (typeof (T).Equals(typeof (IWindsorContainer)))
{
return new WindsorContainer() as T;
}
return _container.Resolve<T>();
}
internal static void AddComponent(string key, Type serviceType, Type classType)
{
_container.AddComponent(key, serviceType, classType);
}
internal static void AddComponentInstance<T>(object instance)
{
_container.Kernel.AddComponentInstance<T>(instance);
}
}

The two AddInstance methods are internal since the Bind class lives in the same assembly.

Here is how i configure the IoC container:

 

public class Bind<T>
{
public static void ToAbstraction<S>()
{
ResolveType.AddComponent(typeof (S).ToString(), typeof (S),
typeof (T));
}
public static void ToInstance(object instance)
{
ResolveType.AddComponentInstance<T>(instance);
}
}
You can find a small solution using this here 

Edit:

Renamed Bind.To to Bind.ToAbstraction, but not in the downloadable solution.

Tags:

C# | IoC

1

[DK] om aspergers

by klh 22. marts 2009 12:08

Jeg har en søn med aspergers syndrom og en af de ting man tit møder er det at folk ikke opdager at han har et handicap.

Udtalelser som "Han fejler da ikke noget" er ret normale at støde ind i, og de sårer, da det jo samtidig siger at de problemer og udfordringer man som forældre til et barn med aspergers har, ikke er reelle - de bliver ikke anerkendt.

Så det folk tit vel-ment udtaler ligesom for at trøste kan i virkeligheden virke sårende.

Aspergers er det man kalder et usynligt handicap, hvor man ikke ved bare lige at møde folk med handicappet kan gennemskue at man står overfor en handicappet person.

Jeg har klippet et citat fra en pdf om hvad aspergers egentlig er:

 Anita Hummelshøj:
“Det, værste jeg ved, er folk, som siger: “du fejler jo ikke noget. Du ser da helt normal ud.
Du får jo nogle gode karakterer. Der er nok slet ikke noget galt med dig. Du er blot
påvirket af de oplevelser, du er  blevet udsat for gennem din barn- og ungdom. Og det kan
man da godt blive ‘lidt anderledes’ af. Hvis du ellers kan slippe ud af den bås, som de
såkaldte eksperter har placeret dig i... Det kan du sagtens lære dig. Du skal bare øve dig!”
   Det er meget hårdt at tvinges til at argumentere for, at jeg er Asperger! Man forsøger da
ikke tilsvarende at lokke sukkersyge børn med slik: “Du vokser nok fra det”, at skælde ud
på ordblinde: “du skal blot have opmærksomhed”? at fortælle ordblinde, at det blot er
indbildning: “du skal bare tage dig sammen”? at bilde døve ind, at “det hjælper med b-
vitaminer”? at sige til en epileptiker: “Det er dine forældres skyld”?

Taget fra http://asperger-holstebro.dk/?download=Froejk_hvad-er-aspergers.pdf 

Tags:

0

Doing Roman Number converter kata using Bellwares SpecUnit

by klh 17. marts 2009 03:53

I was reading Scott Bellwares article on Behavior-Driven Development, and was inspired to try out his framework called specunit-net"

So I took a kata from tddproblems and tried it out, I took the Roman number conversion problem:

So first I implemented a simple spec base class:

[TestFixture]
    [Concern("base test")]
    public abstract class behaves_like_context_with_Converter : ContextSpecification
    {
        protected RomanNumberConverter _converter;

        protected override void Context()
        {
            _converter = new RomanNumberConverter();
        }

        protected void ShouldReturn(string romanNumber, int integerNumber)
        {
            int result;
            result = _converter.Convert(romanNumber);
            result.ShouldEqual(integerNumber);
        }
    }

 

Then I added specs for one char at a time, I started with I (one) and moved up, but reSharper re-structures this stuff:

[Concern("passed only one character")]
    public class when_passed_one_character : behaves_like_context_with_Converter
    {
        [Observation]
        [Test]
        public void should_return_fifty()
        {
            ShouldReturn("L", 50);
        }

        [Observation]
        [Test]
        public void should_return_five()
        {
            ShouldReturn("V", 5);
        }

        [Observation]
        [Test]
        public void should_return_five_hundred()
        {
            ShouldReturn("D", 500);
        }

        [Observation]
        [Test]
        public void should_return_one()
        {
            ShouldReturn("I", 1);
        }

        [Observation]
        [Test]
        public void should_return_one_hundred()
        {
            ShouldReturn("C", 100);
        }

        [Observation]
        [Test]
        public void should_return_one_thousand()
        {
            ShouldReturn("M", 1000);
        }

        [Observation]
        [Test]
        public void should_return_ten()
        {
            ShouldReturn("X", 10);
        }
    }

So I started with the simplest implementation to make it work (unfortunately I didn’t save all the intermediate states so I can only show the end result), and followed that pragma all the way through, only implementing the simplest possible code to make it work.

Here is the end result, I cannot say that it is perfect, but i behaves like the spec says it should:

public class RomanNumberConverter
    {
        public int Convert(string s)
        {
            s = s.Trim();
            int result = 0;
            for (int position = 0; position < s.Length; position++)
            {
                if (position > 0 && !IsPreviousCharSmallerThanOrEqualToCurrent(s, position))
                {
                    result += ConvertOneCharacter(s[position]) - ConvertOneCharacter(s[position - 1]);
                    result -= ConvertOneCharacter(s[position - 1]);
                }
                else
                    result += ConvertOneCharacter(s[position]);
            }   
            return result;
        }

        private bool IsPreviousCharSmallerThanOrEqualToCurrent(string s, int position)
        {
            char previous = s[position - 1];
            char current = s[position];
            if (ConvertOneCharacter(previous) >= ConvertOneCharacter(current))
                return true;
            return false;
        }

        public int ConvertOneCharacter(char s)
        {
            Dictionary<char, int> romanValues = new Dictionary<char, int>
                                                    {
                                                        {'I', 1},
                                                        {'V', 5},
                                                        {'X', 10},
                                                        {'L', 50},
                                                        {'C', 100},
                                                        {'D', 500},
                                                        {'M', 1000}
                                                    };
            if (romanValues.ContainsKey(s))
            {
                return romanValues[s];
            }
            throw new ArgumentException(s + " is not a roman number");
        }
    }

At the bottom you find all the rest of the specs.

 

 

 [Concern("passed only two simple characters")]
    public class when_passed_two_simple_character : behaves_like_context_with_Converter
    {
        [Observation]
        [Test]
        public void should_return_II()
        {
            ShouldReturn("II", 2);
        }

        [Observation]
        [Test]
        public void should_return_XV()
        {
            ShouldReturn("XV", 15);
        }
    }

    [Concern("passed only three simple characters")]
    public class when_passed_three_simple_character : behaves_like_context_with_Converter
    {
        [Observation]
        [Test]
        public void should_return_XVI()
        {
            ShouldReturn("XVI", 16);
        }
    }

    [Concern("passed only values below ten")]
    public class when_passed_values_below_ten : behaves_like_context_with_Converter
    {
        [Observation]
        [Test]
        public void should_return_IV()
        {
            ShouldReturn("IV", 4);
        }

        [Observation]
        [Test]
        public void should_return_IX()
        {
            ShouldReturn("IX", 9);
        }


        [Observation]
        [Test]
        public void should_return_VI()
        {
            ShouldReturn("VI", 6);
        }

        [Observation]
        [Test]
        public void should_return_VIII()
        {
            ShouldReturn("VIII", 8);
        }
    }

    [Concern("passed only one characterwhen passed spaces")]
    public class when_passed_spaces : behaves_like_context_with_Converter
    {
        [Observation]
        [Test]
        public void should_return_trim()
        {
            ShouldReturn("II ", 2);
        }
    }

    [Concern("when passed invalid character")]
    public class when_passed_invalid_character : behaves_like_context_with_Converter
    {
        [Observation]
        [Test]
        [ExpectedException(typeof (ArgumentException))]
        public void should_throw()
        {
            _converter.Convert("P");
        }
    }

    [Concern("when passed large numbers")]
    public class when_passed_large_numbers : behaves_like_context_with_Converter
    {
        [Observation]
        [Test]
        public void should_return_1900()
        {
            ShouldReturn("MCM ", 1900);
        }

        [Observation]
        [Test]
        public void should_return_1974()
        {
            ShouldReturn("MCMLXXIV", 1974);
        }

        [Observation]
        [Test]
        public void should_return_1998()
        {
            ShouldReturn("MCMXCVIII", 1998);
        }

        [Observation]
        [Test]
        public void should_return_2008()
        {
            ShouldReturn("MMVIII", 2008);
        }
    }

Tags:

Powered by BlogEngine.NET 1.4.5.0
Original Design by Laptop Geek, Adapted by onesoft