sfeldman.NET

.NET, code, personal thoughts

March 2009 - Posts

I am amazed. Not everyday you can find a great application that just works the way you expect it to work. Hudson is our teams’ CI engine of choice. We used CruiseControl, but it is no where close to what Hudson is capable.

Features I loved most of all:

  • Ajax updates for the web interface
  • Real time report of the projects statuses
  • Console of the build (see the script execution)
  • Integration with AD
  • Integration with Subversion (providing comments on commits)
  • Recent changes
  • Workspace (ZIPed trunk)
  • Real-time Build Executor Status
  • and much more…

We are less then a month on CI server, and Hudson is only a few days as introduced, but from now on there will be no project outside of it. So what’s the status, doc? Cloudy, but we are getting warmer and sun will eventually shine (a nice visual gimmick for Hudson to report the status :)

image

Posted by Sean Feldman | 7 comment(s)
Filed under:

I know there are lots of good developers in Calgary. I know for sure lots of them feel sort of puzzled if they do things the right way. If you have a chance, get your answers at the course JP is giving in Calgary again – absolutely worth it. As someone who took the course a year ago, I can testify you will not be disappointed, unless code is not what you love to do. Yes, love to do, and not like, since to get through the course you gotta be loving programming. What will this course give you? I think some of the most valuable things a developer can ask for:

- Sanity check: Am I doing the right thing?

- Back to the basic: Technology will come and go, core principles will stay. Do I know what are those?

- Testing is important: Is test only to discover bugs or more than that?

This year JP is changing the way course is done for better (IMO). Sign up and see how deep the rabbit hole goes.

I would like to learn Ruby for .NET (I think it’s out there). But I am also addicted to BDD development style. Can anyone recommend a good book that will teach Ruby through testing?

Today we had a discussion about having strict mocks for all of our dependencies in code. Reason - to force the tests to serve as a safety net for production code. I will try to explain pros  and cons of this approach from the point of view myself is found.

Why not to have strict mocks all over the place?

  • Too much of intimacy with production code - test becomes the production code line by line
  • Painful refactoring - how many times the same code is invoked, etc
  • Behaviour Driven Development becomes impossible (single observation rather than multiple ones) 

Why would one like to have all mocks as strict mocks?

  • Safety net - change in code causes tests to fail right away
  • Simplicity, as opposed to the complexity generated when trying to do BDD with spec based testing

What I am asking, is wouldn't the fact of making all mocks strict cause tests to have more than one responsibility? Rather that to have a single one - test if production code is failing or not, it will also have the responsibility of serving as a security net to prevent developers from starting code from production code and not tests first.

Would it make sense to read

dependency.VerifyAllExpectations();

vs.

dependency.AssertWasToldTo(x => x.SomeBehaviour());

Not sure.

I can definitely see the benefit of forcing strict mocks to force people to get into habit of testing properly, but beyond that, it is a meter of team agreement to adhere to the coding style (tests first). None can ensure that code will go into repository with accompanying tests or tests will necessarily be good. Strict mocks should definitely not be used to pursuit that particular goal.

Share your opinion and experience with our team, feel free to comment.  

Posted by Sean Feldman | with no comments
Filed under:

In my previous post I talked about efficiency of whiteboard with stickies as a tracking tool for a project progress. During last iteration, our PM has suggested to “color code” features with different color stikies. Boy it worked great. Apparently, this is a great way to ease progress reading for a specific feature.

To make it possible, we put the name of the feature with the appropriate color sticky on the top of the whiteboard. The rest – picture will prove it.

06032009110

PS: the bottom left corner represents all known items in Backlog with low priority.

Done-done column is not captured here, it’s a whiteboard (smaller) on it’s own, that is getting slowly filled up with items form “In QA”, when those are accepted, and all associated items with it (from Dev. Complete) are moved.

PSS: The hot pink – these are the bugs, they get attached to the appropriate stickes in order to attract attention and get fixed ASAP (example in column “In Progress”).

