Monthly Archives: May 2013

Friday Babble, May 31, 2013

Every Friday, some babble and somewhat stream-of-conscious thoughts…

UAT and QA do not mix

I think UAT is great. It adds a whole new perspective to the project. It adds much more of the (non-technical) user perspective to testing. However, it is definitely not the same as QA, not the same approach and definitely should not be an added phase after QA that affects development. Rather, the stakeholders involved in “UAT” need to have a say earlier on in the process, need to look at the documents produced by QA earlier in the project, clearly communicate and guide during the early process to dev and QA so that UAT is simply a brushstroke after QA is done.

Sleep/pause/waits are for ninnies

In my opinion, if you use a time/sleep/pause/wait in your automated script, something is wrong with your code. Pause. (get it? Street lingo play-on-words). If you have an ajax request in the midst of loading, you need to account for it. If you have elements loading to populate a table, wait for an indication that the table is loaded. A script riddled with sleeps/waits smells like lazy programmer to me. Save it for debugging or some other purpose. (re: “ninnies”, an old co-worker of mine used that word. He used to say “IDE’s are for ninnies…” More about that later. I disagree, but…)

LinkedIn forums are very revealing

There’s some pretty revealing questions asked on LinkedIn forums by some “QA Analysts”. Word of advice, if you are going to ask “How do I write a test plan” or “What is the difference between a defect and a feature request?” on a site that is intended to help you get employment, please use an alias. Should be obvious… right??

TINSTAAFL and outsourcing

TINSTAAFL = There Is No Such Thing As A Free Lunch. Outsourcing = Free Lunch. Yeah. No such thing. Don’t get fooled by the cheap price. May be obvious in today’s world of startups, but come prepared with a designer, a good Requirements writer/gatherer, a good tech requirements writer and most importantly, a GOOD QA ANALYST! 😉 In all fairness, they don’t read minds, and they are superb at following directions, but can’t follow directions they don’t have… You gotta spend money to get “money”…

Happy Friday and let the weekend free-time on-the-side hacking/programming/research begin!!

My adventures with *args and **kwargs in Python

The Protoss of Python (Warning: Starcraft References ahead!)

I first really truly came face-to-face with *args and **kwargs when working on a project where we were writing automated tests and were attempting to write our own Python Decorators on top of currently existing test cases to seamlessly be able to create a classification to specify whether to run them or not on the go. At the time, I admit, I didn’t really understand them fully, mostly I think because the concept of Decorators themselves was a bit new to me and the difficulty of grasping these overshadowed the realization of how easy understanding the usage of *args and **kwargs were.

Recently, I reunited with *args and **kwargs and have to say the concept of these are pretty easy to grasp. Really easy. I really like to compare them with the Protoss race in Starcraft. Easy to use and powerful, but so easy to OVERUSE and resort to certain-to-fail fallback strategies due to the deceiving ease of implementing. But with the right strategy and planning and full knowledge of these Pythonic creatures, they can definitely be the winner in your project.

What are you wearing? (Basic Function parameters)

I think, in this case, examples are probably the best way of describing WHAT they are.

First, here is a simple Python function/method that accepts items of clothing and spits out (returns) a list that comprises of the person’s outfit.

def outfit(self, socks_color, shoes_color, pants_color, shirt_color):
    return 'You are wearing %s socks, %s shoes, %s pants, and a %s shirt' % (socks_color, shoes_color, pants_color, shirt_color)

If you call this function with the following:

print outfit('grey','black', 'red', 'blue')

the output will be

>>>You are wearing grey socks, black shoes, red pants, and a blue shirt

Accessorize! (Optional Function parameters)

Some people (*ahem myself) are fashionably challenged and only wear a shirt, jeans, socks and shoes, but some others like to pretty themselves up. So we should let people wear a necklace or watch in this function.

The new function will be:

def outfit(self, socks_color, shoes_color, pants_color, shirt_color, accessory=None):
    #if accessory = None
    if not accessory:
        return 'You are wearing %s socks, %s shoes, %s pants, and a %s shirt' % (socks_color, shoes_color, pants_color, shirt_color)
    else:
        return 'You are wearing %s socks, %s shoes, %s pants, and a %s shirt and a nice %s' % (socks_color, shoes_color, pants_color, shirt_color, accessory)

and call it with

print outfit('grey','black', 'red', 'blue', 'watch')

which will produce…

>>>You are wearing grey socks, black shoes, red pants, and a blue shirt and a nice watch

GQ!!!

The beauty of this signature is that you can either include or exclude “watch” into your function call parameters and the function (assuming it’s designed robustly) should be able to handle either case.

