自动化测试(4) | Selenum Python WebDriver 封装

WebDriver 封装

欢迎阅读WebDriver封装讲义。本篇讲义将会重点介绍Selenium WebDriver API的封装的概念和方法,以及使用封装进行自动化测试的设计。

WebDriver API 封装

封装的概念

从之前的讲义和学习中,我们知道,WebDriver API的调用以及自动化测试,我们也初步接触了线性测试、以及模块化自动化测试和数据驱动测试,那么回顾之前的内容,我们不只是可以利用WebDriver提供的一系列的定位符以便使用元素定位方法,我们这里开始尝试封装后调用。首先,我们从封装的概念开始。

封装是一个面向对象编程的概念,是面向对象编程的核心属性,通过将代码内部实现进行密封和包装,从而简化编程。

所谓“对象”,形象地说,我们可以把它理解为一块积木。设计积木的人需要设计积木的外观与形状,还有内部的材质。堆积木的人对于内部的材质并不关心,他们只需要根据不同的外观与形状来决定堆放的位置。因此,对于开发者而言,要设计面向对象的程序,同时会是两个迥然不同的身份:设计者与使用者。

先谈谈使用者。使用者的身份,就是利用已经提供给你的所有对象,根据需求,设计出自己需要实现的程 序。就如堆积木的过程。这恰恰是面向对象编程的优势所在,那就是“对象的重用”。已经设计好的对象,可以被不同的使用者调用,这些功能既然已经实现,对于使用者而言,当然就免去了自己去设计的过程。正如堆积木那样,既然有了现成设计好的积木,使用者所要做的工作就是把这些积木最后组合起来,堆成不同的形状。WebDriver所提供的类库,就是这样的积木。那么我们以下的操作将会基于上述的定位符进行定位操作。

前面说到对象好比是一个积木,设计者需要定义好这个积木的外观和形状,也要考虑积木内部的制作,例如选用的材质,以及是空心还是实心。如果将这个积木剖开来看,实际上该对象应分为内、外两层。由于使用者只关心外部的实现,因此设计者就需要考虑,哪些实现应暴露在外,哪些实现应隐藏于内。这就体现了对象的封装的思想。

简而言之,封装就是把原始和原生的方法进行再包装。将原始的代码用心的代码包装起来,通过对新代码的调用,来使用原始的代码的过程。

封装的好处

对Selenium进行封装的好处主要有如下三个方面:

  • 使用成本低
    1. 不需要要求所有的测试工程师会熟练使用Selenium,而只需要会使用封装以后的代码
    2. 不需要对所有的测试工程师进行完整培训。也避免工作交接的成本。
    3. 测试人员使用统一的代码库
  • 维护成本低
    1. 通过封装,在代码发生大范围变化和迁移的时候,不需要维护所有代码,只需要变更封装的部分即可
    2. 维护代码不需要有大量的工程师,只需要有核心的工程师进行封装的维护即可
  • 代码安全性
    1. 对作为第三方的Selenium进行封装,是代码安全的基础。
    2. 对于任何的代码的安全隐患,必须由封装来解决,使得风险可控。
    3. 使用者并不知道封装内部的代码结构。

封装的目的

封装,最终为了实现自动化测试框架。在自动化测试领域,有一个经典的问题:“既然可以编写或者通过record & playback可以做一个脚本,那么为什么还需要自动化测试框架呢?”简而言之,就是为什么需要如此这般麻烦的设计和编写自动化测试框架,不是原本已经可以做自动化测试了么?

这个回答可以很“官方”,从维护性、重用性、安全性和成本等角度可以回答。

在这点,就好比是建造房子。在没有设计框架的基础上,我们或许可以建造一个楼房,最多也就三两层吧;但是对于一份经过完整设计的图纸,人们可以建造出高楼大厦。

封装,就是把基础的石头等建材,通过我们的个性化的方法,将地基可用而安全的搭建好。是自动化测试框架的基石。

使用封装进行自动化测试

封装示例

测试脚本:以下的脚本

    def getElement(self, selector):
        """
        to locate element by selector
        :arg
        selector should be passed by an example with "i,xxx"
        "x,//*[@id='langs']/button"
        :returns
        DOM element
        """
        if ',' not in selector:
            return self.driver.find_element_by_id(selector)
        selector_by = selector.split(',')[0]
        selector_value = selector.split(',')[1]

        if selector_by == "i" or selector_by == 'id':
            element = self.driver.find_element_by_id(selector_value)
        elif selector_by == "n" or selector_by == 'name':
            element = self.driver.find_element_by_name(selector_value)
        elif selector_by == "c" or selector_by == 'class_name':
            element = self.driver.find_element_by_class_name(selector_value)
        elif selector_by == "l" or selector_by == 'link_text':
            element = self.driver.find_element_by_link_text(selector_value)
        elif selector_by == "p" or selector_by == 'partial_link_text':
            element = self.driver.find_element_by_partial_link_text(selector_value)
        elif selector_by == "t" or selector_by == 'tag_name':
            element = self.driver.find_element_by_tag_name(selector_value)
        elif selector_by == "x" or selector_by == 'xpath':
            element = self.driver.find_element_by_xpath(selector_value)
        elif selector_by == "s" or selector_by == 'selector_selector':
            element = self.driver.find_element_by_css_selector(selector_value)
        else:
            raise NameError("Please enter a valid type of targeting elements.")

        return element
    
    def type(self, selector, text):
        """
        Operation input box.

        Usage:
        driver.type("i,el","selenium")
        """
        el = self.getElement(selector)
        el.clear()
        el.send_keys(text)

以上的代码是封装了find_element_by_的几种方法,在具体使用封装过的代码的时候,只需要简单的调用即可。

调用示例

    def login(self, userName, password):
        self.openPage(self.loginPageUrl)
        # self.driver.clearCookies()
        self.driver.implicitlyWait(5)
        self.driver.type("account", userName)
        self.driver.type("password", password)
        self.driver.click("submit")

自动化的测试代码示例

    def test_ranzhi_login(self):
        """
        测试用例:测试然之登录
        :return:
        """
        # 新建然之的页面对象
        loginPage = RanzhiSubLoginPage(self.autoDriver, self.baseUrl)

        # 利用然之的页面对象进行登录
        loginPage.login("admin", "admin")
        sleep(2)
        # 断言 是否登录成功
        self.assertEqual(loginPage.getMainPage(), self.autoDriver.getUrl(), u"登录失败")

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容