Agile Base Camp 2012

Past Saturday I was a part of big Ukrainian event Agile Base Camp: From Idea to Product. It's been organized by ScrumGuides, pioneers on Agile in Ukraine and organizers of famous Agilee series of conferences.

The conference named "From Idea to Product" and focused on product development issues. There was 3 stages there: Main, XP, UX. Main is for more or less common topics as budgeting, motivation etc.. XP is practical stage for developers and UX for user experience engineers. The program of conference was really interesting, but I spend all my day on XP stage (no surprise).

There were great speeches by Dmytro Mindra, Sergey Kalinets. Probably most valuable for me were ones by Vitaliy Stakhov and Anatoly Kolesnik, Vitaliy shared Hypermedia concepts of RESTfull systems and that looks very promising. Anatoly did great NoSQL introduction that is very actual at the moment. I also enjoyed Dmitry Efimenko speech about testing in product company. He did it in quite tough style, so crowd was a little shocked and kept silence till the last words. I got some interesting points for myself.

I did a talk about - Continues Delivery / Deployment / Production. This practical field is very interesting to me not only because I'm trying to build a product for that and I want to adapt for all project I work to.


alexander beletsky

I've got very nice feedback and questions after my speech, totally collected 15 donuts (a special cards that listeners give to speaker if they like the speech), so I was quite happy about. If you interested, here is my slides on speaker deck.


I really much enjoyed after party and evening we spent in Work'N'Roll, the co-working office of ScrumGuides. Appreciate organizers for that job and wish you good luck of all next events.

Convention based IoC configuration

What's your favorite IoC container framework? For quite long time I stick to Ninject. First time I read about it in Steve Sanders ASP.NET MVC2 book and it's my favorite container since then. But this blog post does not aim particular IoC framework, rather approach you can use. For code examples I'll still be using Ninject, through.

What's are conventions?

Convention over configuration is very popular trend nowadays. Many frameworks trying to adopt it, including ASP.NET MVC. In short, that means you are relying on some front-know conventions, like names of files, folder or classes and system does something meaningful, based on those conventions. Like, all controllers in ASP.NET MVC should have "Controller" postfix, so the framework is able to find and instantiate it.

Conventions make a developer's life a little easier, you are no longer spending efforts on configuration, instead following some simple rules.

What we have for IoC?

My "Shu" level of IoC containers learning was configuration based. This is something you learn at very beginning. So, in case of Ninject, sooner of later you have huge file with dependencies configuration:

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
 kernel.Bind<ISettingsManager>().To<SettingsManager>();
 kernel.Bind<IDirectoryProvider>().To<DirectoryProvider>().InSingletonScope();
 kernel.Bind<ISetupFactory>().To<SetupFactory>();
 kernel.Bind<ITargetsObjectBuilder>().To<DefaultTargetsObjectBuilder>();
 kernel.Bind<ITargetsBuilder>().To<TargetsBuilder>();
 kernel.Bind<IBounceFactory>().To<BounceFactory>();
 kernel.Bind<ITargetsRetriever>().To<TargetsRetriever>();
 kernel.Bind<IConfigObjectBuilder>().To<ConfigObjectBuilder>();
 kernel.Bind<ILoggerFactory>().To<LoggerFactory>();
 kernel.Bind<IHashService>().To<HashService>();
 kernel.Bind<IAuthentication>().To<Authentication>();
 kernel.Bind<IConfigurationsFactory>().To<ConfigurationsFactory>();
 
 // More, more, more...
}

As more your application grows, as more services, repositories, factories you have. As long RegisterServices method becomes longer, as more you forgot to correct correct it after some new dependency added, so you see YSOD during application run.

But please, put your attention to interface and class names. What we have here - ISettingsManager and SettingsManager; IDirectoryProvider and DirectoryProvider.. ILoggerFactory and LoggerFactory. Do you see pattern here? Exactly, it is ["I" + entity name] for interfaces and [entity name] for implementation.

Here we go for "Ha" level of IoC and apply convention based configuration.

Convention over configuration

Let's take an advance of the fact above and shrink our configuration code. First of all, you need to get great extension for Ninject, called ninject.extensions.conventions.

After the package is installed, the simples Ninject start-up code ever would be:

/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
 kernel.Scan(scanner =>
     {
      scanner.FromCallingAssembly();
      scanner.BindWithDefaultConventions();
     }
  );
}

