Saturday, October 22, 2011

WP7 Mango and NUnit from console

If you are building Windows Phone application you probably have faced… well… not rich support for unit testing. But of course there is one rescuing thing – WP7 is almost the same Silverlight application. Thus you have wider area to search for solution. Awesome… but I wouldn't write this blog post if everything is that easy. Right?

 

Support for NUnit and command line

Microsoft for some reason doesn’t care about huge community of those who use NUnit for their projects, and believe me not for small projects. So there of course is mstest project template that allows you to run tests inside of the appropriate CLR. There is good Silverlight Unit Tests Framework and here is information on how you can cheat in order to get it working for the phone. Problem with these two frameworks is obvious – they are not supporting console – they run in native for Silverlight environment – either on phone or in web. See pictures (phone and web respectively):

image

I know that there are ways to make it happen from console under (msbuild for example this temporary wp7ci project on codeplex). Hold on… one second. Again something very specific to Microsoft – msbuild. But what if I’m using nAnt?

Of course there is port of the NUnit for the Silverlight (here is how), also you can change tests provider in the “Silverlight Unit Tests Framework” (further SUTF).

Nevertheless summary is simple – no support for running nunit tests for the WP7 from command line.

 

Support for command line – solution

I came up with odd solution to force nunit-console to run unit tests in command line. After I observed it crashing with error TargetFrameworkAttribute I reflected mscorlib and googled a bit to discover this attribute exists in mscorlib of 2.0.5.0 version, but nunit actually targets 2.0.0.0 one (.net 2.0). Thus I decided to download sources of NUnit and recompiled those against .net framework 4.0 (mscorlib 2.0.5.0). Reason for this error is that Silverlight also uses higher version of mscorlib.

Awaiting for NUnit 3.0 which is promising to have support for Silverlight.

 

Support for Mango – problem

Before upgrading to Mango our tests for WP7 were created by testDriven (to be honest – it is what they use inside of their SUTF). We didn’t have support for command line and tests were running only because they are so Silverlight compatible.

With updating to Mango everything just died. Tests projects simply didn’t get loaded into solution. With this message:

image

“Not a big deal” you say. Actually a big deal, because you can get rid of this message by editing project files to have target framework profile set to WP71 and to reference only WP71 assemblies. But in this case you lose all of you compatibility with Silverlight and when you run your tests you start to get weirdest exceptions in the world like this one below:

