日志

细说selenium的等待条件

 来源    2020-08-01    0  

selenium的显示等待

在进行UI自动化测试的时候,我们为了保持用例的稳定性,往往要设置显示等待,显示等待就是说明确的要等到某个元素的出现或者元素的某些条件出现,比如可点击、可见等条件,如果在规定的时间之内都没有找到,那么就会抛出Exception.

上面是我用selenium写的一个测试用例,展示了selenium中显示等待的使用方式,其中会使用到expected_conditions模块和WebDriverWait类,注意这里expected_conditions是一个py文件的文件名,也就是一个模块名,这个模块下面有很多的条件类,而我们用例中使用的title_is就是一个条件类。

WebDriverWait是一个类,这个类的作用就是根据一定的条件,不断的检查这个条件是否被满足了。WebDriverWait类只有两个方法,一个是until直到满足某个条件,另一个是until_not直到不满足某个条件。

class WebDriverWait(object):
    def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):

WebDriverWait有四个参数分别是,driver驱动, timeout超时时间, poll_frequency=POLL_FREQUENCY轮训时间,也就是去判断条件是否满足的时间间隔,默认是0.5秒, ignored_exceptions=None在等待的过程中需要忽略的异常,是一个可迭代的异常类集合,比如我们可以设置一个list,里面是[NoSuchElementException,NoSuchAttributeException,InvalidElementStateException....],默认情况下,是一个元组,只包含一个NoSuchElementException,因为只有元素出现,才能去判断条件是否满足,在不断轮训的过程中,肯定会发生NoSuchElementException,这个时候必须忽略掉这个异常,不然程序就会中断。

其中drivertimeout是毕传的位置参数,另外两个是选择传递的关键字参数,如果不传都有指定的默认值。

下面就进入我们今天的主题,selenium中的等待条件的讨论

等待条件

条件类的实现原理

selenium.webdriver.support.expected_conditions这个模块里,存放着所有的等待条件,每个条件类的结构都是一样的一个__init__构造方法和一个__call__方法。

在python中,如果想把类型的对象当做函数来使用,那么就可以给这个类实现__call__方法,如下:

class TestCase:
    def __init__(self):
        self.driver = webdriver.Chrome(executable_path="./driver/chromedriver")
        self.driver.get('http://www.baidu.com')
        # sleep(2)

    def __call__(self):
        print(self.driver.title)

if __name__ == '__main__':
    case = TestCase()
    case()

case()对象的调用,就会执行__call__方法里面的逻辑打印当前页面的标题,我们取一个selenium的实现类:

class presence_of_element_located(object):

    def __init__(self, locator):
        self.locator = locator

    def __call__(self, driver):
        return _find_element(driver, self.locator)

这个条件类的意思是判断一个元素是否已经渲染到页面当中,在使用这个条件的时候需要先实例化,传入元素的定位,然后要进行判断的时候需要对实例对象进行调用并传入driver,对实例对象进行调用的时候就会执行__call__方法里的条件判断逻辑。

WebDriverWait是如何进行条件判断的

再回到文章开头看一下我们使用显示等待的代码:

wait = WebDriverWait(self.driver, 2)
wait.until(EC.title_is('百度一下,你就知道'))

先是实例化一个WebDriverWait对象,然后再调用until方法并且传递一个条件的实例对象,until方法里就会不断的去轮训条件是否满足。

def until(self, method, message=''):
    screen = None
    stacktrace = None

    end_time = time.time() + self._timeout
    while True:
        try:
            value = method(self._driver)
            if value:
                return value
        except self._ignored_exceptions as exc:
            screen = getattr(exc, 'screen', None)
            stacktrace = getattr(exc, 'stacktrace', None)
        time.sleep(self._poll)
        if time.time() > end_time:
            break
    raise TimeoutException(message, screen, stacktrace)

method这个参数就是我们传递进来的条件的实例对象,value = method(self._driver)这里就是进行对象的调用,也就是执行了__call__方法里的逻辑。