What it does? It has an abstraction called "scanner". You instruct scanner what to do. In this example, I said - take calling assembly and bind all interfaces to implementation class having Default conventions. The default conventions are ones that I shown above.

That's it, all those lines of code are simply gone away, since we rely on conventions and Ninject is aware how to deal with those conventions. If you added new dependency and followed convention, nothing you should do manually any more.

I have some questions!?

Ok, typically you have something little more complex. I'll try to predict some questions you might have.

I have a lot of assemblies in my application, but want only particular ones to be scanned?

You can easily use only assemblies that matches particular patterns, like:

private static void RegisterServices(IKernel kernel)
{
 kernel.Scan(scanner =>
     {
      scanner.FromAssembliesMatching("Candidate.*");
      scanner.BindWithDefaultConventions();
     }
  );
}

Is it only default conventions I can use?

No, you can specify your own rules. Scanner has BindWith method, that receives IBindingGenerator type. You can implement your own binding generator for custom conventions.

private static void RegisterServices(IKernel kernel)
{
 kernel.Scan(scanner =>
     {
      scanner.FromAssembliesMatching("Candidate.*");
      scanner.BindWith<MyCustomConventionsGenerator>();
     }
  );
}

What if I have several cases of convention violations?

You are still able to bind in exactly same way as before:

private static void RegisterServices(IKernel kernel)
{
 kernel.Scan(scanner =>
     {
      scanner.FromAssembliesMatching("Candidate.*");
      scanner.BindWith<MyCustomConventionsGenerator>();
     }
  );

    // classes that violates conventions
    kernel.Bind<IMyInterface>().To<MyImpl>();
}

What is I have dependencies in different assemblies?

Best thing is to go with Ninject modules. First, correct the scanner:

private static void RegisterServices(IKernel kernel)
{
 kernel.Scan(scanner =>
     {
      scanner.FromAssembliesMatching("Candidate.*");
                        scanner.AutoLoadModules();
      scanner.BindWith<MyCustomConventionsGenerator>();
     }
  );
}

Now, each assembly should include module instance:

namespace Candidate.Core
{
    public class CoreModule : NinjectModule
    {
        public override void Load()
        {
            // place convention-violation classes here
   // Bind&lt;IMyInterface&gt;().To&lt;MyImpl&gt;();
        }
    }
}

Another one good feature of Convention based IoC is - "Config and forget". Once done, use always and forget about manual binding once and for all.

I've heard about this on XP Days 2011 conference, by Mark Seemann. I think it's nice approach.. I adopt it and going to use in my projects.

Pre-announce of Release "Candidate"

For those, who already forgot what the candidate is I'll do a small reminder :). This is an application for Continues Deployment for .NET projects. I started the project at Hackatone that took place in summer 2011, in Kyiv. I liked the results I got there, so I didn't throw it away after the contest, but slowly progressed on that through last several months.


welcome

The goal of application is very simple. Provide you with easy to setup and use tool Continues Deployment. I'm still very confused now with all those terms - Continuous Deployment/Delivery/Production/Release.. but in general it is nothing more as next step of Continues Integration. Rebuild and retest the application and deploy it in case of successful results.


welcome

I'm building that in mind of my own needs, how I see it might work for my projects. My own projects are really simple ones, so the candidate is really simple now. Of cause, I would like to be as general as possible, to cover common needs. I'm pretty much sure it would be rewritten hundred of times to reach the level of mass adoption and I'm looking forward to that.


config

Yesterday, I reached very important milestone of candidate.net. It is now feature completed. I would like to stop on current functionality and show it to you. It would take some time to prepare website and instructions, but please stay tuned for official release of project!


config

By the way, I'm still looking for new name! It turns out that finding the good name, could be even harder than finding process running bugs. I would be really happy if you do such early contribution proposing some nice name. Please do not hesitate and share your ideas just in comments.

Using ASP.NET MVC Validation Mechanism without ASP.NET MVC

I get used to DataAnnotations for model validation very quickly. Indeed, it is great approach. You attribute you model with corresponding attributes, rest is done by framework. It is only ModelState.IsValid, all you have to do before starting working with model.

