每次Selenium函数调用后休眠

0 投票
1 回答
1229 浏览
提问于 2025-04-18 14:08

我想在执行Selenium的操作后,等待几秒钟,这样执行自动化测试的用户就能看到屏幕上发生了什么。

我的问题是:有没有比在代码里写很多次time.sleep更好的方法,可以在每个函数调用后等待几秒钟(可以使用隐式等待、显式等待或者其他方法)?Selenium的函数调用看起来是这样的:

driver.find_element_by_name("Account").click()

1 个回答

3

一种方法是把每个selenium的调用放到自己的函数里,然后使用一个装饰器:

def wait(secs):
    def decorator(func):
        def wrapper(*args, **kwargs):
            ret = func(*args, **kwargs)
            time.sleep(secs)
            return ret
        return wrapper
    return decorator

使用方法:

@wait(5) # waits 5 seconds after running the method
def do_instruction1(...):
    return "hi"

@wait(3) # waits 3 seconds after running the method
def do_instruction2(...):
    return "there"

a = do_instruction1()
print a
b = do_instruction2()
print b

输出结果:

<5 second delay>
"hi"
<3 second delay>
"there"

如果你不想把每个操作都放在自己的函数里,你可以使用协程来实现:

import time
from functools import wraps

class Return(Exception):
    def __init__(self, value):
        self.value = value

def sleeper(func):
    """ Coroutine decorator that sleeps after every yield. 

    Any yield inside a function decorated with sleeper will
    result in a 3 second sleep after the operation being
    yielded has run.

    """
    @wraps(func)
    def wrapper(*args, **kwargs):
        def execute(gen):
            try:
                x = next(gen)
                time.sleep(3)
                while True:
                    x = gen.send(x)
                    time.sleep(3)
            except (Return, StopIteration) as e:
                return getattr(e, "value", None)
        gen = func(*args, **kwargs)
        return execute(gen)
    return wrapper

def f():
    print "should sleep"
    return "abc"

def g(val):
    print "should also sleep"
    return "%s-def" % (val,)

def h():
    print "this won't sleep"
    return "ghi"

@sleeper
def test():
    z = yield f()
    print "hey there, got %s" % (z,)
    y = yield g(z)
    print "ok: %s" % (y,)
    l = h()
    print "see %s" % (l,)
    z = yield f()
    print "done %s" % z
    raise Return("all done") # You can use return "all done" if you have Python 3.x


if __name__ == "__main__":
    final = test()
    print "final is %s" % final

输出结果:

should sleep
<3 second sleep>
hey there, got abc
should also sleep
<3 second sleep>
ok: abc-def
this won't sleep
see ghi
should sleep
<3 second sleep>
done abc
final is all done

使用这种方法,任何你用sleeper装饰的函数,在调用任何你用yield返回的函数后都会暂停一段时间。所以在你的情况下,不是调用

driver.find_element_by_name("Account").click()

而是调用

yield driver.find_element_by_name("Account").click()

唯一的限制是,你想要暂停的所有调用必须在一个用sleeper装饰的函数里面。如果你使用的是Python 2,并且想从装饰的函数返回一个值,你需要用raise Return(value)来代替return value。在Python 3.x中,return value是可以正常工作的。

撰写回答