CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Ranjan Sakalley

April 2005 - Posts

  • TDD with Whidbey (Team Test)

    Honestly, its good to have a test generator right there in your own sweet copy of VS.Net. But you need to buy the Team Test edition of the Team System. Sad. In the past, I have argued with many people about generated test cases, from people who have written books on TDD to normal people like me, and all their arguments were centered on "You will lose the control"/"Whats the use of TDD then?"/"What about test first and code then?". Except for the last one, these are very much similar to the ones which came forward when people cried about why "Drag Drop"/"Visual Studio Generated code" for VB(of which i know nothing) and other languages (and this was my argument :) ) . Ofcourse every geeko will take their time criticizing this feature, embracing it later one way or the other. Paying for it too. Sad.

    Personally I hold the last point, namely "test code first and then code" to be the strongest argument out there against code generation. I have thought about this a lot, and though I understand that I am no high authority in this world, I find myself thinking that its just a philosophy. And as any other philosophy, there are better and more personalized ones out there. Which broadly means that as and when I find myself in a situation where generation speedens my development process, I shall use it, no matter what people say. Good old test first is correct, and it shall carry on, with a little personal twist on my side.

    Wait, I have one more argument! Most of the people think that TDD cases are just a way to verify the "correct"ness of the code, by developers. No. Not just that. TDD cases, i.e. code written to test code actually opens up a new perspective towards quality verification by third parties too namely the QA teams. They tally their use cases with the test cases, write extra if there are none there for the use-cases. They are not developers (which is sad, and they earn more than developers, which is sadder still) so they normally work on written code. What of them?

    So test generation is ok by me, because it serves a purpose. If handled correctly. Sad.
    Handle it correctly.

    Here is some insight I might provide. Darrell has already written about how to re-use your NUnit test cases ( I really wish MS had supported this rather than creating their own, with Mr.Newkirk right there in Redmond) here (http://codebetter.com/blogs/darrell.norton/archive/2004/06/17/16811.aspx).
    In brief, almost all attributes, asserts and static calls are supported. So you just need to change one "using" line. And so, I will try to concentrate on the generator.

    Lets take a class that needs to be tested.

    namespace Tested
    {
        public class Math
        {
            public int Add(int firstNumber, int secondNumber)
            {
                return firstNumber + secondNumber;
            }
        }

    }


    Generated test class for the Add method is-

    using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;

    // The following code was generated by Microsoft Test Code
    //  Generation V1.0. The test owner should check each test
    //  for validity.

    namespace Tested
    {
        ///
        /// This is a test class for Math and is intended
        /// to contain all Math Unit Tests
        ///
        [TestClass()]
        public class MathTest
        {
            ///
            /// Initialize() is called once during test execution before
            /// test methods in this test class are executed.
            ///
            [TestInitialize()]
            public void Initialize()
            {
                //  TODO: Add test initialization code
            }

            ///
            /// Cleanup() is called once during test execution after
            /// test methods in this class have executed unless
            /// this test class' Initialize() method throws an exception.
            ///
            [TestCleanup()]
            public void Cleanup()
            {
                //  TODO: Add test cleanup code
            }

            private TestContext m_testContext = null;

            public TestContext TestContext
            {
                get { return m_testContext; }
                set { m_testContext = value; }
            }

    ///
    /// AddTest is a test case for Add (int, int)
    ///
            [TestMethod()]
            public void AddTest()
            {
                Tested.Math target = new Tested.Math();

                //  TODO: Initialize to an appropriate value
                int firstNumber = 0;
                //  TODO: Initialize to an appropriate value
                int secondNumber = 0;

                int expected = 0;
                int actual;

                actual = target.Add(firstNumber, secondNumber);
                Assert.AreEqual(expected, actual);

                Assert.Inconclusive("Verify the correctness of this test method.");
            }

        }
    }

    Stop tinkering about my color coding scheme. I am color blind. Concentrate. We need to do this correctly.

    You can yet again read about the attributes at msdn2.microsoft.com (wait, there are no descriptions there, and may be that's why I am telling you to go there.) Let me try -

     [TestClass] = [TestFixture]
     [TestMethod]  = [Test]
     similarly [TestInitialize] [TestCleanup] are mapped to the corresponding SetUp and TearDown attributes. ( naming something differently does give you a copyright, am I right?).

    So the test case looks like -

            public void AddTest()
            {
                Tested.Math target = new Tested.Math();

                //  TODO: Initialize to an appropriate value
                int firstNumber = 0;
                //  TODO: Initialize to an appropriate value
                int secondNumber = 0;

                int expected = 0;
                int actual;

                actual = target.Add(firstNumber, secondNumber);
                Assert.AreEqual(expected, actual);

                Assert.Inconclusive("Verify the correctness of this test method.");
            }

    TODO's  are I think very nice, I need not run around trying to find out where to initialize to an appropriate value. I call it the VB touch.  "expected" and "actual" are pretty descriptive names. Then there is the regular assert. And then there is Inconclusive, which is basically there to notify you to write a conclusive test case (by commenting the line? ha)

    Anyway, what my point is (listen, its not very hard to understand), is that I fight all those people, tell everybody how good generating test cases would be, and all I get is ONE test case?

    Who will write the test cases to check the method input parameters?
    Who will write the test cases with expected exceptions?
    Where should I define my own test template, and then the generator generate the test cases based on that?

    Like you would have guessed, this test case generator is inconclusive. Its got nothing yet, and I hope it would be improved. Till then, I am happy to write my own test cases, and write them first. (Do look into the tests generated for the private methods. Really a great implementation.)

    Anyway, I am just one in more than a million, so the VS.Net team might not even notice this, and so......

    Lastly, I am not color blind. I am just lazy (as you would have guessed too, by now).

    Posted Apr 29 2005, 06:59 AM by rsakalley with 9 comment(s)
    Filed under:
  • Friday Quiz I : Who wrote the first Hello World program?

    Thought about starting a quiz series, a question every friday kind of. So todays question is :
    Who wrote the first "Hello World" program?

    I might know it, but I am not sure. Do you know?

    Posted Apr 28 2005, 10:37 PM by rsakalley with 6 comment(s)
    Filed under:
  • Loading two versions of an assembly that are not in the GAC

    Many a time you might face this issue. Especially when you are using a third party component, which uses an older version of an assembly, of which you are using a newer version. Pre 2.0 (and I do not know for sure of 2.0) compiler compliant to the CLS do not support the functionality of a static reference of two differently versioned assemblies with the same name at compile time.

    The safest way to do this is Load the assembly object at runtime using Assembly.Load and then calling the appropriate methods. Do not forget to give different display names to these. If the assemblies have strong names and they are Loaded then, they are treated as different assemblies by the CLR. If the assemblies are not strong names, even two identical assemblies loaded from different paths are considered two different assemblies. In both the cases (strongly named or not) even the identical types in the two assemblies are not castable to each other.  
    In other words, you have an Assembly X v1.0 with type A and type B. Type B changed with X v2.0 but type A did not. Even so, if you create an object of type A using the reference of Assembly X  v1.0, you will not be able to cast it to the identical Type A of the Assembly X v 2.0. So do not design your application in such a way that you need to cast types in two different assemblies. Or otherwise, include a casting provider.

    Code

    Lets say we have an assembly AssemblyX. Version 1.0.0.0 has the following classes

    public class A
                 {
                             public void WriteToConsole()
                             {
                                          Console.WriteLine(" Class A, AssemblyX version 1.0 " );
                             }
                 }

    public class B
    	{
    		public void WriteToConsole()
    		{
    			Console.WriteLine(" Class B, AssemblyX version 1.0 " );
    		}
    	}
    

            Version 2.0.0.0 of AssemblyX has the following classes

          
    public class A
    	{
    		public void WriteToConsole()
    		{
    			Console.WriteLine(" Class A, AssemblyX version 2.0 " );
    		}
    	}

     

    public class B
    	{
    		public void WriteToConsoleV2()
    		{
    			Console.WriteLine(" Class B, AssemblyX version 2.0 " );
    		}
    	}
    
    

     AssemblyX v1.0.0.0 is already added as a static reference to our project, lets call it AssemblyLoader (console application), directly or indirectly. Following is the code I have used to load the newer version too, along with the older one, in the same AppDomain,

    public class Loader
    	{
    		static void Main()
    		{
    			Loader _loader = new Loader();
    			_loader.LoadAndRunMethodsV1();
    			_loader.LoadAndRunMethodsV2();
    			_loader.TryCastA();
    
    			Console.ReadLine();
    		}
    
    		public void LoadAndRunMethodsV1()
    		{
    			AssemblyX.A _a = new A();
    			AssemblyX.B _b = new B();
    
    			_a.WriteToConsole();
    			_b.WriteToConsole();
    
    		}
    		public void LoadAndRunMethodsV2()
    		{
    			Assembly _assembly = 
    Assembly.LoadFrom(@"E:\Blog\Assemblies\v2\AssemblyX.dll"); Type Av2 = _assembly.GetType("AssemblyX.A"); Type Bv2 = _assembly.GetType("AssemblyX.B"); object _a = Activator.CreateInstance(Av2); object _b = Activator.CreateInstance(Bv2); MethodInfo _mA = Av2.GetMethod("WriteToConsole"); MethodInfo _mB = Bv2.GetMethod("WriteToConsoleV2"); _mA.Invoke(_a,null); _mB.Invoke(_b,null); } public void TryCastA() { try { Assembly _assembly =
    Assembly.LoadFrom(@"E:\Blog\Assemblies\v2\AssemblyX.dll"); Type Av2 = _assembly.GetType("AssemblyX.A"); object _a = Activator.CreateInstance(Av2); Console.WriteLine(typeof(AssemblyX.A).AssemblyQualifiedName); Console.WriteLine(Av2.AssemblyQualifiedName); (_a as AssemblyX.A).WriteToConsole(); } catch(Exception ex) { Console.WriteLine(ex.Message); } } }

    When you run the console application, you get the following output. Notice the object reference exception you would get, because of the invalid cast between the the two classes.

     

    You would get the same results if you used strongly named assemblies.

    Posted Apr 13 2005, 12:04 AM by rsakalley with 8 comment(s)
    Filed under:
  • Using AppDomain.Unload II

      There were a few mistakes in the last post on the AppDomain.Unload solution (thanks Manoj for pointing out) (John Papa wanted to know why I did not use LoadFile, thanks John, now I know should have written that MarshalByRef, just forgot it completely.) And sorry for this delayed update, damn weekend.

    First of all,I missed to mention the MarshalByRef derivation for the AssemblyLoader. This is essential because the Dispatch should be made to the secondary AppDomain, and if the AssemblyLoader is not a MarshalByRef object, the dynamic assembly (Tested there) will be loaded in the primary AppDomain, and therefore, the latest version will not run.So if you have just copied and pasted the code somewhere, it might not work. Just inherit MarshalByRef for the AssemblyLoader and it should work. The update is in red.

     

     [Serializable]
    public class AssemblyLoader : MarshalByRef
    {
    public void LoadAndRun()
    {

    Assembly _assembly = Assembly.Load(<< assembly file path>>);
    Type _type =_assembly.GetType(“Tested”);
    MethodInfo _method =_type.GetMethod("Test");
    _method.Invoke(Activator.CreateInstance(_type),null);

    }

    }

     

     

    Second thing, there is a workaround, if you do not want the calls to be dispatched to the secondary AppDomain. You can use the following -

    [Serializable]
    public class AssemblyLoader
    {
    public void Load()
    {
    FileStream _fileStream = File.OpenRead("Tested.dll");
    byte[] _assemblyAsByteArray = new byte[_fileStream.Length];
    _fileStream.Read(_assemblyAsByteArray,0,(int)_fileStream.Length);
    _fileStream.Close();
    Assembly _assembly = Assembly.Load(_assemblyAsByteArray);
    Type _type =_assembly.GetTypes()[0];
    MethodInfo _method =_type.GetMethod("Test");
    _method.Invoke(Activator.CreateInstance(_type),null);

    }

    }
     
    That is, do not inherit the AssemblyLoader from MarshalByRef, and Load the assembly as a byte array. This loads the latest version. 
    The good part here is that there are no calls dispatched on the secondary appdomain, so it should be faster. The bad break is,
    there is an upfront overload of File IO. And yes, I do not know if this is supported or not.
    Posted Apr 11 2005, 01:35 AM by rsakalley with 11 comment(s)
    Filed under:
  • Assembly.Unload? Use AppDomain.Unload instead.

    Well we ended up writing a VS.Net plugin to add to our developer testing tools (something like NUnitPlugin, but different). Not much, but almost the whole program was written and then there was this problem that all VS.Net plug-in writers face, atleast once in their life. Namely, you load an assembly, using Assembly.Load, but then how do you unload it? There is no Assembly.Unload out there ( Why isn’t there an Assembly.Unload method out there? ).

    Solutions posted by Jason Zander, Suzanne Cook (if you haven’t read her blog, go read it, especially if you’re missing one Mr. Chris Brumme, and btw, Suzanne hasn’t posted for a long time too, so ping them and tell them that we want them back) mention that you need to load an assembly into a secondary appdomain, and then unload that appdomain. Eric Gunnerson’s MSDN article is a great help,here.

    I will try to explain the pattern, with a console app that I wrote.

       The Type “Test” is the dynamic type we have, and even when the assembly containing this type is changed, the final console application should run the latest compilation. For simplicity, lets have a simple class that writes to console. Compile this and keep this in an assembly.

    	public class Tested
    	{
    		public void Test()
    		{
    			Console.WriteLine("First Run");
    		}
    	}

    First, create the assembly loader. The following code loads an assembly using a file path (hard coded here, you need to do it in a better way).
    It gets the Type I wanted to run (Tested) and then invokes a method in the class ( “Test”) using an object of the Type. Create another assembly for this class.

     

              [Serializable]
    	public class AssemblyLoader : MarshalByRef /*<updated>*/
    	{
    		public void LoadAndRun()
    		{
    			
    			Assembly _assembly = Assembly.Load(<< assembly file path>>);
    			Type _type =_assembly.GetType(“Tested”);
    			MethodInfo _method =_type.GetMethod("Test");
    			_method.Invoke(Activator.CreateInstance(_type),null);
    
    		}
    		
    	}

     

    Next create an AppDomainLoader(code below) (console exe here, you can have a class of your own in an assembly of your own) which creates an AppDomain. It then loads an instance of the assembly Loder class, using CreateInstanceAndUnwrap, which combines the CreateInstance and Object.Unwrap. It then runs the LoadAndRun method to indirectly invoke the latest version of the “Test” function in the “Tested” class.

     
    	class AppDomainLoader
    	{
    		[STAThread]
    		static void Main(string[] args)
    		{
    			while(Console.ReadLine() != "X")
    			{
    				try
    				{
    					Console.WriteLine("Press  to start");
    					Console.ReadLine();
    					AppDomain _domain = AppDomain.CreateDomain("Remote Load");
    					AssemblyLoader _aLoader = 
    						(AssemblyLoader)_domain.CreateInstanceAndUnwrap(
    						"AssemblyLoader","Proteans.IPDev.PoC.AssemblyLoader ");
    					
    					_aLoader.LoadAndRun();
    
    					AppDomain.Unload(_domain);
    				}
    				catch(Exception ex)
    				{
    					Console.WriteLine(ex.ToString());
    				}
    			}
    		}
    
    	}
    Once you unload the app domain, the assembly automatically (well!) gets unloaded with it. I have written a while loop here,
    which shall run the the process repetetively, till you want, and in between this, you can go ahead and recompile the “Tested”
    class with a changed Console statement, and check if the latest changes are reflected in the output.
    This can be a good skeleton to build on. Helpful?
     
     
    Posted Apr 08 2005, 05:16 AM by rsakalley with 12 comment(s)
    Filed under:
  • Multiple overloads with distinguishing parameter as object is dangerous

     From John Papa's post to Jackie Goldstien's that quoted Pablo Castro[MS], got these words that were somewhere in my mind but never expressed. Thanks all.

    In general, having multiple overloads where the distinguishing parameter type is “object” in one of them is a dangerous thing to do.

     

    Posted Apr 06 2005, 11:37 PM by rsakalley with 10 comment(s)
    Filed under:
  • Metrics and XP

      The measurement of change, the expected and the implemented, are best expressed as numbers. The numbers might represent different aspects in different situations; in different phases, sprints, pushes, periods or whatever you prefer to call them. The number themselves are more important to the team, «For philosophical reasons, I refuse to break the team into sub-atomic particles» than external elements, and in more cases than not become the pivot around which the development revolves and evolves. Much to our delight, these numbers seem to be very important to managers and clients for obvious reasons, and both ends of the river meet. Its such a nice place to live, this world ain’t it? Be forewarned.

      There are some numbers that I would decide upon, if I just started developing a robust «lets hope» software product.

    1. Features completed/ Feature backlog
              Very basic metric. Divide each iteration into a number of features. While developing, find out whats the % age of work completed in terms of features. The one flavor that really helps is the weighted %. Assuming all features are not equivalent, assign a weightage to each feature. And then calculate the work done % age. This becomes complex with the 2nd iteration when bugs start coming in. You need to add bug fixes as features too. Some people call them «tasks», whatever.

    2. Test cases failed %
             Another important metric. In subsequent iterations (to the first one), one might want to look at this metric to know the quality of the development, the stress areas, and most importantly, which module requires pair programming. One very important push monitoring this metric should give is the urge to follow TDD to the core. And ofcourse a better design and good distribution of features iteration-wise.    

    3. Velocity of development
             This is a metric followed by some people to track the expertise of the team, their proficiency to code. To add another parameter here, I would like to add the proficiency to understand. This makes it number of features ( x weightage preferably)  / «time frame» per developer. Definitely very helpful one the team chart.           

    4. Team meeting time and its effect 
                 An XP team should meet. Meetings are called with a goal in mind. Without discussing the types of meetings, it must be noted that one has to find out the effect of such meetings, on the overall or iteration-wide goal. The time spent on each meeting must be recorded, and its effect «if there is one expected» should be measured using one of those numbers above. 

     5. Number of change requests
                Change requests are one of the bitter truths of programming. To measure these is again an important decision. Considering them as features is another. But thats not the point. This metric is essential to note down the requirement gathering design issues involved. Another product of this metric is to keep the team updated with their mistakes «if any» .

     6. Time spent on change requests 
                 The time spent on change requests is another important metric, which highlights the design issues, extensibility factor. Noormally a good design should allow a speedy recovery path, for all such requests.
                 
       There are other mainstream metrics, that accompany the Agile RUP process which might be useful. One must not forget that keeping a chart, and updating it with the current metrics is the most important part of a development process. Ultimately, passers by should feel the enthusiasm and excellence of a team just by looking at the chart. It should be something the team must be proud of.

         

  • Practical examples of where to use Static/ Singleton instances

    Recent questions in one of the newsgroups, regarding practical examples of Static instances. I’m sure there are many ideas out there, here is my take

    Normally you would need to create a static instance when the secondary ( the primary ofcourse is the busines logic) need is -
     
     1. Keeping an instance which holds the state of the application, while all other objects around this one in the application can live and die at will ( eg. the Request/ Application objects in ASP.Net  which are static.)
     
     2. To remove the overhead of creating  and collecting objects which are more or less expected to be stateless ( consider the case of a remoting server/webservice providing math functions, totally stateless, and hence the service should mask a singleton/static instance that provides the services , thus avoiding the creation and collection of the objects created, one each for each call.)

     The question sometimes raised is whether singleton is really better than static. Situational, is it?

    Posted Apr 03 2005, 09:19 PM by rsakalley with 6 comment(s)
    Filed under:
More Posts

Our Sponsors

Free Tech Publications