During implementation of some feature for candidate.net I thought to myself, that I need need exactly same validation for my model class, but out of MVC framework. Namely, for some model class, like Github.cs I just want to know, is it "configured" or not. And configured == valid in my context. Instead of writing custom code with checking all required properties to have some values I wished to do the same as ASP.NET MVC does, through DataAnnotations. It turned out to be possible and really easy.

Basic start

Assume you have such model:

public class SimpleModel
{
 [Required]
 public string SomeProperty { get; set; }
 
 [Range(0,50)]
 public int SomeAnotherProperty { get; set; }
}
    

If your goal is just to get answer "yes or no", you can create such function:

public bool ValidateSimpleModel(SimpleModel validate)
{
 return Validator.TryValidateObject(validate, new ValidationContext(validate, null, null), null);
}
    

Validator is a static class in DataAnnotations namespace. It takes target object, validation context and validation results collection. But due, to it just "tries" to perform validation, most of all parameters could be null.

Use validation results

If you need more specific information, like which field is exactly invalid you need to have ICollection<ValidationResult>

public ICollection<ValidationResult> ValidateSimpleModel(SimpleModel validate)
{
 var validationResults = new List<ValidationResult>();
 Validator.TryValidateObject(validate, new ValidationContext(validate, null, null), validationResults);
 
 return validationResults;
}
    

In case of invalid object it would return non-empy collection of ValidationResult, that would contain all relevant information.

Wrapping up to extension method

Finally, you can create simple extension extension method and apply DataAnnotations validation to any kind of object:

public static class ValidatorExtensions
{
    public static bool TryValidateObject(this object validate)
    {
        return Validator.TryValidateObject(validate, new ValidationContext(validate, null, null), null);
    }
}
    

So, the model could just have IsValid() method, like:

public bool IsValid()
{
 return this.TryValidateObject();
}
    

It works great for such simple task I need to accomplish.

Approval Tests: Locking down an output

We have seen how Approval Tests are useful for locking down some legacy code. You might say, that on practice we are having much more bigger problem, like some code that executes queries against the database. We need somehow to be able to work with that code, without worries of brake it down. Approvals could help here.

The case

Again I just imagine some legacy code that works with DB, it might look something like that:

public class ClassThatOutputsSomething
{
 private static Connection _connection;

 public void MethodThatProduceSomeResults(string parameterOne, int parameterTwo)
 {
  if (!IsConnectionOpened())
  {
   OpenConnection();
  }

  var connection = GetConnection();

  var value = HugeAndScarryLegacyCode.TheUgliesMethodYouMightEverSeen(parameterOne, parameterTwo, 'c');

  var query = string.Format("INSERT INTO TableName (SomeColumn) VALUES ({0})", value);
  connection.ExecuteQuery(query);
 }

    // ...
    

The MethodThatProduceSomeResults takes some arguments, call another method to get value and then store value to database. It will be problematic to tests what exactly is happening there. We might consider approach to check the difference in TableName before code execution and after, but we will go smarter and easier way.

Let's prepare the test for that code.

Tests

The great thing with Approvals is the tests are really elegant. Just 2 steps - DO and VERIFY.

[Test]
public void should_be_able_to_test()
{
 // DO
 var some = new ClassThatOutputsSomething();
 some.MethodThatProduceSomeResults('some_input', 221);

 // VERIFY
 Approvals.Approve(...);
}
    

But you can see, the problem here is that we don't have any return value of that method. Instead, it does something inside and keep that action in secret. We need some how to log all internal activities and than verify that log. Approval.Utilities contains exactly what we need.

[Test]
public void should_be_able_to_test()
{
 // DO
 var output = ApprovalUtilities.SimpleLogger.Logger.LogToStringBuilder();
 new ClassThatOutputsSomething().MethodThatProduceSomeResults('some_input', 221);

 // VERIFY
 Approvals.Approve(output);
}
    

I have just added logger ApprovalUtilities.SimpleLogger.Logger.LogToStringBuilder and do approve against it. But if I run this test I could see that output is just empty. Sure, we need to change MethodThatProduceSomeResults a little.

public class ClassThatOutputsSomething
{
 private static Connection _connection;

