Agile Software Development

2009 Retrospective

Monday, 18 January 2010

Posted by Sébastien Lachance with Comments (0)

2009 has been a big year. A lot happened. Professionally and in my life in general.

What went well

Reading other books than technical books

I have been reading a lot of books that had nothing to do with the technical aspect of my job, but with other challenges in mind. I’ve read about business development, learning process, design (not software design) and project management. I’ve also came in contact with the Pragmatic Thinking and Learning book which gave me a lot of great tools to learn more effectively.

Agile

I’ve been working with an Agile Team for half a year now, going back where I really belong. I liked the experience and hope we (the team) can get even more benefits from this methodology this year. I’ve also assisted to some of the conferences of the Agile Tour 2009 which was a fantastic event.

Web Development and Javascript

I’ve always been a developer with a little knowledge of web design but no deep knowledge. I’ve always had design supplied to me and been able to hack through it and get thing done. This year, I’ve gone deeply in web design and CSS, so deeply that I now really hate browsers differences :). And I’m now an expert in Javascript, thanks to jQuery. Seriously, I made really big improvement on this side.

SEO

Search Engine Optimization that his. I was expected to increase visitors from the US on a website. I’ve started with no real knowledge on how Google was indexing content. So I geared myself, watched videos and read everything I could for this. It’s not always easy but it was a fun learning experience. One tool worth mentioning is the IIS SEO toolkit. The first analysis with this extensions showed me that I had a lot of problems with missing descriptions, keywords, titles, broken links, etc, on my blog, and it provided a great experience in allowing me to resolve them and understand what I did wrong.

Wedding

I’m now married. Since October 17. What an intense ride it was. And we are now waiting for our first child to be born (due February 2010).

Consulting

I’ve done some consulting work at the beginning of the year and it was really fun. Delivered on time and exactly what they wanted. Great experience. Great customer.

What could have been better

Lack of time to post on my blog and the migration to BlogEngine.

I have missed a lot of opportunity to blog and I intend to get back on track this year. I also migrated my blog from Wordpress to BlogEngine.Net this summer and seen a drop of more than 50% in traffic. I blame myself for my lack of migration strategy.

Technical Reading

I read some technical books in 2009, but not as many as the other years. In fact, aside from Clean Code, CSS Web Design and ASP.NET MVC in action, I had read no other technical book.

A contract

A situation has occurred in which I was unable to deliver a project on time. Some deadline were too thigh and a last minute change (technology switch at the last minute) made the situation goes havoc and the project was abandoned (by me).

Skullcandy headphones

