msdeploy - more than I thought

I have been using msdeploy for years for automating ASP.NET deployments, I always knew it was a clever/cool tool, but I really had no idea of the depth!

I had a bit of an issue very recently whereby I needed to get structure and data from a SQL CE SDF database file (don't ask!!). I thought this was going to burn a morning - obviously my Google fu kicked in and I found a useful article on migrating between database formats. This pointed me to using msdeploy command line, so reading the docs to see what I could do I was surprised to see the depth – just look at al the providers available!

I ended up running a simple command line to extract a full SQL Server DDL/DML script allowing me to create a copy of the database wherever.

msdeploy -verb:sync -source:dbFullSql="Data Source={{ Path to SDF file! }}",sqlCe=true -dest:dbFullSql="{{ Path to output file}}"

Script generated and full SQL DB created in less than five minutes from opening the browser tab!

This is definitely a tool to have in your utility belt…

Problems that can happen - we have always done it that way!

The more businesses and development organisations I work with, the more I see common problem “themes”. In this series of articles I am trying to highlight the problems and show the potential solutions to some of these common symptoms.

When I visit companies to help them with software development I end up asking a lot of questions - often finding myself sounding like an annoying 5 year old child just repeating the word "Why?" in response to every answer! When I get down to responses like "because we have always done it that way" or "that’s' just the way we do it" then I know the way things are being done needs to be reviewed. It's like a smell - if we haven't thought about something we are doing for so long that it becomes second nature, how can we be sure it is still valuable or relevant?

In software development when we are trying to improve something (or to generally be innovative) failures and mistakes are seen as a necessary part of the process of working out what's right. The path to the successful solution is comprised of a series of small mistakes and failures from which we learn, adapting the solution as we go. I often find that development teams neglect applying this practice to the way they build software. If we take to be fact that nobody is perfect, and that things can always be improved - then it's OK to make mistakes and it's OK to get things wrong. What's not OK is to repeat the same mistakes ad infinitum!

I like the metaphor of friction when looking at issues in the development process, friction holding us back and slowing down our delivery vehicle!

Friction can be felt anywhere from the initial idea right through to running in production, and friction may be felt in one part of the process but caused elsewhere. I think it is easiest to spot (and fixing has the greatest gain) in the things we do regularly - like deployment. Teams I have worked with have "got used" to the process of creating builds and deployment taking days. It's obviously never that hard!

No matter how you are building software this is why taking time to "inspect" what we do so that we can make small adjustments toward continuous improvement is so important. Take time to note what you do, how long it takes, what feels productive, what’s frustrating etc. Reflect over this as a team and honestly question and evaluate what you do and how. Don’t be afraid to try and make small changes, measure the effect and adjust as necessary – removing friction makes you faster. Don't just do things "'cos that's what we do" - think and reflect – it *may* still be the right way, but there may be a better way. The world doesn't stand still so nor should we!

Re-factoring unit tests to use automatic mocks

Working as a consultant with lots of different teams helping to promote engineering practices I often hear ‘reasons’ as to why teams and developers don’t or can’t write automated tests. Most developers and teams want to do things that will ultimately make their lives easier, but sometimes hurdles and issues seem too big to overcome, and so they stop trying! One conversation with a particular developer a while back went along the lines of “the tests slow me down”. This intrigued me as personally I find that TDD speeds me up - so I asked a few more questions and paired with him to see his approach. Long story short I found that when building this developer changes his mind and his constructor injected dependencies a lot, and without auto mocking he was changing his mocks and construction more than his code.

Everyone’s approach is different – that’s what makes the world so great right – so when I listened and understood the pain I was able to offer a solution. I think all too often we just say “do this” or “do that” without looking at the reasons people may be struggling…

I will try and demonstrate the change in approach to auto mocking that helped in this case using a massively fictitious (and equally tragic) example.

We have an article service that returns articles based on a string Identifier (presumably to display somewhere). The first test written using NUnit and Moq to read the article looks like so:

1 [Test] 2 public void returns_read_article() 3 { 4 var repository = new Mock<IArticleRepository>(); 5 repository.Setup(r => r.Get(It.IsAny<string>())).Returns(new Article()); 6 7 var service = new ArticleService(repository.Object); 8 9 var article = service.Get(Guid.NewGuid().ToString()); 10 Assert.IsNotNull(article); 11 }

And the simplest ‘production’ code looks like:

1 public class ArticleService 2 { 3 private readonly IArticleRepository _repository; 4 5 public ArticleService(IArticleRepository repository) 6 { 7 _repository = repository; 8 } 9 10 public Article Get(string articleId) 11 { 12 return _repository.Get(articleId); 13 } 14 }

I told you it was a tragic example right!

So the issue this developer had was that whenever he changed his mind and needed to introduce another dependency, all of his tests need to be changed (OK in this case it’s one test, but if you have 20 tests that’s a bit more work). Let’s simulate the change with another tragic example – let’s say we have been asked to change the system to record the popularity of articles – we decide that the easiest way is to change our ArticleService to use another dependency to record the request of read of the article.

Obviously as soon as we add another dependency the test code will need to be change too. So what are our choices – 1. give up 2. Put up with it and re-factor all of the tests 3. try and find a way to focus our use of mocked dependencies. 1 and 2 have already been tried! So lets try 3!

How about we automatically create Moq’s for the service – like when we use a DI container, just injecting Moq’s that we can control. Most test/mocking frameworks already have a capability – they aren’t too tricky to build, but as we are using Moq how about we NuGet install and use AutoMoq.

1 [Test] 2 public void returns_read_article() 3 { 4 AutoMoqer moqer = new AutoMoqer(); 5 moqer.GetMock<IArticleRepository>().Setup(r => r.Get(It.IsAny<string>())).Returns(new Article()); 6 7 var service = moqer.Create<ArticleService>(); 8 9 var article = service.Get(Guid.NewGuid().ToString()); 10 Assert.IsNotNull(article); 11 }

Simple changes – we new up an AutoMoqer tell it to use a Moq with the same Setup for our repository then create our service using the Moqer – tests run green. Now we can add our test for the new feature:

1 [Test] 2 public void records_article_read() 3 { 4 AutoMoqer moqer = new AutoMoqer(); 5 moqer.GetMock<IArticlePopularityManager>().Setup(r => r.RecordRead(It.IsAny<string>())).Verifiable(); 6 7 var service = moqer.Create<ArticleService>(); 8 9 service.Get(Guid.NewGuid().ToString()); 10 moqer.GetMock<IArticlePopularityManager>().Verify(); 11 }

This time we only deal with our new popularity manager (I know tragic!) – obviously the test fails – so we step by step change the implementation until we get green tests and we end up with:

1 public class ArticleService 2 { 3 private readonly IArticleRepository _repository; 4 private readonly IArticlePopularityManager _articlePopularityManager; 5 6 public ArticleService(IArticleRepository repository, 7 IArticlePopularityManager articlePopularityManager) 8 { 9 _repository = repository; 10 _articlePopularityManager = articlePopularityManager; 11 } 12 13 public Article Get(string articleId) 14 { 15 _articlePopularityManager.RecordRead(articleId); 16 return _repository.Get(articleId); 17 } 18 } 19

Our existing test (apart from our re-factor to auto mock) was untouched and still runs green – so we can now amend dependencies to our hearts content only affecting tests relying on those dependencies. So our developer is happy that he can write tests without this issue slowing him down.

Really simple. Before you start thinking this is still a bit kek with all the duplication ‘n stuff – go and have a look at the AutoMoqTestFixture in the AutoMoq.Helpers namespace, then re-factor again!