 public void MethodThatProduceSomeResults(string parameterOne, int parameterTwo)
 {
        // ...

        connection.ExecuteQuery(query);
        ApprovalUtilities.SimpleLogger.Logger.Event(query);
 }
    

So, in the place where query is being executed, we placed the logger and put exact some query inside it. Now if I run the test I will got application output, that I will approve and use those approved results after.

I'm not limited with only one place I could put logger. On practice, would more that one places to grab the results, as well as more that one argument for MethodThatProduceSomeResults method. By analysis of particular practical case, it is possible to place logger exactly where it's needed, plus prepare best matching inputs. Just for example: after code examination it might happen that parameterOne is ProductId, but parameterTwo is ProductPrice. In my test I could query the database to select all products and prices and call MethodThatProduceSomeResults in loop, to get all potential output. That approved test will give me much confidence during refactoring.

Conclusion

Locking down output is very powerful technique, you can use it for any kind of objects that are "hidden" inside legacy classes, like SQL or console outputs.

On Herding Code episode Llewellyn describes the case of some legacy project he worked on. There was a kind of report generator and it's code was just a big mess. He did copy of production database and put it in "Read-Only" mode. By running the report, he was able to find all places where code was accessing DB, since exception is thrown in that place. Putting in just the same log instructions as I did above, he managed to grab all SQL queries that run for that particular report. Everything were just in one file.

That's the good example of reaching 100% code coverage just with one test.

Retrospective 2011

Last year I failed to create retrospective blog post, so lesson learned and I started a little bit earlier now. Not the 1 day, but 3 days before NY :). Retrospective is a great practice and I hope it give me some value when I'll be reading it next year and laughing on my previous achievements.

I'll try to cover 4 basic directions: Career, Development, Blog, Personal.

Career

I continue to do my job for e-conomic.com. As I said here e-conomic is the most important thing that happened to me in 2010 and keeps it influence on 2011. I'm still a product developer there, but in general situation has been changing radically. First of all, we are now much more bigger team. Both Ukranian and Denmark parts of team are growing and new cool guys join us. Second, we finished up few projects at the beginning of the year and joined very cool adventure that I a little described here. Sure, I have fun and boring, easy and tough, nice and bad days there. But overall impression is still very good. As soon as we'll keep same as we are doing, with same level of passion and team atmosphere - we are on right track.

Besides the e-conomic, there is something else that happened to me this year and had direct impact on career - Kiev ALT.NET. Unfortunately, I did not blog to much about that community just a some mention here. Community is very important to any developer and I'm really happy I found the one. I haven't noticed how I became a speaker, actually. With a few nervous tries on Kiev ALT.NET I've managed to give up to 8 (or so) public speeches this year. It might not be so much, but great achievement for me. The speaking opened new opportunities, especially in meeting new people. But first of all it is a great joy and motivation to learn new things.

With a great atmosphere and enthusiastic people inside Kiev ALT.NET I've launched another project called Kiev Beer && Code. The idea is taken from Seattle Beer && Code community, but it is nothing more as developers gathering for social coding. The community is very young and to be honest I don't put to much efforts on it's promotion, but it a very beginning. I'm very happy with out current Beer && Code team and will be much more happier if new guys are joining.

I became MVB (Most Valuable Blogger) for DZone, that I'm really proud for. It is 2-way value, DZone is using my content.. To me it gives additional traffic. I hope we are still partners for long years.

At the end of the year I tried myself in completely new area - trainings. Thanks to XP Injection training center in Kiev, I've been invited to 2 days training session "TDD in .NET". It appeared so much successful that chief trainer offered me a place in their trainers group. At December 22, I officially joined XP Injection. I'm very excited about that and hope I can do my best there. So far, we've planned some further TDD .NET trainings, but definitely TDD won't be the only one topic I can work in.

Development

I mean, everything that I work on my own: pet projects, self education etc. I don't remember who said that, but I very agree with this statement - "if you don't write code at home, you are not progressing". You have not time to learn at work. Work is the place to perform. You have to have sharp axe, if you came to chop the wood.

My main sharp axe exercise is coding. I try to code as much as I can. For productive coding you have to have some projects. Doesn't matter what exactly, what's important is: you like the idea, you have corresponding technological stack. Technological stack have to correspond the area you want to improve in. My main area's are still: C#, HTML/CSS and JavaScript.

I was reading Pragmatic Programmer this year, with a great advice: "Learn new programming language each year". I formulated Pragmatic Product Developer advice, just for my self: "Release new product each year". Even if you release something at work, release something on your own is completely different feeling. It takes too much effort, it's painful.. But shipment is like drug, you feel very happy as soon you ship.. You fill very bad as you don't ship for a while.

While ago I write small article there I mentioned what's my targets and what I working on. Let's quickly go through it:


