views:

261

answers:

2

Hi,

I am using Marathon 2.0b4 to automate tests for an application.

A shortcoming of wait_p, one of the script elements provided by Marathon, is that its default timeout is hardcoded to be 60 seconds. I needed a larger timeout due to the long loading times in my application.
[I considered patching Marathon, but didn't want to maintain parallel versions etc., so figured that a better solution would actually be a workaround at the test script level.]

def wait_p_long(times, compID_name, ppty_name, ppty_value, compID_cell=None):
    from marathon.playback import *
    """Wrapper around wait_p which takes exactly the same parameters as wait_p,
    except that an extra first parameter is used to specify the number of times
    wait_p is called"""
    for i in range(1, times):
     try:
      wait_p(compID_name, ppty_name, ppty_value, compID_cell)
     except:
      if (i < times):
       print "wait_p failed, trying again"
      else:
       raise

wait_p is short for "wait property", and it takes in 3 compulsory and one optional argument (the argument's names are rather self-explanatory), and what it does is wait for a speicifed property of the specified component to be equals to the specified value.

What the above method (Jython) intends to do is take one extra parameter, times, which specifies the number of times to attempt wait_p, suppressing the exceptions up until the last try.

However, this method isn't working for me, and I am afraid there might be some syntactical or logical error somewhere in there. Any comments from python / jython gurus out there?

Thanks!

+2  A: 

Two things:

  • range(1, times) should almost certainly be range(times); what you wrote is equivalent to for (int i=1; i < times; i++)
  • Because of what I just explained, if (i < times) will always be True in your except block

If this doesn't help with your problem, please describe how exactly your results are differing from what you expect.

The results would look something like:

def wait_p_long(times, compID_name, ppty_name, ppty_value, compID_cell=None):
    from marathon.playback import *
    """
    Wrapper around wait_p which takes exactly the same parameters as wait_p,
    except that an extra first parameter is used to specify the number of times
    wait_p is called.
    """
    for i in range(times):
        try:
            wait_p(compID_name, ppty_name, ppty_value, compID_cell)
        except:
            if i == times - 1:
                raise
            else:
                print "wait_p failed, trying again"
Hank Gay
I feel like such a n00b now! Just to clarify your suggestions: 1) Change `range(1, times)` to `range(times)` and 2) Change `if (i < times)` to `if (i < (times -1))`; in order to capture the last occurence of the for loop?
bguiz
+2  A: 

@Hank's explanation is correct, but I would suggest a different approach:

def wait_p_long(times, compID_name, ppty_name, ppty_value, compID_cell=None):
    from marathon.playback import *
    for i in range(times-1):
        try:
                wait_p(compID_name, ppty_name, ppty_value, compID_cell)
                break
        except:
                pass
     else:  # try one last time...!
         wait_p(compID_name, ppty_name, ppty_value, compID_cell)

It feels conceptually simpler to me (though the textual repetition of the wait_p call is a minus, it avoids checks on i to do something different "the last time around"). The else clause on a loop executes if no break ever executed in the loop, btw.

Alex Martelli
Thank Alex, but I think I prefer Hank's solution. +1 for you still!
bguiz
OK, but that solution as currently coded is buggy -- the test `if (i == times):`, besides the redundant parentheses, will never be satisfied, so the `raise` will never happen. The point is not this specific bug, which can of course be fixed: it's that the kind of coding you and Hank are using is **bug-prone** -- it's just too easy to have an off-by-one bug. Coding it the way I suggest (and thanks for the +1, btw) is just less bug-prone -- which is why you _should_ prefer it;-). Give it a few decades, and you'll learn which idioms and approaches are less bug-prone **and** will prefer them!-)
Alex Martelli
@Alex thanks for pointing out the bug; I'll fix that immediately. For the record, I like your approach more but was trying to get bguiz's example to work with minimal conceptual changes.
Hank Gay