UI自动化框架bok-choy(selenium+python+page object)使用介绍

前言

bok choy是一个开源的使用python语言,以Page Object模式封装selenium的验收测试框架。在工作中可以用它来做UI层面的自动化。为了更好地理解本文,您需要有selenium和python的基础知识。

准备工作

需要安装python和pip
使用pip安装即可。

pip install bok_choy

写Page

PO设计模式中是以页面(page)为一个单位,作为一个对象。将这个页面所做的动作作为这个页面对象的方法(比如点击某个按钮,在某个输入框输入文字等操作),在具体写用例的时候都是实例化页面对象,调用该对象的相应方法,这样写的好处是:如果某个页面进行了改版,页面元素发生了改变,对测试用例是没有影响的,只要在相应的Page object里修改相应方法就好了。
写Pages前需要分析测试场景,以测试百度搜索为例,首先需要在百度搜索页面输入关键字,并点击搜索按钮。然后页面会跳转到一个搜索结果页,我们验证结果页是否包含关键字即可。在这个场景中,我们涉及到了两个页面,一个是搜索首页,一个是搜索结果页,我们新建一个pages.py文件,见下面的代码。


  # -*- coding: utf-8 -*-
  from bok_choy.page_object import PageObject

  class BaiduSearchPage(PageObject):
      """
      Baidu search page
      """

    url = 'https://www.baidu.com/'

    def is_browser_on_page(self):
        return self.q(css='#su').is_present()

    def input_search_key(self, keyword):
        return self.q(css="#kw").fill(keyword)

    def click_search_btn(self):
        self.q(css="#su").click()

    def search(self, keyword):
        self.input_search_key(keyword)
        self.click_search_btn()
        BaiduSearchResultPage(self.browser).wait_for_page()

class BaiduSearchResultPage(PageObject):
    """
    Baidu search result page
    """
    url = None

    def is_browser_on_page(self):
        return self.q(css='h3').is_present()
    
    @property
    def search_results(self):
        return self.q(css='h3').first.text

如上述代码所示,自己写的页面对象都继承于bokchoy的PageObject,每个页面对象都必须给url赋值,还要实现is_browser_on_page方法。
url是这个页面的入口,在测试过程中,会遇到一种情况是你不关心它的url具体是多少,因为这个页面总是从别的页面点击进入的,而不是直接从浏览器输入url进入,这时,将它的url设为None即可,上例中的BaiduSearchResultPage(搜索结果页)就是这种情况。
is_browser_on_page方法,是PageObject类的抽象方法,需要在子类中具体实现。这个方法的作用主要是判断浏览器打开的是不是你要的这个页面。在百度搜索页这个实例中,为了确保搜索首页打开并加载完成了,我用了搜索按钮是否存在来判断。而对于搜索结果页,必须有测试结果在页面展示出来,才能说明这个页面完全打开了,所以用测试结果元素是否存在来判断。
bok-choy中提供两种定位方式:css和xpath,本例中使用css定位。

self.q(css='#su')

除了url和is_browser_on_page是每个页面对象都有的,其他方法需要根据具体页面上的元素和操作来增加。
BaiduSearchPage-百度搜索首页,在这个页面我们需要做的操作有1.在输入框输入文字,所以我们写了input_search_key方法;2.点击搜索按钮,所以我们写了click_search_btn方法,从方法的命名上我们也能看出来这两个方法是什么作用。一个完整的搜索动作,包含了这两个步骤,所以又写了一个search方法。页面中的各种操作方法相当于一块一块的拼图,具体想拼成什么样,根据不同测试场景可以自由地组合。目前页面中的search方法算是两个小拼图拼出的一个场景。在百度的首页,还可以点击贴吧、图片等,这些操作也可以写到这个页面对象中,以备其他测试场景使用。
BaiduSearchResultPage-搜索结果页,这个页面是在搜索页点搜索按钮之后,跳转进入的。进入这个页面后,主要是需要验证搜索结果中包含搜索关键字。因而有了search_results来返回搜索第一个结果的文字,以便于在测试中去使用。这个方法加了property装饰器,区别将在下一部分展示。

写测试用例

有了pages.py之后,就可以写用例啦,建立test_search.py文件。

# -*- coding: utf-8 -*-
import os
import unittest
from bok_choy.web_app_test import WebAppTest
from pages import BaiduSearchPage, BaiduSearchResultPage

class TestBaidu(WebAppTest):
    """
    Tests for the Baidu site.
    """
    def setUp(self):
        """
        Instantiate the page object.
        """
        super(TestBaidu, self).setUp()
        self.baidu_search_page = BaiduSearchPage(self.browser)        

    def test_page_existence(self):
        """
        Make sure that the page is accessible.
        """
        self.baidu_search_page.visit()

    def test_search(self):
        test_key = u"学堂在线"
        self.baidu_search_page.visit().search(test_key)
        self.baidu_results_page = BaiduSearchResultPage(self.browser)
        result = self.baidu_results_page.search_results
        assert test_key in result[0]

if __name__ == '__main__':
    os.environ["SELENIUM_BROWSER"] = "chrome"
    unittest.main()

bok-choy默认是使用firefox运行测试用例,它支持的浏览器有火狐、chrome、IE、safari和phantomjs。如果想要修改运行测试的浏览器,需要修改一下环境变量SELENIUM_BROWSER即可。本例中,我们将运行测试的浏览器换成了chrome。其他有效值有'firefox', 'internet explorer', 'safari'和 'phantomjs',使用非火狐浏览器记得下载相应的Webdriver,将webdriver放到与测试相同的文件夹下即可。

在测试文件中,首先需要实例化页面对象

self.baidu_search_page = BaiduSearchPage(self.browser)  

然后就可以调用该页面对象的方法

self.baidu_search_page.visit().search(test_key)

请注意,在调用操作方法的时候先调用了visit(),visit方法通过在页面对象中定义的url打开页面。在页面中做的任何操作,前提都是该页面被正确地打开了,所以每次调用都应该先调visit()。
但是,我们注意到在取搜索结果的时候并没有调用visit,代码如下:

self.baidu_results_page.search_results

这是因为在写search_results时,我们加上了装饰器property,那它就变成对象的属性了,可以直接用“点”访问到。
最后我们用assert 对测试结果进行验证。

运行测试

代码已写完,现在可以跑测试(≧≦)/啦! 运行结果如下。

testresult.png

在测试的过程中,如果测试用例没有pass,框架会自动默认在跑测试的路径下保存截图和日志,如果你想把他们保存在别的地方,可修改环境变量SCREENSHOT_DIR和SELENIUM_DRIVER_LOG_DIR。

bok-choy的基本使用就是如此,你学会了吗?想了解更多可访问官方文档(见参考文献)哦~

以上示例代码可在github查看

参考文献

http://bok-choy.readthedocs.io/en/latest/

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

推荐阅读更多精彩内容