I had a pair of Skullcandy headphones that broke unexpectedly. But due to the formidable warranty (complete replacement or half-price on another pair), I had sent them to be replaced in October. I’m still waiting and all my attempt to contact them has failed. The problem is that I would have been able to repair them myself and now I’ve just lost them.
Update 1 (January 14, 2010 : It seems the package never arrived…).
Update 2 (January 19, 2010 : Now they found it and the new headphones are being returned to me.
Update 3 (February 11, 2010) : 3 weeks now and still haven't received them (Canada Post is slow or ...).



My opinion about Duct Tape Programmer

Wednesday, 07 October 2009

Posted by Sébastien Lachance with Comments (0)

duct-tape As everyone else, I have been following the discussion about the Duct Tape Programmer post that Joel Spolsky has written. If you haven’t read it yet, go read it and be objective.

 

Simple is better, less is better

I agree with him, really! Not totally, but the essence of what I believe is written there. It’s all about simplicity. I want my code to be simple. If I need to figure out what it’s doing, I will refactor it until I can understand it easily. And I will never consider the use of a framework or another piece of technology if I really don’t need it. Adding things for fun or for learning purpose can be fun, but it’s not the most important aspect of software development.

I just want to stay away from complicated stuff. Simpler is better. Less is better. If there is a way to accomplish a task easily without a grandiose architecture, then I’ll do it.

And don’t forget that the ultimate goal is to ship it!

 

TDD

But, I refuse to let TDD down. I don’t know why everyone else is talking about Joel hatred concerning unit testing (am I to only one not reading his blog religiously?) but I need to put my feet here and give my opinion about TDD in this context. TDD allow me to write simple code. Just what is needed and nothing else. I don’t think it slows me down. I don’t think it gave me a lot more speed on my productivity, but it sure as hell helped me a lot in making things simple. But! Yes It could slow down dramatically a new team that has never done any sort of unit testing. Why not, you need to think a lot more of how you are going  to do things and it’s not easy to get out of the “write and forget about until we test” state of mind.

 

TDD and 100% code coverage

One of the aspect of unit testing that can be a problem is the 100% code coverage mark. Most people are trying to test everything and will put a lot of effort in it. Why should it be important to cover every single line of code. Not everything should be tested. Automatic property in C# should not be tested. Use your judgement.



Moving to an Agile Team

Wednesday, 30 September 2009

Posted by Sébastien Lachance with Comments (0)

Let me start by telling you that I strongly believe in agile software development. Agile for me is about rapid feedback, improvement and a chance for all team members to give their opinions (and a lot more). Far too often I have seen developers only following wishes and desires of their lead programmer and never been asked for their opinions (it’s not a personal experience but this is what I have heard many times). And I don’t think it works.

Recently, I have been assigned to help a team that just got started on the agile path. They want to do it with Scrum and XP. I have not been sent specifically to help them with the agile transition but since I got some experience I think I could be of some help.

The new team has a great willingness to learn and improve themselves and finding a better team and a better project would have been possible for this transition. If there is a team that will successfully make it happen, it’s them. Our Scrum master is using the “Scrum and XP from the Trenches” book written by Henri Kniberg as a reference and so far, it’s working amazingly. I did not had time to read it yet, but I plan to purchase the book as soon as I have some free time (I’m getting married and having a baby).

We are experimenting different things and and seeing by ourselves what works and what is not. So far we already implemented the daily meeting, user stories and an integration server. We also make use of “story point”, but for us, one point is one hour. We also use a burndown chart to track the effort we make (as I said: rapid feedback).

It’s also a learning experience for me. I got to read a lot more and have been asked frequently to give feedback. So I’m not letting myself go with the flow and only live the experience, but I am asked to participate actively. In the past, I have been on an agile team but as a remote worker (and a lot of distraction at the time, read : new house) and did not fully lived the experience. I also tried by myself on a lot of one-person project but, it’s not just the same.

We have configured a build server and now we are trying to write more tests (just me for the moment, since I got “extensive” experience with that (3-4 years, wow time goes fast)).  One thing I would like to apply as soon as possible is the use of TDD or BDD. But this one will be a lot harder to be approved since it’s a considerable overhead when the team have no experience and a lot harder to get started correctly.

Happy to be back on the Agile train.



Why I’m doing unit testing

Wednesday, 23 September 2009

Posted by Sébastien Lachance with Comments (0)

To be honest, I believe that we have reached a point where we can’t allow ourselves to deliver untested software. I lived through a lot of maintenance work and debugging that were so time consuming that It took more time to debug than it took to actually develop. And it’s for that reason that I believe that unit tests are essentials and should belong to every developer toolbox.

Easy to get started

It’s actually not so hard to learn and a lot of resources already exists to get you started rapidly (Roy Osherove and his book are a must).

Unit test and design

I also believe that unit tests have a strong positive impact to the design of the code. Doing correctly, TDD (test-driven-design or test-driven development) is a powerful tool. I’m talking with experience here and it’s very impressive. I worked on two almost identical project and one was driven by test and the other was not. The quality of the design was much much better on the project that was test driven than the other one. But what was way more impressive was the number of changes made to the structure of the project. Code with tests has evolved tremendously and untested code had a static structure that stayed the same over the course of it’s development.

Unit test as a learning tool

And a great one it is. I recently had to create regular expression to find email in some large text file. Instead of rapidly hitting google for a rapid solution, I created a class library, added the nUnit framework and started writing tests. This way, I could test assumptions and learn some aspect of writing regular expressions. I learned a lot.

I can’t believe!

Today, I can’t believe myself when I see a method that contains logical code, and no tests. Tests are so easy to do (when you actually know how to do them) that it’s almost a shame to forget about them.

My answer

And here is my answer to the “we don’t do test because our organization don’t want to” argument : Don’t tell them. You are responsible for the quality of your code and it’s very unprofessional to leave code go in production that you knew would have been much better and feel more confident if it was tested. I believe the advantages outweigh the disadvantages in this particular case.

This is my point of view. 



My TeamCity testimonial

Wednesday, 29 October 2008

Posted by Sébastien Lachance with Comments (0)

Some months ago, someone from Jetbrains asked me if they could use a comment I made on my TeamCity blog post (the one I demonstrate how to get TeamCity up and running) on their testimonials page.

My testimonial. However, I am not working anymore for bxsystems but for a great local company where I currently live. I think there is a lot of potential there.

I still believe TeamCity is an impressive product and I am waiting for version 4 that will be out soon.



Unit Testing, LinqToSql and CreateDatabase

Monday, 27 October 2008

Posted by Sébastien Lachance with Comments (0)

When using LinqToSql and unit testing in your application, you can benefit from two handy method calls that will make your life a lot easier.

var db = new DatabaseDataContext();
db.DeleteDatabase();
db.CreateDatabase();

 

You won't need to worry about putting the database in a correct state before each of your test. I call them in my setup part of each unit tests that make use of the database.

If you need to insert some test data, so I used the ExecuteCommand method to execute a sql script.

db.ExecuteCommand(File.ReadAllText(@"..\..\..\..\db\referencedata.sql"));
 
And if you have more than one test that will use this code at a time, you may need to close the connection after the setup.
 
Putting it all together look like this :
var db = new DatabaseDataContext();
db.DeleteDatabase();
db.CreateDatabase();
db.ExecuteCommand(File.ReadAllText(@"..\..\..\..\db\referencedata.sql"));
db.Connection.Close();

 



Convert a test to Rhino Mocks 3.5 and the number of constraints

Wednesday, 01 October 2008

Posted by Sébastien Lachance with Comments (0)

I decided to convert a test to Rhino Mocks 3.5 to "enhance readability". This test was using constraints to make sure that properties of a supplied object was changed during the execution of the tested method.

Original Code :

var mockery = new MockRepository();
var mockedRequestRepository = mockery.DynamicMock<IRequestRepository>();
var sut = new RequestService(mockedPreviewRequestRepository, null);

Expect.Call(mockedRequestRepository.GetByID(1)).Return(new Request { ID = 1 });
mockedRequestRepository.Update(null);
LastCall.Constraints(Property.Value("RequestState", RequestState.BeingProcessed));

mockery.ReplayAll();

sut.MarkAsBeingProcessed(1);

mockery.VerifyAll();

 

Converted Code (Rhino Mocks 3.5) :

var requestRepository = MockRepository.GenerateMock<IPreviewRequestRepository>();

var sut = new RequestService(requestRepository, null);

requestRepository.Expect(rr => rr.GetByID(1)).Return(new Request {ID = 1});
requestRepository.Expect(rr => rr.Update(null)).IgnoreArguments().Constraints(
    Property.Value("RequestState", RequestState.BeingProcessed), Property.Value("ID", 1));

sut.MarkAsBeingProcessed(1);

requestRepository.VerifyAllExpectations();

 

However, on the converted test, I got this nasty exception :

System.InvalidOperationException: The number of constraints is not the same as the number of the method's parameters!

After playing around with different combinations of constraints I found out that you can supply a predicate to the Is.Matching constraint. So I ended up modifying my constraint a little.

requestRepository.Expect(rr => rr.Update(null)).IgnoreArguments().Constraints(
         Rhino.Mocks.Constraints.Is.Matching(
             (IRequest request) => request.ID == 1 && request.RequestState == RequestState.BeingProcessed));

 

Et voila! Everything works fine. However, I would like to hear how you got to get rid of this message if there is another way.

 



The importance of database versioning

Wednesday, 12 March 2008

Posted by Sébastien Lachance with Comments (0)

2-3 months ago, I have deployed the application I was working on the client. Since then a lot of changes have been made and I did not work on this project. The database changed significantly but the sql script have not been updated with the latest changes. Now, I have to get back on the project to make an update to the client. I can generate a new set of scripts to create a new database, but how am I suppose to update the production database ...

Before I left, I gave instruction on how to version every changes to the database. I wanted to have scripts with every changes that have been made and then run them on the client on future update.

Let's see the pros and cons of not doing so :

PROS :

  • Save time when developing

CONS :

  • No way to easily update an existing database
  • Loose time trying to figure out what is changed
  • No confidence that you will update the existing database correctly
  • No way to get back in time if needed

Please, version your sql script! It will be much easier for those doing the futur work.



Screencast and my opinion about TypeMock

Thursday, 24 January 2008

Posted by Sébastien Lachance with Comments (0)

I have always been told that TypeMock was too powerful, not strongly typed and for that, It shouldn't be used. I believed that. The problem is : I should have given it a try before taking that for granted.

I have watched the Roy Osherove screencast and was impressed! I am currently working on an existing code base that was done before we went Agile and even before we were doing object-oriented development. When I need to refactor certain features I usually start writing tests and then using dependency injection to be able to mock some object. The minimum to be testable with Rhino Mocks. But with TypeMock you can mock object and don't even need to inject them. You can also make expectation on static methods. Isn't that just great! I believe so.

However, I will stick with Rhino Mocks for now. I like the way It force me to decouple my code and in some sense, it provide me with guidance to make my work testable.

P.S. : This is just my opinion and not the absolute truth.



Setting up a the build file for a new application

Tuesday, 04 December 2007

Posted by Sébastien Lachance with Comments (0)

(Index of the whole series)

This is really easy on a new project! I think that the success on setting up a build file is going a step at a time. Unfortunately this is not always the case in some of our projects due to time constraints.

I am using NAnt for this.

Step 1. Deciding where I wanted to put my build.

Going with some advices I decided to go on the classic build folder. I make sure the folder is deleted and created back at every build.

 

 

<!-- Start by cleaning the build area -->
<target name="clean">
  <delete dir="build" if="${directory::exists('build')}" />
</target>

<!-- Create a build area -->
<target name="init">
  <mkdir dir="build"/>
</target>

Step 2. Compiling the project.

This is where the challenge lies. The csc Nant task is not aware of the .NET 3.5 framework. To get around this problem I have download a nightly build of NAnt 0.86. Works perfectly, until... Remember I'm using WPF for my GUI. I was getting some strange errors about something missing in the System.Window. Full error :

      [csc] Compiling 7 files to 'C:\dev\LogItAll\build\LogItAll.exe'.
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\App.xaml.cs(13,32): error CS0246: The type or namespace name 'Application' could not be found (are you missing a using directive or an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(6,22): error CS0234: The type or namespace name 'Controls' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(7,22): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(8,22): error CS0234: The type or namespace name 'Documents' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(9,22): error CS0234: The type or namespace name 'Input' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(10,22): error CS0234: The type or namespace name 'Media' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(11,22): error CS0234: The type or namespace name 'Media' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(12,22): error CS0234: The type or namespace name 'Navigation' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(13,22): error CS0234: The type or namespace name 'Shapes' does not exist in the namespace 'System.Windows' (are you missing an assembly reference?)
[csc] c:\dev\LogItAll\src\app\LogItAll.UI\Window1.xaml.cs(20,36): error CS0246: The type or namespace name 'Window' could not be found (are you missing ausing directive or an assembly reference?)

Humm, why is there something so obvious that it should be there failing? The reason is that some of the libraries required on a WPF project are not in the GAC. They are located in the C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\. Next, there is the problem that some file are generated and not always there, the InitializeComponent method is missing everywhere.... This is strange, how can I use csc.exe to generate those files? You can't use csc.exe, when you use XAML ! After a lot of googling, I stumbled upon this MSDN page. I had no choice but start using MSBuild for the compilation.

So I changed my csc task to an exec task and called MSBuild. I was now facing the problem that the assembly are compiled and put in their respective folder. A little change to the Output path in Visual Studio 2008 did the trick. Note that I am not using it on all project. I'm only interested in the UI project and all the tests projects. They are all what I need to run the application and the unit test.

outputpath

This is what the NAnt section look like:

 

 

<target name="compile" depends="init">
    <exec
    program="C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe"
    commandline="LogItAll.sln"/>
</target>
3. Executing the tests.

 

 

<target name="test" depends="compile">
  <exec basedir="tools\mbunit\"
    useruntimeengine="true"
    workingdir="build"
    program="mbunit.cons.exe"
    commandline="LogItAll.Domain.Tests.dll /rt:html /rf:"."" />
</target>
I'm still trying to find a more generic way to execute all the test projects. As you can see I am using MBUnit as my unit testing tool for this application.
4. Result

 

 

<?xml version="1.0"?>
<project name="LogItAll" default="all">

  <target name="all"/>

  <!-- Start by cleaning the build area -->
  <target name="clean" description="remove all build products">
    <delete dir="build" if="${directory::exists('build')}" />
  </target>

  <!-- Create a build area -->
  <target name="init" depends="clean">
    <mkdir dir="build"/>
  </target>

  <target name="compile" depends="init">
      <exec
      program="C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild.exe"
      commandline="LogItAll.sln"/>
  </target>

  <target name="test" depends="compile">
    <exec basedir="tools\mbunit\"
      useruntimeengine="true"
      workingdir="build"
      program="mbunit.cons.exe"
      commandline="LogItAll.Domain.Tests.dll /rt:html /rf:"."" />
  </target>

</project>