Posted by Sean Feldman | 5 comment(s)
Filed under:

Anyone can recommend on good Domain Modeling (not design) books? Thank you.

Posted by Sean Feldman | 2 comment(s)
Filed under:

The current project I am involved in, we are using BDD style of testing, where our specifications (tests) are both designing force and documentation for the implementation. One of the interesting cases we are running into, is when we need to express some complex conditions. For example

When a component is asked to perform some action on some object

- Should do A

- Should do B

Then we add complexity by trying to look into what is going to happen when

- instance of some object is valid

- instance of some object is invalid

So far it’s working nicely, and code looks like this

   1: public class When_component_is_asked_to_perform_some_action_on_some_other_object : Component_Specs
   2: {
   3:     [Observation]
   4:     public void Should_do_A() {}
   5:  
   6:     [Observation]
   7:     public void Should_do_B() {}
   8: }
   9:  
  10: public class And_some_other_object_is_valid : When_component_is_asked_to_perform_some_action_on_some_other_object
  11: {
  12:     [Observation]
  13:     public void Should_happen_something_when_some_object_is_valid() {}
  14:  
  15: }
  16:  
  17: public class And_some_other_object_is_invalid : When_component_is_asked_to_perform_some_action_on_some_other_object
  18: {
  19:     [Observation]
  20:     public void Should_happen_something_else_when_some_object_is_invalid() {}
  21:  
  22: }

The problem started when there were 10 passing tests instead of 6. Well, good that they all were passing, but what’s the catch? Apparently, the When_component_is_asked_to_perform_some_action_on_some_other_object class was running on it’s own, in addition to the AND specifications that included its’ observations by inheritance. Solution was simple, don’t let the testing framework instantiate the base specification.

   1: public abstract class When_component_is_asked_to_perform_some_action_on_some_other_object : Component_Specs
   2: {
   3:     [Observation]
   4:     public void Should_do_A() {}
   5:  
   6:     [Observation]
   7:     public void Should_do_B() {}
   8: }
   9:  
  10: public class And_some_other_object_is_valid : When_component_is_asked_to_perform_some_action_on_some_other_object
  11: {
  12:     [Observation]
  13:     public void Should_happen_something_when_some_object_is_valid() {}
  14:  
  15: }
  16:  
  17: public class And_some_other_object_is_invalid : When_component_is_asked_to_perform_some_action_on_some_other_object
  18: {
  19:     [Observation]
  20:     public void Should_happen_something_else_when_some_object_is_invalid() {}
  21:  
  22: }

Moral: passing tests is important. Having clean and manageable tests is no less important.

Posted by Sean Feldman | with no comments
Filed under:

Today, while Mike Hesse and I were working on one of the tasks, we had to implement logging capabilities. Log4Net was the component we abstracted and used to achieve the result. Though logger our code could not know ahead what class would use it, so this is what we put in place:

   1: public class Logger : ILogger
   2: {
   3:   private readonly Type logInvokerType;
   4:  
   5:   public Logger(Type logInvokerType)
   6:   {
   7:     this.logInvokerType = logInvokerType;
   8:   }
   9:  
  10:   public void LogError(string message)
  11:   {
  12:     var logger = LogManager.GetLogger(logInvokerType);
  13:     logger.Error(message);
  14:   }
  15: }

Yes, constructor is the one that receives the type of the invoker. We are still able to resolve logger from container despite this (this is not an issue in our case).

The issue we started to look into was performance. Normally, sample code for Log4Net would have logger instance as static. Our thoughts were, well, it’s probably ‘expensive’ to instantiate logger each time we want to log an error. But we don’t know the invoker until we have the instance of the logger constructed. Chicken or egg? But then we stepped back, and thought – in the current system this error logging will be happening rarely, so why we are concerned about “premature optimization”? Pragmatic decision was – roll it out the way it is, and if we run into issues, refactor.

Thank you Mike for keeping me on the ground.

Posted by Sean Feldman | 2 comment(s)
Filed under:
More Posts