Test Case Best Practice: It’s better to LogPass than to LogFailure

In our test case world, we assume a test case fails, unless we log pass. We changed our way of thinking a while ago, where we used to assume a test case passes, unless we log a failure. I wish I could give an example of a bug I’ve caught because of the change, but I’ve never been able to identify one that was caught exclusively because of log pass. I’ve been asking people on my team if they have any examples of bugs and other benefits from the log pass, but most people are on vacation right now. If I get more info from them after the holidays, I’ll do a follow-up post.

Here are some benefits:

  1. It significantly improves the readability of your test case.
  2. It makes the test case much easier to write and gives the test case writing more confidence in what is being verified.
  3. You have a higher chance of catching failures that do not meet your specific “pass” criteria.
  4. If, for whatever reason, the test case doesn’t explicitly log a pass, a failure is logged automatically.

Simple example:

LogPass()

 

If currentLineAfterDelete = currentLine.Remove(whitespaceLocation, 1) Then

LogPass()

Else

LogFailure("Failed to delete whitespace…")

End If

 

Versus LogFailure()

 

If currentLineAfterDelete <> currentLine.Remove(whitespaceLocation, 1) Then

LogFailure("Failed to delete whitespace…")

End If

Back to the New Orleans French Quarter and the Mississippi Gulf Coast

This Thanksgiving, I went home to the Mississippi Gulf Coast for the first time in three years (since joining Microsoft). Of course, I had to stay a couple of nights in New Orleans to begin the trip. Being back in the Quarter made me think of this list:

How do you spot a New Orleans native in the French Quarter who hasn’t been home in a while?

  1. You hear them say, “I haven’t been back to the Quarter in years.” (especially for those who still live in N.O.)
  2. They get emotional when asking for a “Sweet Tea and a Shrimp Poboy Dressed.”
  3. They refuse mardi gras beads because they don’t want to get their shirts dirty.
  4. Nothing on Bourbon St. after dark shocks them. Nothing.
  5. They do their gift shopping in the Flea Market, except for the mardi gras beads.
  6. They drink at Pat O’Brian’s at noontime in the air conditioning (in November)
  7. They wonder if the Saints have won a game yet.

Got an account at Digital Blasphemy

DigitalBlasphemy.com is the best website I’ve seen for wallpaper. While working on webtop in college, one of my coworkers had the Fluorescence wallpaper installed on his account. As soon as I saw it, I was hooked.

I have a tri-monitor setup in my office in the following way: [2] – [1] – [3]. What I like most about this setup is that the primary is in the middle, allowing me to test Visual Studio in the negative coordinate system, on monitor 2. But I digress…

I purchased the account so I could download the tri-monitor wallpapers. I’m alternating wallpaper every other day. Yep, it’s the simple things in life.  =)

What’s wrong with this test case code? – Identifying False Positives Part 2 – The Answer

The problem is with this line:

‘ retval is NULL if API failed to set focus on requested window

If retval.Equals(0) Then

Remember, the retval for this API is an IntPtr, not an integer. Even if the IntPtr is null, the exception will not get thrown.

You can do

You can do

If retval.ToInt32.Equals(0) Then

Or

If retval.ToInt32 = 0 Then

Or

If retval.Equals(IntPtr.Zero) Then

But not

If retval.Equals(0) Then

When you’re dealing with lots and lots of APIs in an automation framework, this sort of gotcha might not be as blatantly obvious as it was tonight.

What’s wrong with this test case code? – Identifying False Positives Part 2

Really easy one tonight, but something ever tester working with APIs should be aware of. Even if you know better, someone else might not.

Here’s a little example I threw together in the past 10 minutes to illustrate tonight’s point.

Public Declare Function SetFocus Lib "user32" Alias "SetFocus" (ByVal HWnd As IntPtr) As IntPtr

 

Public Sub SetWindowFocus(ByVal hwnd As IntPtr)

 

‘ call the Windows SetFocus function

Dim retval As IntPtr = SetFocus(hwnd)

 

‘ retval is NULL if API failed to set focus on requested window

If retval.Equals(0) Then

            Throw New Exception("Failed to set focus")

End If

End Sub

 

‘ the actual test case code

Public Sub Run()

 

‘————————————————–

InitScenario("Verify user can set focus on window")

‘————————————————–

 

‘ get the hwnd for the editor

Dim hwnd As IntPtr = GetSomeWindowsHwnd()

 

Dim ex As Exception

 

‘ try to set focus to window

Try

SetWindowFocus(hwnd)

Catch ex

End Try

 

‘ if we catch an exception, log a failure

If ex Is Nothing Then

LogPass()

Else

LogFailure()

End If

 

‘ continue with the rest of test case

End Sub

By popular demand, I will post the answer on a second entry. At least this way, if you find a bug in this code that I wasn’t expecting, I can play it off that I planned it that way. =)

What’s wrong with this test case code? – Identifying False Positives

This is my first attempt at a series of “what’s wrong with this test case code” entries. Let me know what you think of this idea and if you’re interested in seeing more examples.

A False Positive is defined as a test case that has been logging a passing result; however, the test case logic is incorrect, masking a product bug. In other words, if the test case writer were to run the test case manually, he or she would see the product bug.

Can you identify why the test case below could contain a false positive? Remember, you’re looking for the logic error.

You can make the following assumptions (for the sake of this example)

  1. The current line in the text file contains at least one whitespace
  2. Each individual method is bug free and does what the comment above says

