Posts Tagged ‘Software Quality’

As a continuation to my recent rant about the differences between programmers and developers and how programmers love to code and … well, everything it is mentioned in that post, I felt like sharing a little bit of fun I had with this stackoverflow question.

Since it had already been answered and actually there was a little debate going on about the pros and cons of the accepted answer I was about to close it and look for something else when I decided to have a little bit of fun and make the solution generic.

Not like it was difficult, after a couple of minutes I had this:

    public class PropertyValidator
    {
        public bool Validate<T, TResult>(IEnumerable<T> list, Func<T, TResult> expression)
        {
            return list.Select(expression).Distinct().Count() <= 1;
        }
    }

But the fun didn’t end there, since this was not needed in what I was working on I had to demonstrate that it worked by other means, what could those means possibly be? You guessed it, unit tests!

    [TestClass]
    public class SameValueInPropertyValidatorTests
    {
        private PropertyValidator _validator;

        [TestInitialize]
        public void Initialize()
        {
            _validator = new PropertyValidator();
        }

        [TestMethod]
        public void ReturnsTrueIfListIsEmpty()
        {
            var list = new List<string>();
            Func<string, string> expression = x => x;

            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForStrings()
        {
            var list = new List<string> {"1", "1", "1", "1", "1", "1"};
            Func<string, string> expression = x => x;

            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForStrings()
        {
            var list = new List<string> { "1", "1", "2", "1", "1", "1" };
            Func<string, string> expression = x => x;

            var result = _validator.Validate(list, expression);

            Assert.IsFalse(result);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForKeyValuePair()
        {
            var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string, int>("any1", 1),
                new KeyValuePair<string, int>("any2", 1),
                new KeyValuePair<string, int>("any3", 1),
                new KeyValuePair<string, int>("any4", 1),
            };

            Func<KeyValuePair<string, int>, int> expression = x => x.Value;

            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForKeyValuePair()
        {
            var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string, int>("any1", 1),
                new KeyValuePair<string, int>("any2", 1),
                new KeyValuePair<string, int>("any3", 456),
                new KeyValuePair<string, int>("any4", 1),
            };

            Func<KeyValuePair<string, int>, int> expression = x => x.Value;

            var result = _validator.Validate(list, expression);

            Assert.IsFalse(result);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForEnumProperty()
        {
            var list = new List<Car>
            {
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
            };

            Func<Car, Colors> expression = x => x.Color;

            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForEnumProperty()
        {
            var list = new List<Car>
            {
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Black},
                new Car {Color = Colors.Red},
            };

            Func<Car, Colors> expression = x => x.Color;

            var result = _validator.Validate(list, expression);

            Assert.IsFalse(result);
        }

    }

And since we were on a roll, why not remove the duplication by creating generic methods to assert the results:

    [TestClass]
    public class SameValueInPropertyValidatorTests
    {
        private PropertyValidator _validator;

        [TestInitialize]
        public void Initialize()
        {
            _validator = new PropertyValidator();
        }

        [TestMethod]
        public void ReturnsTrueIfListIsEmpty()
        {
            var list = new List<string>();
            Func<string, string> expression = x => x;

            AssertIsTrue(list, expression);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForStrings()
        {
            var list = new List<string> { "1", "1", "1", "1", "1", "1" };
            Func<string, string> expression = x => x;

            AssertIsTrue(list, expression);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForStrings()
        {
            var list = new List<string> { "1", "1", "2", "1", "1", "1" };
            Func<string, string> expression = x => x;

            AssertIsFalse(list, expression);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForKeyValuePair()
        {
            var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string, int>("any1", 1),
                new KeyValuePair<string, int>("any2", 1),
                new KeyValuePair<string, int>("any3", 1),
                new KeyValuePair<string, int>("any4", 1),
            };

            Func<KeyValuePair<string, int>, int> expression = x => x.Value;

            AssertIsTrue(list, expression);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForKeyValuePair()
        {
            var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string, int>("any1", 1),
                new KeyValuePair<string, int>("any2", 1),
                new KeyValuePair<string, int>("any3", 456),
                new KeyValuePair<string, int>("any4", 1),
            };

            Func<KeyValuePair<string, int>, int> expression = x => x.Value;

            AssertIsFalse(list, expression);
        }

        [TestMethod]
        public void ReturnsTrueWhenValuesAreSameForEnumProperty()
        {
            var list = new List<Car>
            {
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
            };

            Func<Car, Colors> expression = x => x.Color;

            AssertIsTrue(list, expression);
        }

        [TestMethod]
        public void ReturnsFalseWhenValuesAreNotSameForEnumProperty()
        {
            var list = new List<Car>
            {
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Red},
                new Car {Color = Colors.Black},
                new Car {Color = Colors.Red},
            };

            Func<Car, Colors> expression = x => x.Color;

            AssertIsFalse(list, expression);
        }

        private void AssertIsTrue<T, TResult>(IEnumerable<T> list, Func<T, TResult> expression)
        {
            var result = _validator.Validate(list, expression);

            Assert.IsTrue(result);
        }    

        private void AssertIsFalse<T, TResult>(IEnumerable<T> list, Func<T, TResult> expression)
        {
            var result = _validator.Validate(list, expression);

            Assert.IsFalse(result);
        }    
    }

Not exactly a break through discovery or even a coding kata but still it was a cute exercise for me to kill some time.

Would you like to share your favorite exercises or your sources of inspiration for coding research? I’d love to hear about them.

I dare say that the people who are kind enough to read this blog already know that I am a little freakily fanatic about unit testing. Believe it or not I do have a lot of experiences in which having unit tests in the code I was modifying saved me from doing very stupid and embarrassing mistakes and I want to share a very recent, although small, example.

For the past month I have been getting into Single Page Application development, better known as SPA and I find this book to be quite insightful. Anyway, when I read technical books I like to code all the examples and make sure they run as the book claims they do, I find I learn better that way. On the very first one, after coding a very large portion of JavaScript, I fired up the browser and … well nothing happened. I looked at the browser’s console and there were no errors whatsoever. To make a long story short I spent almost an hour reviewing and comparing the code to the book line by line, even with the downloaded code which worked. File comparing tools were not helping at all and it was a quite frustrating hour.

Finally I realized I had a typo in the following line:

var result = modal.$container.height === newConfig.heigt;

It was so subtle! Of course the newConfig object did not have a “heigt” property so its value was undefined, which of course is different that whatever value the height property in the container had and so the result was always false.

Of course I do not pretend that we should be writing unit tests for the code we copy from technical books. My point is that in a real project this kind of errors in a language like JavaScript could not only happen but cause to waste a lot of debugging time. All this time would be better spent writing a unit test that would immediately fail and point you in the right direction so the typo is found quickly and corrected, before it even reaches QA, UAT or, God forbids, production.

Because of what’s going on in the software development industry with things like mobile development and SPAs, JavaScript is gaining a lot of importance so we better start to get used to the idea, not only that we’ll be coding a lot more with this language but that we need to be concerned at unit testing that code too.

Software development has changed a lot in just a few years. I remember not very long ago that it was common and expected to work long hours, even pull all nighters just to be able to meet a deadline or worse because the deadline was the following day and there were still dozens of defects to be fixed so the deliverable would barely work. Those days, fortunately, seem to be long gone. I have not been in a project where I have had to do those kind of stupid things, of course there have been times that I have worked a little overtime but those have been the exception rather than the rule.

Unfortunately there are a lot of managers who were developers in those days who still think that we live in those days and expect their development teams to work in that fashion. Not only expect it, but demand it.

Quite recently I was assigned to a project for one of the major credit card companies and we were having our planning game for the upcoming iteration. One of the stories was particularly large so we suggested to break it down in more manageable pieces and gave our estimates to which one of the customer’s managers said, and I quote, “I can lock down a couple of guys in a room and they will have this feature ready in a couple of days”. Needless to say every single one of the members in the team was quite upset about this remark. This was not a matter of challenging our estimate but to question our professionalism. Besides, it is widely known these days that this is the worst way of developing software since it is completely counterproductive and error prone, by the twelfth hour both guys would be making careless mistakes which would generate several very hard to debug defects and the readability of the code would be questionable to say the least.

Anyway, putting aside the fact that we were quite offended by his comment, you can probably imagine how this manager visualized how his team of a couple of guys could deliver his feature. In the end there is absolutely no doubt in my mind that these two guys would pull it off, I have seen it many times before, some brilliant hero style developer getting a required feature to work in record time just before the deadline and he saves the day.

Of course as time goes by this feature will have to be maintained, defects will have to be fixed and requirements will change and guess what, the only person capable of doing that maintenance would be the hero developer who wrote the code because it is so tightly coupled and so tangled up that he is the only one who can understand what it is doing. Of course there would be no tests whatsoever so every time the code would get changed there would definitely be regressions all over the place. Every developer in the organization would dread the idea of working on that piece of code. Not to mention the huge expense these maintenance efforts would be.

I find it hard to believe, and really sad, that there are people, managers and developers alike, who think that we can and should develop software in this fashion. It almost seems as if these people have been living under a rock and have not heard anything about the trends of how to increase the quality of a software product. These people truly believe that the effort put on properly engineering the code and covering it with tests is a waste of time.

To be honest, sometimes I feel I am on the losing end of the battle and the vision of seeing software being developed with discipline and sound engineering practices is but a dream. But you know what, I do not care. I will keep pushing for building software with all the quality characteristics that so much literature, both off an online, is talking about. I will keep fighting against the idea that software development is somewhat of an art; that has got to stop. I will keep trying to evangelize as many people as I can and someday, maybe, we will see that software is built the same way as buildings, bridges, cars, or airplanes, with repeatable practices and solid discipline. I know I am not alone, there are lots of people who are striving for this, and we really hope you will be on our side.