So, if you exclude the watch, as such:

print outfit('grey','black', 'red', 'blue')

you will get

>>>You are wearing grey socks, black shoes, red pants, and a blue shirt

Fashion Plate! (*args)

I’m not sure how I got from Starcraft to Fashion and Accessories, but we plug on!

Some people like to add on watches, sunglasses, pinky rings (FUHGETTABOUTIT) and earrings. Whoa, that’s a lot of accessories. But only one parameter for accessories! And with so many people dressing up (that’s what makes Humans so special and unique) we have to be able to accomodate them! Or for Halloween, maybe someone will come dressed with a Freddy Krueger mask on! Or maybe Freddy himself!!

So, for Freddy’s amazing outfit of brown socks, black shoes, brown pants, and red shirt, along with his claws, amazing signature hat, and let’s say he was going for some gold bling today in honor of his 50th Halloween, we’d love to pass this along:

>>>print outfit('brown', 'black', 'brown', 'red' 'claws', 'hat', 'bling-bling')

but remember, we only had ONE optional argument:

def outfit(self, socks_color, shoes_color, pants_color, shirt_color, accessory=None):
    #if accessory = None
    if not accessory:
        return 'You are wearing %s socks, %s shoes, %s pants, and a %s shirt' % (socks_color, shoes_color, pants_color, shirt_color)
    else:
        return 'You are wearing %s socks, %s shoes, %s pants, and a %s shirt and a nice %s' % (socks_color, shoes_color, pants_color, shirt_color, accessory)

so we would for sure get this exception:

>>> print outfit('brown', 'black', 'brown', 'red', 'claws', 'hat', 'bling-bling')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: outfit() takes at most 6 arguments (7 given)
>>>

Now we use our magical *args… (changed method a bit for simplicity)

def outfit(self, socks_color, shoes_color, pants_color, shirt_color, *args):
   return'%s, %s, %s, %s, %s' % (socks_color, shoes_color, pants_color, shirt_color, args)

and once again pass in the following items in Freddie’s ensemble… and…

>>> print outfit('brown', 'black', 'brown', 'red', 'claws', 'hat', 'bling-bling')
black, brown, red, claws, ('hat', 'bling-bling')
>>>