‘ put the contents of the current line into a string var

Dim currentLine As String = vsEditor.Cursor.GetCurrentLineText()

 

‘ find out where in the line the whitespace is

Dim whitespaceLocation As Integer = currentLine.IndexOf(" ")

 

‘ move to the left until we’re at the whitespace location

vsEditor.Cursor.Move(CursorUnits.Character, whitespaceLocation)

 

‘ press delete

vsEditor.SendKeys("{DELETE}")

 

‘ get the new contents of the line

currentLine = vsEditor.Cursor.GetCurrentLineText()

 

‘ if the whitespace is gone, the test case passes

‘ otherwise, the test case fails

If currentLine.Substring(whitespaceLocation, 1) <> " " Then

LogPass()

Else

LogFailure("Failed to delete whitespace…")

End If

Got it figured out? If not, here’s a hint…

One common mistake when writing test cases is to verify against the side effects of what we’re expecting to happen. In the above code, the side effect is that the whitespace is gone from that location. In order to correctly verify that some desired action has occurred properly, the test case needs to simulate what the desired action is really doing.

Ready for the answer?

We’re testing that pressing the delete key will remove the whitespace, a single character, in front of the cursor. But let’s say delete is broken, and it deletes the whitespace and the next character. If our line of text was, “A lazy brown dog” and pressing delete deleted “ l”, the string would become “Aazy brown dog”. The second character isn’t a whitespace, yet it would pass our test case logic.

A better test case would simulate what the delete key is doing, for example

‘———————————————————————

InitScenario("Verify user can delete whitespace in middle of line")

‘———————————————————————

 

‘ put the contents of the current line into a string var

Dim currentLine As String = vsEditor.Cursor.GetCurrentLineText()

 

‘ find out where in the line the whitespace is

Dim whitespaceLocation As Integer = currentLine.IndexOf(" ")

 

‘ move to the left until we’re at the whitespace location

vsEditor.Cursor.Move(CursorUnits.Character, whitespaceLocation)

 

‘ press delete

vsEditor.SendKeys("{DELETE}")

 

‘ get the new contents of the line

Dim currentLineAfterDelete As String = vsEditor.Cursor.GetCurrentLineText()

 

‘ Remove the whitespace from the string variable

‘ and verify this is what the current line really is

If currentLineAfterDelete = currentLine.Remove(whitespaceLocation, 1) Then

LogPass()

Else

LogFailure("Failed to delete whitespace…")

End If

 

View original comments

First Karate Rank test in 10 years tomorrow night

Update 12/13/2004:  I won’t know whether i passed or not for another month.  The head sensei wasn’t there, so they videotaped the exam for him.  Not sure if that’s a good thing, since he’ll be able to rewind and watch everyone individually.  =)  I felt that i gave an good representation of my current skill level, which is really all you can ask for during an exam.  The only thing I did that frustrated me was the very first move i did, a simple jab.  My back foot slipped on something on the wooden floor.  Certain spots on the floor can get slippery.  So, it gave me an unwanted boost of adrenaline (I say unwanted, because it was the very beginning, and i had enough adrenaline in my system, and i had another 30 minutes of movements to do).  After the 15 minutes of doing basics, we sat down to let the next wave of students do basics.  My throat hurt so badly.  If i go overboard working out doing something cardio (about once in 2 years or so, this will happen to me) or run in the cold, my throat will get really tight and it hurts to breath and i cough of days.  So, i’m sitting down trying to cough into my Gi so no one can hear me.  No one did, which was good.  For kata, i felt i did a solid performance, and i was able to get my coughing under control for the time being once i started.  I did the best i could with the stationary kicks, which none of the black belt spectators commented on afterwards to me.  All the feedback i got was extremely positive from the spectators.  The only thing i was told by one of the black belt spectators was that when i do the jab, i telegraph it by dropping my hand slightly before throwing the jab.  It’s a bad habit i picked up somewhere, which i hope to break soon enough.  Even the next morning, i was still coughing, so i really went overboard trying to put on the best show possible, especially after slipping on the opening move.

This weekend my karate dojo Washington Shotokan Association had a seminar with Shihan Fuankoshi (a 9th degree black belt) and Kyle Fuankoshi (a 6th degree black belt). Their website is http://www.fska.com. For those of you non-karate people out there, Gichin Fuankoshi founded Shotokan in 1936. It was really cool to have a class taught by the direct descendants of the person who founded my style of karate. Watching Sensei Kyle do kata or basics was watching exactly how the Shotokan style is supposed to be done. It’s one thing to be told how to do something; it’s another to see exactly how it is done.

Tomorrow night (Wednesday night) I’m testing for 2nd Kyu (brown belt). I decided to start over at 3rd Kyu, so I’d have some steps to reach for before I go for Shodan (first degree black belt) next year at this time. I have to say I’m somewhat nervous, since I haven’t tested in a long, long time.  Actually, I feel like I’m testing for the first time ever. But then again, I keep telling myself to think of the exam as a way of getting detailed feedback on my current performance, and not as a pass / fail sort of thing.

After class tonight, someone told me that I didn’t breathe during my entire kata. It was the last kata of the night, and I was pretty tired, but I didn’t realize I was holding my breath the entire time. I was wondering why I had to muscle my way through the last 6 moves and why I was starting to see the white dots. Yeah, breathing while doing cardiovascular activity is kinda important =)

Wish me luck tomorrow night!