System.DivideByZeroException : Attempted to divide by zero.
at System.Collections.ObjectModel.ObservableCollection`1..ctor()

At least this brings some more sense:

System.InvalidProgramException : Common Language Runtime detected an invalid program.

 

Support for Mango – solution

Solution I came up with is not 100% right, but at least it works. I just had to pretend that I’m still completely compatible with Silverlight. So I created copy of my project. One is considered to be used from command line and other for usage from VS.

Project 1 is used under VS has correct references directly to WP71 assemblies, like below:

    <Reference Include="System.Windows">
<HintPath>..\Library\Silverlight\WP71\References\System.Windows.dll</HintPath>
    </Reference>

This ensure that VS loads your projects without errors, also you make it think it is WP7 by these:

    <TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>

and this:

<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets" />

Project 2 is used for console and is pretended to be pure Silverlight, so it has:

    <Reference Include="System.Windows">
            <Private>True</Private>
    </Reference>

Which in reality copies (because of <Private>) wrong assemblies – from Silverlight, not from phone.

You would need to play a lot with which assemblies you want to get in folder where you run tests. I do have some confidence that Silverlight and WP7 are much compatible thanks to this brilliant explanation of what is WP7 from developer’s view.

 

Results

image

At #1186 I finally got build working and running tests. At #1193 I invented this Silverlight pretending trick. And finally till build number #1196 I ignored couple of incompatible tests and fixed some really failing tests.

Hope this helps someone. At least it is going to help my team.

Monday, October 17, 2011

Why am I angry at developers? Is it factory? Is it testable?

Please take a look at this code snippet. What would you say about it?

    public class TreatmentDataProviderFactory
    {
        private IDataAccess _dataAccess;
        private TreatmentDataProvider _treatmentDataProviderHost;
        private TreatmentDataProviderField _treatmentDataProviderField;

        public TreatmentDataProviderFactory(IDataAccess dataAccess)
        {
            _dataAccess = dataAccess;
        }

        public ITreatmentDataProvider Provider
        {
            get
            {
                if (SomeInteractionSingleton.PluginHost.GetWorkMode() == WorkMode.ConnectedMode)
                {
                    if (_treatmentDataProviderHost == null)
                    {
                        _treatmentDataProviderHost = new TreatmentDataProvider(_dataAccess);
                    }
                    return _treatmentDataProviderHost;
                }
                else
                {
                    if (_treatmentDataProviderField == null)
                    {
                        _treatmentDataProviderField = new TreatmentDataProviderField(_dataAccess);
                    }
                    return _treatmentDataProviderField;
                }
            }
        }
    }

Doesn’t it smell bad a lot?

1) Let’s start with obvious: properties in C# are not intended to be 10-20 lines long and having complex logic. Anyway I won’t wrote post if this was a problem.

2) Now the worst mistake here: how am I supposed to test this code if it uses SomeInteractionSingleton in the if condition. Why should this code be so coupled to SomeInteractionSingleton? I wrote this post because developer didn’t run tests. If he ran the tests, he would see they fail.

3) Now second bad mistake: this code keeps two instances of data providers. We can suppose that this is storage for two providers or something? :) I think GC is designed for something and lifecycle of objects shouldn’t be treated as this. I thought IoC is invented for something like this. At least developers should not keep code that much coupled and deliver creation logic.

4) Another mistake: Is this a Factory Method design pattern? – Almost. At least it has such name and looks like it (a bit). But it doesn’t meet either its original definition or either Parameterized Factory Method definition.

I redesigned this class. See:

    public class TreatmentDataProvider
    {
        protected TreatmentDataProviderHost TreatmentDataProviderHost { get; private set; }
        protected TreatmentDataProviderField TreatmentDataProviderField { get; private set; }
        protected IPluginHost PluginHost { get; private set; }

        public TreatmentDataProvider(IPluginHost pluginHost, TreatmentDataProviderHost treatmentDataProviderHost, TreatmentDataProviderField treatmentDataProviderField)
        {
            PluginHost = pluginHost;
            TreatmentDataProviderHost = treatmentDataProviderHost;
            TreatmentDataProviderField = treatmentDataProviderField;
        }

        public ITreatmentDataProvider Provider
        {
            get
            {
                if (PluginHost.GetWorkMode() == WorkMode.ConnectedMode)
                {
                    return TreatmentDataProviderHost;
                }
                else
                {
                    return TreatmentDataProviderField;
                }
            }
        }
    }

Code above does the same logic, but it delivered control of creation of instances to other parties (IoC), also it now doesn’t have dependency on static methods, so code is less coupled. I didn’t remove this class as we have to keep verification for WorkMode at runtime. I know you might complain about these protected properties, but I like to have it that way for more flexibility when testing.

What are your thoughts? [Sentence removed 10/18/2011]

[Added 10/18/2011]

5) Yet another big mistake: Code reviewer. Guess who he was. When I’ve been reviewing this code by request of developer I just thought “it works, then it should be ok”. Why didn’t I ask about unit tests and why didn’t I took reviewing more scrupulously. I have to be more accurate when reviewing others code. Bad code reviewer.

6) Yet another mistake: writing this blog post. I understand that my criticism might be taken to close, especially if this was read. I also don’t like criticism. No one likes. Man, if you reading this you have to know I didn’t mean to abuse you or something, I just was upset at night about failing tests.

Saturday, October 15, 2011

Help me select UML for book: hand-drawn or tool-prepared

As you may know I’m working on Design Patterns book in Ukrainian and as most of the posts I had on patterns have UML-s, I’m considering having UML diagrams in book as well to be consistent. Thus I can either prepare them in some UML tool or just draw. See yourself.

Drawn by me

FACTORY_NEW

Also drawn by me, but in advanced tool

image

And here how it looks like when on paper

image

image

Why I like hand-drawn option

I would like to use hand-drawn variant because it will make the book look cheery and will make the difference. It might bring some interest like “So what’s is really on that diagram?”. Also I still don’t position book as an “official” book, so I would like to have some bits of unofficially. Especially taking into account that auditory is mostly young starting developers.

Why I don’t like it

I’m of course hesitating, as this variant in its origin is inaccurate (of course I can try harder). Also maintaining such diagrams is bit more difficult, but I don’t see any problem with this.

Please help me choose!

 

[Added later (wasn’t in original post)]

After I posted this friend suggested me to use this online uml generation tool. And it would be great another option to consider, but it generates not really what I want:

image

But it was extremely nice, that to generate picture above I just used this code:

# Abstract Factory
[Cat]^[WoodenCat], [Cat]^[TeddyCat]
[Bear]^[WoodenBear], [Bear]^[TeddyBear]
[IToyFactory]^[WoodenToysFactory], [IToyFactory]^[TeddyToysFactory]
[TeddyToysFactory]uses-.->[TeddyBear]
[TeddyToysFactory]uses-.->[TeddyCat]
[Client]->[IToyFactory]
[Client]->[Cat]
[Client]->[Bear]
[WoodenToysFactory]uses-.->[WoodenCat]
[WoodenToysFactory]uses-.->[WoodenBear]

Nice tool, indeed, but for extremely simple diagrams.

[Added later (15 Oct, after comments)]

After comment by Satomi Joba I tried community edition of another tool, called Astah. Below is what I was able to draw by it. Two things about it: 1) Drawing in this tool is just fabulous, smooth and easy. For me it was more quick and intuitive drawing than in such matured tools as Enterprise Architect for example. 2) Although I’m not sure I like this bold borders and I wasn’t able to quickly change styling of diagram (maybe because of edition I used?).

image

Anyway question is still the same: do I use hand-drawing or do I use tool?

Saturday, October 8, 2011

Uneta Plus

Week ago I had a chance to be at one of the best Ukrainian conferences for the recent time. Awesome conference, awesome presenters, awesome people, awesome uneta plus.

Andriy Buday at Uneta Plus ConferencePPhoto by Mike Chaliy

Conference was far from my home in faraway city Kharkiv. I’ve been there once, when delivering MEF talk last year at ITJam2010. Even location kept the same:

 

Now more on conference itself. It started with keynote from two maybe most known ms guys in Ukraine – Dmitriy Nikonov and Serhiy Baidachni.

I cannot say that keynote was structured and well organized speech, it was more improvising, but having those two guys rescued it. They definitely are not new in field of presenting something, so auditory listened with attention, and all get acquainted with what’s next. Especially I really enjoyed stuff now available in TFS. It is getting matured over time.

Following presentation I attended was about Silverlight and XNA and how they live together in WP7 Mango. It wasn’t deep dive into things in Silverlight or XNA, but I enjoyed observing small UFO flying thought the auditory (background was transmitted from phone camera).

“Every game consists with 3-4 parts at each level. They are load and unload. Between those is while loop that has two calls – update game world and render game world.” – said Alex Golesh*. Now in WP 7.5 we can render both Silverlight and XNA in same application. I found this msdn page well informative.

Sharepoint for internet sites gives good business solution. I was able to see Sharepoint in action. Marat showed how we can start with file->new project and proceed to completed site, designed in sharepoint designer. Also some bits about authorization and authentication in sharepoint, and I felt like I’m guru in sharepoint… NO! I still think it is complex and not clear, but Microsoft actively pushes this product. Personally I think, that even if it is great product, it is not something that you would want to listen at programmers conference.

Lunch. Oh yeah, I really appreciate guys, who organized this event, as I could eat tasty (no really!) food without leaving conference. I guess money I paid for conference has something to do with taste of food, but believe me – it worth to pay more and get normal food.

I also attended presentation on entity framework, which consisted with two parts and was delivered in English by Diego Vega. Man, if you are reading this, you have to know – you rocked! I found this presentation to be best structured and most fulfilled with information on its topic.

Also I’m bit disappointed that I didn’t saw that amazing luster of Dmitriy Kostylev. Everyone who was in section 2 listening to him were literally excited. Ah… sad I missed that hardcore SQL optimization wisdom.

Another thing made this event different - so called “round table”. All of the speakers were gathered at the scene answering questions from auditory. I enjoyed this part as well, but left before the end, as I had train back to home.

Organizers of even asked few times about feedback. They want to hear more about what can be improved in this event, what was great and what wasn’t that much great. Here are few of my subjective thoughts:

  1. Lower price a bit. I think more people will attend if price would be something more moderate, but who knows… you tried to balance between number of attendees and price, not me. I was frustrated about showroom not being full.
  2. How about more sections, so I can choose if I get overview of sharepoint, tfs, or if I get flood of hardcore wp7 stuff. I just want more clear vision on what I can grasp from one or other presentation, because in some topics I feel myself confident and need advanced level, respectively in some I need introductory level.
  3. Personally I would like to see more foreigners, like Diego. I don’t know if it is hard to have them on event, but if you bring someone like Hanselman, I bet I will visit you even I have to pay more and travel longer.
  4. I’m not sure it worth complaining but why not Kyiv?

Despite of what I listed above uneta plus really was different sort of event of those I visited ever before because of extremely awesome presenters and great organization. Well done!

* This is how I remembered his words. I don’t promise I didn’t misinterpret something.