selenium里都有哪些条件

  • title_is 判断title是否出现
  • title_contains 判断title页面标题是否包含某些字符
  • presence_of_element_located 判断某个元素是否被加载到了dom树里,但是并不代表这个元素可见
  • url_contains 判断当前url是否包含某个url
  • url_matches 判断当前url是否符合某种格式
  • url_to_be 判断当前url是否出现
  • url_changes 判断当前url是否已经发生了变化
  • visibility_of_element_located 判断某个元素是否被添加到了dom树里,且宽高都大于0
  • visibility_of 判断看某个元素是否可见
  • presence_of_all_elements_located 判断至少有一个元素存在于dom树中,返回所有定位到的元素
  • visibility_of_any_elements_located 判断至少有一个元素在页面中可见
  • visibility_of_all_elements_located 判断是否所有元素都在页面中可见
  • text_to_be_present_in_element 判断指定的元素中是否包含了预期的字符串
  • text_to_be_present_in_element_value 判断指定的元素属性值中是否包含了预期的字符串
  • frame_to_be_available_and_switch_to_it 判断iframe是否可以switch进去
  • invisibility_of_element_located 判断某个元素是否在dom中不可见
  • element_to_be_clickable 判断某个元素是否可见并且是enable的,也就是说是是否可以点击
  • staleness_of 等待某个元素从dom中删除
  • element_to_be_selected 判断某个元素是否被选中了,一般用于下拉列表中
  • element_located_to_be_selected 与上面的意思一样,只不过上面实例化的时候传入的是元素对象,这个传入的是定位
  • element_selection_state_to_be 判断某个元素的选中状态是否符合预期
  • element_located_selection_state_to_be 与上面一样,只不过传值不同而已
  • number_of_windows_to_be 判断当前窗口数是否等于预期
  • new_window_is_opened 判断是否有窗口增加
  • alert_is_present 判断页面是否有弹窗

以上就是selenium支持的所有条件。

然后就是自定义了

说了那么多条件,其实我们也可以自己实现一个条件类,

class page_is_load:
    
    def __init__(self, expected_title, expected_url):
        self.expected_title = expected_title
        self.expected_url = expected_url
    
    def __call__(self, driver):
        is_title_correct = driver.title == self.expected_title
        is_url_correct = driver.current_url == self.expected_url
        return is_title_correct and is_url_correct

上面是自己实现的一个条件类,根据页面的url和标题来判断页面是否被正确加载,

class TestCase:
    def __init__(self):
        self.driver = webdriver.Chrome(executable_path="./driver/chromedriver")
        self.driver.get('http://www.baidu.com/')
        # sleep(2)

    def __call__(self):
        print(self.driver.title)

    def test_wait(self):
        wait = WebDriverWait(self.driver, 2)
        wait.until(page_is_load("百度一下,你就知道", "http://www.baidu.com/"))

欢迎大家去 我的博客 瞅瞅,里面有更多关于测试实战的内容哦!!

