Upcoming stb-tester features: Composable API
22 Sep 2014.
wait_for_match function works well enough, but what if you want
to wait for a UI element to disappear? Or when you want to check that 2
different UI elements are present in the same frame? Or when you just want to
know if the element is present or not, without raising an exception? An
addition to stb-tester’s Python API, due in stb-tester 0.21, will make this
Stb-tester.com Ltd is currently working with a global TV manufacturer to provide testing services for their latest development project. To support this work we have developed a lot of exciting new features in stb-tester. We’ve been far too busy to release these features officially, but over the next months you should see them making their way to an stb-tester release.
wait_for_match really does 3 things:
- It searches for a template image
- …over and over, pulling new frames from the system under test, until it finds the template image
- …or raises an exception if it doesn’t find a match within a certain time.
Sometimes you want all three behaviours, but sometimes you only want the first
one. The new
stbt.match does just that – it searches for an image in a
if stbt.match("template.png"): do_something() else: do_something_else()
Other times you want the first and second behaviours (matching repeatedly until finding a match or timing out, but without raising an exception):
if wait_until(lambda: stbt.match("template.png")): do_something() else: do_something_else()
(See below for an implementation of
And yet other times you want the first and third behaviours:
If you want all three behaviours, you don’t even need
assert wait_until(lambda: stbt.match("template.png"))
More complex examples
Check that a UI element has disappeared after you dispelled it (just negate the
assert wait_until(lambda: not stbt.match("template.png"))
Check that 2 different templates are present at the same time in the same frame:
f = stbt.get_frame() assert (stbt.match("template1.png", frame=f) and stbt.match("template2.png", frame=f))
You can get as complex as you like while keeping quite good readability. Here’s an example from our own HbbTV test suite:
def find_selection(): # ...image processing details elided... stbt.press(Key.MENU) selection = wait_until(find_selection) assert selection print stbt.ocr(selection.region)
wait_untilis a helper function that can be implemented without using any stb-tester APIs. It takes a timeout in seconds and a function
f; it calls
freturns something truthy or until the timeout is reached.
def wait_until(f, timeout_secs=10): expiry_time = time.time() + timeout_secs while True: val = f() if val: return val # truthy if time.time() > expiry_time: return val # falsy
(We place the above code snippet in the public domain.)
wait_until is now provided by the
API, as of stb-tester v22. See the Python API
assert throw away too much information? The stb-tester results
will say “AssertionError” instead of the MatchTimeout information that the
wait_for_match logs (including, most usefully, the name of the
template image that failed to match).
You could write your test script like this:
assert stbt.match("menu.png"), "Failed to match menu.png"
…but we’re not going to ask you to stoop to that level of boilerplate and repetition! We’re working on a new, smarter test runner that solves this problem. But that will have to wait until the next blog post.
Comments? Join the discussion on the project mailing list.