  • trackyt.net as I released that late 2010 I did provide a support up the the May of 2011. A lot of new features has been commited there, but still I slowed down the progress much. It has very low traffic, almost 0 active users. I was about to release version 2.0, absolutely different with all good things that I see in GTD. But I have to admit, I failed that.

  • elmah.mvc.controller started out as very simple helper for ASP.NET MVC applications that want to use ELMAH, but with a great surprise to me it appeared so popular, that finally wrapped up in a micro product. Now, it has ~2,000 downloads on NuGet, I've received several pull requests and had a talk about it on Kiev ALT.NET. Even if is so small, I treat that as success.

  • github.commits.widget also a micro product that gathered some attention. That was my attempt of working with github API in javascript and I spend maybe 3 hours to create that code, but I know several sites that using that widget. I had joy of creating that and happy that some people find it useful.

  • githubbadges.com a little application that I wrote to participate 10K competition. Total application zipped content should not exceed 10K. I've haven't won, I haven't got any mentions.. But again it was fun small project. I used some my knowledge of github API and tried to do very tiny JS and CSS code.

  • candidate.net is something I started this summer of hackthone. Since then I completely rewrite it, start to use bounce framework inside and had plans to release it October, but failed. I'm not throwing away this project and going to ship that soon. I have yet-another-huge-refactoring cycle now, but after that I hope that alpha version could be ready middle January.

So, it looks like "I did something".. but really nothing impressive. I try to be a little more focused, not more than 2 projects in parallel + very clear criteria's of success for projects. But in general my criteria's are still simple: actually ship it, learn something new, enjoy the ride.

Blog

Thanks to google analytics it is very simple to have analysis. Just take a look at those figures:


stat

So, I've got 25,341 Unique visitors and 36,560 visits in total. To understand what it means to me, let's take a look last year statistics for same period of time.


stat

In 2010 I got 3,979 Unique visitors. It basically means I improved traffic ~637%. This is actually huge number, I don't expect that next year of cause.. but hope that traffic will be improved more.

OK, what was most popular content this year:

Personal

First of all, I got married. I strongly believe it is for good and for long.

I did several interesting trips, especially to Val Gardena with my friends at the beginning of the year and Japan. Unfortunately, I don't predict anything like that in 2012, so it will be kept for good memories.

I have to admit I lowered my sport activities too much. I almost stopped every morning exercises, kyokushin karate, rollerblading. Doing those very occasionally. This is not good at all and I already feel bad influence of that. So, my next year is to make it more balanced.

It was a great year to me. I wish Merry Christmas and Happy New Year to you, dear reader. I'm really looking forward to create new content you would like, new products you would find useful. Let's gather all good things happened this year and take them for next one.

See you 2012!

XP Days Ukraine 2011

Photos from conference are made by Andrii Matukhno

XP Days is a 3 days event. First 2 days are dedicated for trainings and meet-ups and the last day was for speeches. This time I had 3 roles actually: trainer, speaker and visitor. And that was extremely cool.

.NET TDD class

I've never done any trainer job before, so I was little worried of how it goes. With respect to XP practices we decided to do it in pair with Sergey Kalinets.

Our group consisted of 12 students. After initial introduction I realized - wow, we've got a pretty strong guys here.. Most of group had some real TDD practice before and came to improve the skill and found out new techniques. We had a program for 2 days, which covers the theoretical intros to TDD and practical tips and tricks.

We used String Calculator kata which we used both days to warn up. This is very productive way of learning and improving and all guys in group absolutely loved that. I hope this kata became every morning exercise and would be shared among colleagues and be done together, which is great fun.

We had great tandem, together with Sergey. We know each other from Kiev ALT.NET community, but never worked closely. I was very surprised how similar initial experience of TDD we had, so there was absolutely no problem to collaborate. Sergey is very professional trainer, his confidence and experience ruled among these days, he managed to create the training in consistent way. Very naturally we divided technologies & tools, since Sergey works mostly with Desktop and WCF and I work with Web.

So, it went very fine as for me. Friday evening, when we've closed training I was very happy to receive feedback. I believe everyone liked what we did. If you guys are reading that, I would ask to put small comment to that post (yes, "+1" would be alright :)).

Conference

There was a lot of interesting talks. Unfortunately I had to miss several quality-proved ones by Sergey Kalinets and Dmitriy Pasko, I'm really sure that was great stuff. I liked several speeches the most: one by Mark Seeman about Convetions, that showed me how to write less code relying on conventions.. and lighting talk by Dmitry Mindra on software craftsmanship. It was so great and inspirational! I was touched with case regarding Dmitry's father and his attitude to craft. At the end of speech I was happy to get yellow bracelet in return to my promise to:

  • Love the craft
  • Study and improve knowledge all the time
  • Share the knowledge with people around you

I hope I will do that!


dmitry mindra

My speech was dedicated to Approvals. Even I had some lack of time and did not manage to show final example I believe it worked great. The audience were very interactive and I felt the positive energy in the air.

I had prepared introduction part and code examples that I did just on stage. In my opinion the best way to show something to developers is to write some code, but unfortunately it took a little more time that I expected. Moreover, I received many questions at the very first example, so I had to calm down people a little saying "Guys, please wait.. I haven't even started to show cool things" :)..


alexander beletsky

One nice feature of this conference was that all participant two small card which they could fill with feedback and give to speaker back. I was amazed people very stepping by, saying thank you and giving those cards to me. It turns out that most of audience not familiar with Approvals, so general comment was "Man, I would never heard about that, thanks for sharing it".


good job cards

It was extremely pleasant to receive that feedback thought cards and twitter. I'm truly appreciate each good word I got from you guys. Totally I collected 22 feedback cards and treat it as very good result!

Conclusions

First of all, big kudos for all people who make this event happen: XP Injection, sponsors, speakers and visitors. Conference took place in business center Parus, which was a great idea. It is in a center of the Kyiv and has very suitable infrastructure.

As always, it was great pleasure to meet with people from other cities and countries, getting new contacts. I hope that's not the last XP Days in Ukraine, not the last I'm participating in.

The slides from my speech is shared on SpeakerDeck. Also, I'm happy to help you with Apporvals, so do not hesitate to contact my skype or twitter.

Approval Tests: Locking Down Legacy Code

Suppose, you working on project with a lot of legacy code inside. I know it makes you sick, but as brave developer you want to improve things. You met that ugliest method in your life and only one thing you want to do - refactor it. But refactoring is dangerous procedure. For safe refactoring you need to have good test coverage. But wait, it is legacy code. You simply have no tests. What to do? Approvals have answer.

Legacy code is the code that...

Works! Right, it is ugly, un-supportable, nothing you can easy change there. But the most wonderful feature of that code - it works for years. And first thing is to get advantage of that fact!

Here is my "just for example" legacy method.

namespace Playground.Legacy
{
    public class HugeAndScarryLegacyCode
    {
        public static string TheUgliesMethodYouMightEverSeen(string s, int i, char c)
        {
            if (s.Length > 5)
            {
                s += "_some_suffix";
            }

            var r = new StringBuilder();
            foreach (var k in s)
            {
                if ((int)k % i == 0)
                {
                    r.Append(c);
                }
                else
                {
                    if (k == c)
                    {
                        if (r.Length <= 2)
                        {
                            r.Append('a');
                        }
                        else
                        {
                            r.Append('b');
                        }
                    }
                    if (k == '^')
                    {
                        r.Append('c');
                    }
                    else
                    {
                        r.Append(k);
                    }
                }
            }

            return r.ToString();
        }
    }
}