Notice the (‘hat’, ‘bling-bling’). Looks like a tuple! (feel free to confirm with the following:

def outfit(self, socks_color, shoes_color, pants_color, shirt_color, *args):
   print type(args)
>>> print outfit('brown', 'black', 'brown', 'red', 'claws', 'hat', 'bling-bling')
<type 'tuple'>
>>>

Wow! Looks like you can add any number of accessories (fo’ shizzle!) and this function still would accept all your bling bling!

Of course you need to prettify your usage of your *args

def outfit(self, socks_color, shoes_color, pants_color, shirt_color, *args):
   return'%s, %s, %s, %s, %s' % (socks_color, shoes_color, pants_color, shirt_color, args)
>>> print outfit('brown', 'black', 'brown', 'red', 'claws', 'hat', 'bling-bling', 'necklace', 'earrings', 'gold shoes', 'cracka-lacking pinky ring', 'chest hair exposed')
black, brown, red, claws, ('hat', 'bling-bling', 'necklace', 'earrings', 'gold shoes', 'cracka-lacking pinky ring', 'chest hair exposed')
>>>

Now that’s a SCARY Freddie Krueger.

Let’s also make use of the tuple and prettify it a bit.

def outfit(self, socks_color, shoes_color, pants_color, shirt_color, *args):
   print 'Looks like you have %s accessories' % len(args)
   outfit = ''
   outfit += 'You are wearing %s socks, %s shoes, %s pants, %s shirt. ' % (socks_color, shoes_color, pants_color, shirt_color)
   if len(args):
      outfit += 'You also have some nice accessories! I dig your '
      for item in args:
         outfit += '%s, ' % (item)
      outfit += 'outfit. Now dont haunt my dreams, Freddie!'
   return outfit
>>> print outfit('brown', 'black', 'brown', 'red', 'claws', 'hat', 'bling-bling', 'necklace', 'earrings', 'gold shoes', 'cracka-lacking pinky ring', 'chest hair exposed')
Looks like you have 7 accessories
You are wearing black socks, brown shoes, red pants, claws shirt. You also have some nice accessories! I dig your hat, bling-bling, necklace, earrings, gold shoes, cracka-lacking pinky ring, chest hair exposed, outfit. Now dont haunt my dreams, Freddie!
>>>

 Freddie is mad!

Now one thing I can think that may go wrong. Let’s modify the outfit method a bit (make it a little less lengthy)

def outfit(pants_color, *args):
   print args
   outfit = ''
   outfit += 'Nice outfit Freddie! You are wearing %s pants. ' % (pants_color)
   if len(args):
       outfit += 'Looks like you also have some %s underwear and a %s shirt' % (args[0], args[1])
   return outfit

Which is fine if you pass in the following:

>>> print outfit('black', 'pink', 'purple')
('pink', 'purple')
Nice outfit Freddie! You are wearing black pants. Looks like you also have some pink underwear and a purple shirt
>>>

Hey, a gentleman’s underwear color is his own business. However, the crux of the *args is that you need to make sure the order of arguments passed in is correct if you designed the method with the order of the arguments in mind. Quick simple example of what can go “wrong”:

Same function:

def outfit(pants_color, *args):
   print args
   outfit = ''
   outfit += 'Nice outfit Freddie! You are wearing %s pants. ' % (pants_color)
   if len(args):
       outfit += 'Looks like you also have some %s underwear and a %s shirt' % (args[0], args[1])
   return outfit

And let’s switch up the method call:

>>> print outfit('black', 'purple', 'pink')
('purple', 'pink')
Nice outfit Freddie! You are wearing black pants. Looks like you also have some purple underwear and a pink shirt
>>>

WHOA! Now you gave Freddie a pink shirt!!! He’s not happy! He has no issue with the color pink in and of itself, but it’s definitely less scary!! (ok a bit over the top, but see the complications?) Better not sleep (remember, he haunts your dreams) and read the rest of this blog entry instead!!

Some quick notes:

*args does not need to be your argument name. You can use *accessories, *bling, *yoyo, etc. The key part is the * (asterisk). Also, you should keep it at the end of the function signature.

Also note, on the example just above, the number of expected arbitrary (“extra”) arguments is only 2 for example purposes. If you plan to regularly use arbitrary (*arg) arguments, you should account for the fact that it is possible to pass an arbitrary number of arguments into the function.

Now onward.

**KWARGS = KeyWord ARGumentS

Hopefully this is becoming pretty clear now what **kwargs are/will be. Same concept as *args, except in the form of key/value format. A tiny bit more controlled.

Thus, using our previous example, the order doesn’t matter, and the method signature is still arbitrary to some degree. The method must still be written robustly enough to expect the correct arguments and handle it correctly if arguments differ then expected. Perhaps the best illustration is a simple example.

def outfit(pants_color, **kwargs):
   print kwargs
   outfit = ''
   outfit += 'Nice outfit Freddie! You are wearing %s pants. ' % (pants_color)
   if len(kwargs):
       outfit += 'Looks like you also have some %s underwear and a %s shirt' % (kwargs['underwear_color'],kwargs['shirt_color'])
   return outfit

Note the

       outfit += 'Looks like you also have some %s underwear and a %s shirt' % (underwear_color, shirt_color)

in the above.

Now, we pass in the arguments differently when calling this method.

>>> print outfit('red', shirt_color="red", underwear_color="polka-dot pink")
{'underwear_color': 'polka-dot pink', 'shirt_color': 'red'}
Nice outfit Freddie! You are wearing red pants. Looks like you also have some polka-dot pink underwear and a red shirt
>>>

Note that we passed in the underwear_color and shirt_color in a different order, yet, since we are relying on “keywords” to reference the expected value we need, order should not matter.

Freddie is happy you didn’t mix up his underwear color.

You can also pass in dictionaries as arguments. This is called unpacking an argument list.

def outfit(pants_color, underwear_color='red', shirt_color='red'):
   outfit = ''
   outfit += 'Nice outfit Freddie! You are wearing %s pants. ' % (pants_color)
   outfit += 'Looks like you also have some %s underwear and a %s shirt' % (underwear_color,shirt_color)
   return outfit
>>> new_dictionary = {'pants_color':'not-red', 'underwear_color':'not-red-underwear', 'shirt_color':'not-red-shirt'}
>>> print outfit(**new_dictionary)
Nice outfit Freddie! You are wearing not-red pants. Looks like you also have some not-red-underwear underwear and a not-red-shirt shirt
>>>

Note the “**” before the dictionary. This is a special symbol within your function call that designates that that dictionary should be passed as an argument. Of course, you need to be sure that the arguments (keys) match.

Conclusion/Wrap-up

So hopefully, this makes *args and *kwargs somewhat easier to comprehend. Once you do understand them, they are really easy to (over)use.

They are most commonly used in Python Decorators, and in functions that require a lot of arguments/settings (such as a DB connection string).

Again, do not overuse these. Best Practice dictates that your method definition is tight and well-defined to prevent undesired input from being received by the method during runtime.

But keep *args and **kwargs in mind when developing.

Comment below with any questions or if you need clarity on these. I may expound on this further in a future blog post.

Debugging the iPhone Safari browser, html, and css on the fly

Lightweight Browsers = Lightweight Tools

Testing applications on mobile browsers has always been interesting to me. It goes without saying that testing solely on desktop html browsers with a mobile user agent request header is not sufficient when testing mobile applications. Too many actions cannot be replicated on a browser, such as swiping, pinching, landscape vs. portrait orientation, specific screen specifications and resolution, phone call interruption, text message interruption, push alerts, loss of service etc.

However, with the desktop browser comes the myriad of extensions and tools that is essential for good website testing. This includes Firebug, Chrome Developer Tools, and various other plugins and add-ons that check everything from font size to request header parameters to image size. On most mobile devices themselves, however, there just isn’t that many tools such as these. I guess their intent is to keep the browser lightweight and limited resources free.

(NOTE: same as above also goes for virtual devices and emulators. Some are advanced nowadays, but I can come up with quite a few issues that will not be caught by emulators.)

Break away from the jailbreak

Is there a way to obtain browser jscript/html/css debugging functionality such as that inherent in the tools just mentioned? Of course the easy answer to access the source itself on the fly is “jailbreak” or “root” the phone. Ugh. As a legitimate Quality Assurance Analyst, nothing is more annoying and a sign of a newbie than to hear that “solution.” To me, that is definitely giving up and if jailbroken, definitely not a legitimate control test device. That’s akin to, in automation, when you cannot “click a certain drop-down” to hacking out a javascript function to “drop it for you.” That’s not what the user does, and immediately breaks away from the model of QA Automation, which is to imitate the user as much as possible.

When jail-breaking or rooting a phone, you are compromising the designed functionality of the Operating System, and testing on a now non-standard device. Even if you are now able to access functionality of the browser, who is to say that any defects you find, or DON’T find are replicable on someone else’s standard non-jail-broken device. Even if there is no one solution for all devices, please do not root the phone. There are solutions, you just need to be a little resourceful. But I digress slightly.

The Safari Web Inspector

On a recent project I was on, there was a menu header/footer that, per requirements, could not cover 3 lines per the requirements. However in our required device matrix, an older phone, with a smaller screen width was stubbornly wrapping over 3 lines. This code base, annoyingly, takes approximately 30 minutes to push to a test server so trial and error was out of the question. Of course, locally, we were not able to see the issue. I figured we needed a tool with capabilities such as Firebug so we could shimmy around with the css styles and see if decreasing font size, or spacing would solve the situation on the suspect device, while maintaining visual integrity on the previously passing devices, all while without having to do a trial and error on x number of successive builds.

Our developer came up with reasonable design solutions that worked on the trouble-making device, such as smaller font, smaller padding between the menu divider (in this case “|”) etc. Since there is a shared css file, we needed to figure out if any of these solutions would be feasible on the iPhone Safari browsers. Enter the Safari Web Inspector. Built into Safari and Mobile Safari, I was able to, like Firebug and Desktop browsers, navigate to the troublesome pages, and after they loaded and rendered, directly edit their css and html, and get a realistic idea of how these changes would appear when implemented in the source code.

Turns out, these changes were not to be for the iPhone and we had to abandon the requirement for this particular device, but I did save the team at least an hour of making changes, pushing to test, testing on all devices, and most likely, another hour to revert these changes, or try other variations in the source code before pushing it to test yet again.

Setting up the Safari Web Inspector for Mobile Safari

Requirements:

  • Any device (from Apple of course) running iOS 6 (or greater, if this is read in the future)
  • USB cable
  • Safari 6 (or greater)
  • Mac OSX Lion – 10.7.4 (or greater)

Steps:

1. In Safari, go to Preferences –> Advanced –> Select “Show Develop menu in menu bar”
2. On your iPhone, go to Settings –> Safari –> Advanced –> Turn “ON” “Web Inspector”
3. Go to your iPhone and open up your Safari browser
4. From Safari, go to Develop –> [User’s iPhone] –> [tab name on iphone safari browser]
safari_browser_debug_menu_demo

 

 

 

 

 

 

 

 

 

 

 

You should now be able to see the Safari Web Inspector for the mobile Safari instance on your iphone and be able to directly edit, view, and change css and html elements and values in real time.

safari_browser_web_inspector