【问题标题】:Sleeping after every Selenium function call每次 Selenium 函数调用后睡觉
【发布时间】:2014-07-21 17:50:19
【问题描述】:

我想在执行 selenium 调用后等待几秒钟,以便执行自动化测试的用户可以看到屏幕上发生的情况。

我的问题是:有没有办法在每个函数调用之后等待几秒(使用隐式或显式等待或其他),这比在代码中多次编写time.sleep 更好? selenium 函数调用如下所示:

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

【问题讨论】:

    标签: python selenium python-3.x


    【解决方案1】:

    一种选择是将每个 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并且你想return来自装饰函数的东西,您需要使用raise Return(value) 而不是return value。在 Python 3.x 上,return value 可以正常工作。

    【讨论】:

    • 一条指令类似于:"driver.find_element_by_name("Account").click()"。
    • 这似乎行得通。我会尽快检查结果并在这里发表评论。尽早为所有清晰的样本和努力投票
    • @almanegra 谢谢。注意:我忘记在原始编辑中包含 Return 类的定义。我现在已经添加了。
    • 我已经测试过了,效果很好。抱歉迟到了:)
    猜你喜欢
    • 2020-12-05
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多