(it's it ugly enough?)

It has a cycles, nested if-else case and all nice features of legacy code. We need to change it, but in the same time guarantee it would not be broken.

Trying first simple test

Supposing also, I'm not much in details of how exactly this function works.. So, I'm creating the test like:

[Test]
public void shoudl_work_some_how()
{
    Approvals.Approve(HugeAndScarryLegacyCode.TheUgliesMethodYouMightEverSeen("someinput", 10, 'c'));
}

I run it and got some result to approve:

approvals

I approve that, cause I know that function works. But something inside tells you - that is not enough. Try to run in under the coverage:

approvals

That does not make me real confident with tests only one hit and coverage 76%. We have to create better tests cases.

Use combinations of arguments

Approvals include some tools to deal this case. Let's change out test and write something like,

[Test]
public void should_try_to_cover_it()
{
    var numbers = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
    var strings = new[] { "", "approvals", "xpdays", "^stangeword^" };

    ApprovalTests.Combinations.Approvals.ApproveAllCombinations(
        (s, i, c) => HugeAndScarryLegacyCode.TheUgliesMethodYouMightEverSeen(s, i, c),
        strings,
        numbers,
        chars);
}

With only few lines of code, I've got 1560 test cases and all of them are correct!

approvals

Besides, I got pretty good coverage. Ideal, I would say. Now, if even one small change would happen, some of 1560 tests will notice that.

approvals

Locking down

The process of controlling the legacy code in that way is called "Locking down". After the code is locked down, you have high confidence (read low risk) of breaking changes you introduce. Please note how low effort it was to create all that 1560 tests and how much value gained in that.

Notice, that test like should_try_to_cover_it is not supposed to "live forever". You probably even don't need to check it in to source control. You just do your job, either refactoring or changing that functionality and use Approvals to notify you as fast as possible of something goes wrong.

Why New Technologies Move Your Product Faster?

This summer my company e-conomic started new project with a working title SBA (Small Business Accounting). The project is about the creation of the product for small business owner, like consultants, web shops, freelancers etc. Since my company already had great expertise in that area the product vision and initial backlog of stories was already in place. Even more, we already had a product that does nearly the same but for a different target user - so, it was kind of natural to try to build SBA based on existing one. We started our journey having very ambitious plan in our mind meaning release in less than 6 month.

But to our great disappointment the progress for next 2 month appeared very low. We underestimated one thing - the existing product is a great but some of the underlying technologies were ill-suited for the new projects. Very simple things, like adding new custom form, UI changes, data access etc. were hard and unpleasant.

The legacy code, de-motivation and low progress.. were about to bury the project. Fortunately, the company were brave enough to change something on a fly. We went a very risky way, to build new product not based on old technologies, but almost from scratch. And as for me, that was great decision! So, somewhere in October we re-started the project.

What have we changed and how it went?

SVN => Git

I have posted earlier some my experience of starting to use Git in SVN-based organization. That time it was 2-3 people that tried to adopt that process, now it is only 2-3 who are not using it. We are thinking about moving to pure Git environment, but our deployment procedure slightly depends on SVN. As soon as we fix it, we can get rid of SVN completely.

You might argue, that changing source management tool is not exactly technological change and not affecting development velocity! But wait a minute.. How much time did you waste to resolve stupid tree conflicts? How much time you waste waiting for new branch, at the code freeze period? How many times your thrown away yours refactoring results, simply because you are not able to commit that now?

All of that factors are contra-productive. It could be not even seen from first sight, but Git improves the velocity simply by getting rid of annoying things that are natural to centralized source control management systems.


git

ASP.NET WebForms => ASP.NET MVC

Supporting WebForm's code is a big mess. It's is difficult to test, difficult to understand and to change. We had a bunch of custom controls that worked fine, but adopting them to something different is hard.

For the year I'm studding ASP.NET MVC and much inspired by it's clear and powerful design. So, I was really happy we finally moved that direction.

We are using MVC in both modes: as for our web UI pages and for REST services. The same URL could produce both HTML or JSON response, depending on context. Having that, we are much flexible and not duplicate the code on pages and web services. MVC controllers are easy testable, Views are clean having only HTML with only few server side code snippets. Switch to ASP.NET MVC boosts us pretty much.

I think the adaption of new technology was really fast, even if we had some issues at the beginning they have been solved. I have to say that to use ASP.NET MVC we have to update production environment, namely upgrade in Windows 2008 with II7 which requires additional investment. But I think it's only for good, cause having environment debt is the same as having technical debt in code.


asp.net mvc

Pure jQuery => Backbone.js

jQuery is the best javascript framework ever. It suites so nicely till the application is not getting to much big. As you getting out some imaginary "bounds" jQuery code get out of the control. Till that time we already had huge amount of .js files mixing out logic and UI stuff.

We were choosing between Knockout.js and Backbone.js and finally stopped at Backbone. Backbone.js introduce order in client-side code. It has clear separation of concerns for Models, Views, Controllers.. so we can say Backbone.js is MVC framework on client.

Having order is first step for productivity. The things are more predicable, read more fast to getting things done. Of cause, it takes a lot of effort to learn it. And no surprise some we still having some challenges caused by lack of expertise. But having Derick Bailey as our consultant making it better.

I would add that ASP.NET MVC and Backbone.js suits each other very nicely, since Backbone.js is REST oriented and ASP.NET MVC exposing REST in a right way.


backbone.js

Super.Tricky.NHibernate.Wrapper => ADO.NET

One of the pain-in-neck points of our application is data access. We have huge wrapper around the NHibernate framework. Words "Wrapper on NHibernate" could make someone sick, what if I say, "Wrapper on HHibernate, which is code generated"?

So, someone might treat that are making step back. But I don't agree. Whatever things you can do in C# code, it is SQL only the language your Database can speak. Having a ORM's are kind of having translator during the conversation with foreign guy. It works great as soon you speak simply, it's getting worse than conversation going complicated, so translator hardly could translate everything you want to say. And of cause, it almost has no sense to have a translator, as soon if you can speak that language.

We are not using pure ADO.NET, it would be complicated. We have a tiny wrapper on that that basically run queries and returns result sets. It might seem harder, but I would say it's very flexible. You can create what ever queries you need and map them what ever models you have. It works fine, it works fast. It is easy to test, since you no longer need NHibernate profiler to understand what's wrong in you application, code just close to you.

After last Kiev ALT.NET meeting I understood we are not alone here. A lot of people start to understand that NHibernate becoming to heavyweight. New movement of MicroORM's appeared, that combines power of SQL and functionality of mapping tables to objects. I want to believe that some MicroORM framework could be our next thing to adopt.


sql

De-motivation => Obsession

It is not technological factor.. it is not even something I easy describe. Developers are taking responsibility by changing the things or advocating for some particular technology. You are no longer have excuse of bad quality because of legacy reasons. Sure, legacy still plays some role but impact is not so high.

Having a new technologies on board simply makes developers happier. Happy developer is obsessed developer, he is commited to success. He will work as much as he can to make good results.

With a consistent challenge, every day is no longer "another day in office", but rather "yet another day on pirate ship". It starts to smell start-up shop, that tried to get on market as soon as possible, adapting last available tools. The project now is not something I just had to do, but kind of pet project, where you trying things out and feel great if those things works.

That's why in particular I think it is great to start from scratch (or near to scratch) one a year or something. Pick up last thing, learn them, adopt and build something valuable - it is nothing to compare with maintenance of 5 year old code.

New technologies moves you product faster!

ELMAH MVC: Answering questions

I've received some questions recently regarding ELMAH.MVC nuget package. Here is the summary blog post and I hope it is helpful.

How to change that to log it into a database?

Indeed, the demo project on a github uses simple Elmah.MemoryErrorLog just holding all errors in session. That works great for small application or just to try out things. In reallity you need some persistant storage, like files or database. And this is extreamly easy to do. Take a look at this section of web.config:

<elmah>
    <security allowRemoteAccess="yes" />
    <errorLog type="Elmah.MemoryErrorLog, Elmah"/>
    <!--<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="elmah" />-->
    <!--<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/Elmah.Errors" />-->
</elmah>

Just comment out Elmah.MemoryErrorLog and de-comment Elmah.SqlErrorLog (will store errors to SQL database) or Elmah.XmlFileErrorLog (will store errors to XML files). XML logger, just requires a virtual path to folder there files will be stored. Sql logger, requires a connection string name for ELMAH database. The same web.config contains:

<connectionStrings>
    <add name="elmah" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=elmah;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>

The database have to have ELMAH schema inside. It is very easy to prepare that schema, just run this SQL script against database you want to keep errors to.

Does ELMAH.MVC handle custom error pages?

This is a misconception. ELMAH.MVC is not about custom pages, at all. This is good answer on stackoverflow on that. For a code example, you can refer to something I did for before my projects just here

ELMAH.MVC gives me FxCop/StyleCop issues?

I've received that kind report on github issues. Initially I thought to do something about it but then I left that idea. The explanation is inside the ticket.

Short answer is, ELMAH.MVC is nothing more that boilerplate code. As soon as you can see it work and it works OK for you, adopt it for your custom needs. That's it.