相关文章
ajax – 如何让Selenium WebDriver等待一段时间?
问答我可以编写以下代码来请求WebDriver等待一段时间 new WebDriverWait(driver, 20).until(ExpectedConditions.presenceOfElement ...
1
ruby-on-rails – 如何在水豚场景中添加等待条件?
问答我正在使用capybara测试我的rails应用程序进行集成测试. 在我的应用程序中有许多Lightbox和Ajax和js调用. @javascript Scenario: I agree funct ...
2
为什么在等待条件变量时需要while循环
问答说你有这个代码 pthread_mutex_lock(&cam->video_lock); while(cam->status == WAIT_DISPLAY) // <-- ...
1
php – 如何让Mink Selenium 2驱动程序等待页面加载Behat
问答我正在从Behat 2.x系列升级到Behat 3.x系列.在之前的版本中,我可以加载Selenium 1驱动程序,该驱动程序连接到PhantomJS以执行测试.当我这样做时,我能够挂钩一个名为wai ...
1
java – 即使等待条件已经改变,AbstractQueuedSynchronizer.acquireShared也会无限期地等待
问答我写了一个使用AbstractQueuedSynchronizer的简单类.我写了一个代表"门"的类,如果打开则可以传递,如果关闭则可以阻塞.这是代码: public class ...
1
Selenium会等待JavaScript完成吗?
问答我正在使用Java / Selenium测试JavaScript API. 我在Java端发出这些命令, executor.executeScript("setName('Hello');& ...
1
Linux被动等待条件更新
问答我正在尝试创建一个模拟幼儿中心的代码.在这个中心,一个成年人可以照顾最多三个孩子.必须始终满足这一条件.成人和儿童是随机产生的过程,儿童和成人的数量在程序参数中设定.只有当里面有足够的成年人时,孩子才 ...
1
java threadump意义“等待条件”
问答我有一个应用程序的threaddump,显示3个线程如下. =============== "http-443-11" daemon prio=10 tid=0x000000004 ...
java – Jenkins无法启动selenium测试(等待创建配置文件超时)
问答jenkins无法启动硒测试(ubuntu) 错误 11:26:24.652 INFO – 已开始使用org.openqa.jetty.jetty.Server@ab50cd 11:26:24.738 ...
2
如何通过JS事件加载新页面时,使Selenium WebDriver等待页面加载
问答我正在努力自动化一个网站,该网站有许多通过JS事件加载新页面的链接.基本上,有些元素是可点击的,点击一个元素会导致一些JavaScript运行,这会导致表单被提交并路由到新页面. 现在,如果这些只是标 ...
1
iphone – iOS中的多线程 – 如何强制线程等待条件?
问答我正在创建一个从数据库中获取一组结果的应用程序 – 我使用MBProgressHUD来显示带动画的查询进度.我使用的方法在另一个线程中执行方法时调用动画,一旦完成,它就会隐藏动画.我的问题是,在致电: ...
1
selenium – 流利等待和WebDriver等待 – 差异
问答我在使用Selenium的代码中看到了FluentWait和WebDriverWait. FluentWait使用轮询技术,即它将针对特定WebElement每隔固定间隔轮询一次.我想知道WebDri ...
1
Capybara / selenium:等待元素隐藏
问答我需要等待加载条(div #loading)在黄瓜步骤中消失(变为display:none).我希望以下内容可以解决问题 find('#loading').should_not be_visible ...
2
Selenium Python等待文本出现在元素错误显示中需要3个参数2
问答我正在使用WebdriverWait等待一些文本出现在网页上的元素中.我正在使用Selenium和Python.我的语法不正确. 我收到错误: TypeError:init()正好接受3个参数(给定2 ...
1
c – 杀死等待条件变量的pthread
问答我有一个pthread使用pthread_cond_wait等待条件变量.它正在等待来自另一个线程填充的队列结构的数据.我想杀死这个帖子,最好没有pthread_kill.在Linux和WinPthr ...
2
Pthread和等待条件
问答我在学习pthread和等待条件.至于我可以告诉一个典型的等待线程是这样的: pthread_mutex_lock(&m); while(!condition) pthread_cond_wa ...
java – 为什么等待条件释放锁但信号没有?
问答我编写下面的代码来测试线程在等待Condition对象时何时处于唤醒状态. >但是我发现在调用signal()后我必须解锁.此方法不会释放锁定,而await()将释放此锁定. 这是从Condit ...
1
c – 线程休眠VS等待条件
问答编辑: 这里的要点是知道实现等待循环的更有效的解决方案,该循环在每次迭代中轮询一个条件.通过有效,我的意思是"有效的CPU调度". 我知道我的代码中使用的等待条件不是"w ...
1
C 11线程:等待条件变量的多个线程
问答我目前正在研究一个模拟扩展的Producer-Worker模型的问题.在这个问题上,有3个工人和3个工具可供使用,而对于工人来说,他们需要2个工具(和材料,但那些是无关紧要的).如果保险库中有> ...
2
selenium – OperaDriver等待歌剧发射器超时
问答我正在尝试将OperaDriver for Java(版本0.11)集成到我的测试套件中.这是代码片段: DesiredCapabilities operaCapabilities = Desired ...
1