Friday, January 29, 2016

"Good Enough" Testing for Infinite Inputs

As of late, I have spent a decent amount of time focused on testing.  I released an updated version of my Coded UI Fluent Extensions.  These extensions are for testing UI so it is not really important to test all combinations of inputs since what you are really testing in the UI whether things are bound correctly and trigger events expected.

When unit testing, typically we want to test as many different inputs that have meaningful results as possible.  When the inputs are finite you could test all inputs.  What about inputs that are infinite; and is infinite really something real in programming?  Consider I have a function that takes an int and returns the square.  Well, we know that only the first (int)sqrt(int.MaxValue) will work even if integers are infinite.  What about a function that reads from a stream and computes a hash of the entire stream; but the stream never ends?

Let's consider an example where we want to test an improved implementation of an existing algorithm.  Common problems for testing would be the Bag Packing problem or Fibonacci Sequence.

In the case of Fibonacci Sequence, I could compute all numbers in the sequence that fit within UInt64 or whatever structure, but consider GoLang which supports infinitely sized numbers.  Because a function can be implemented in an infinite number of ways, there would be no way to ensure that it works for *all* inputs.  I would argue that a requirement to work with *all* inputs is rarely needed.  In such cases, proving the implementation works by actually looking at the implementation would probably be the only testing strategy.

In most cases, however, testing a finite input set is 'good enough'.  We can always add bad values to regression tests as they are found over time.  Most apps can handle this and the cost of dealing with these cases is way smaller than the cost of provably perfect code.

In these cases that can handle 'good enough' testing, I would say using a crude implementation to test against is the best approach.  These results can be stored if the computation is too expensive, but then the implementation would really be a look up table in most cases :)

Also, how often does a test need to be run against code that doesn't change?  Or, changes relatively slowly.  A slow test for slowly changing code seems reasonable when the coverage makes sense.

When I used to do coding challenges, I asked the students to implement the bag packing algorithm.  I had a set of objects which I would use to test their implementations.  Using the Test-All-Combinations approach to see which was best, I was able to generate all bags in just over 4 hours, but to write the code, I was done in about 20 minutes. Students were able to find bags in seconds, but not all were implemented correctly and I could prove my bags were correct.  Further, implementing the improved algorithm took hours and hours.

This is not possible to do against all inputs; there are an infinite number of items that can go into bags with infinitely different sizes, but against a set of inputs that could not be predicted by the implementer is a sufficient for 'good enough' testing.

Well, that's my 2c anyway!  

Interviews and Whitespace

Lately, I have been in the market for a new position, but I'm not looking to settle.  I have worked at enough different places to know what is important for me, and it's not just the bottom line hourly wage.

There are so many other aspects of being happy at work that do not involve getting paid.  Team environment, willingness to collaborate and innovate, and general motivation to get better are all things that I find appealing.

Being that I do not *need* to work, I have the luxury of viewing potential work with in a very different light.  I want to work with motivated engineers who do not hide behind 'We do not have time to do things right', or 'testing just wastes time', or any other excuses of why things are not done well.

So with that in mind, I have been out looking for a perfect place where I can work to my hearts content and produce value to the company.  While interviewing, I have noticed something ... concerning ... to say the least.

I have had at least a few interviews where I was not even asked anything technical!  I wonder how these companies decide to hire talent and what problems they are running into with this approach.  I know when I interview potential candidates, I typically have the following format:

1.  Ask the candidate to self rate (on a scale of 1 to 10, 10 being a complete expert, 1 being a novice)
-> This is important to find out their confidence level and guides me on what level of question to ask.

2.  Start with the basic (what is OOP, inheritance, design patterns, sealed classes, ...)
-> This gives me an idea of the candidates strength, whether they self evaluated correctly, and further points where to start digging.

3.  Rapid descent into technical weeds.  From here, I try to quickly get to questions at the users self evaluation level.  For instance, if they evaluated at a 5, I would ask questions a mid level developer should be able to answer, or at least talk intelligently about.  I would not go into questions I would expect expert knowledge to answer unless the candidate crushed the mid level questions.

I would say about 45 minutes of digging into the candidate's brain gives a good idea of technical background.  The remaining 15 minutes are typically soft-skills type questions and allowing the candidate to ask any questions.

I finally had an interview today where they asked me a decent amount of technical questions.  One came up, however, that I just cannot seem to understand.  "Do you prefer tabs or spaces?"

I prefer spaces, always.  The reason is for dot alignment of code.  At a minimum, you would have to mix tabs and spaces to account for when you want to align to a character that is not at a tab stop.

Still, I cannot see the benefit of tabs.  You can press the tab key in Visual Studio and it will enter the appropriate number of spaces for you.  Same with Shift + Tab.

During the conversation around this, it seemed more important for a dev with different tabs to be able to see the code differently.  I do not see any value in this at all compared to dot alignment.  I would rather see my functions lining up than worry about the difference between 0.125" and 0.200" white space on the left.  I left the interview still wondering why they were so insistent about tabs.  I frankly see no benefit that would even out the fact you cannot dot align.  I am going to see what google has to say about it :)

Saturday, January 16, 2016

SendGrid in Azure

When creating a SendGrid account from the Azure portal, the user is prompted to enter a name and password for the SendGrid resource.  The specified password is the password used by SendGrid, however, the name specified is the resource name used by Azure and the username is found under the Keys button on the created resource's blade.