<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
behave是python語言的行為驅動開發,全稱:Behavior-driven development,簡稱BDD。
BDD框架
BDD即行為驅動開發(Behavior Driven Development),其特點為:
它是一種敏捷軟體開發技術,它鼓勵軟體專案中的開發人員、QA和非技術或業務參與者之間進行共同作業。
python behave的官方網址:
https://behave.readthedocs.io/en/latest/gherkin.html
最初由Dan North命名,並於2009年對BDD給出瞭如下定義:
“BDD是第二代、由外而內、基於拉動、多利益相關者、多規模、高度自動化、敏捷的方法。
它描述了一個與定義明確的輸出互動的迴圈,從而交付了重要的工作、測試軟體。”
BDD並不會描述或定義軟體怎麼做,而是能做了什麼。最終通過python程式碼進行驗證。
首先用pycharm建立專案Python-Behave,python環境選擇Virtualenv,接著安裝behave包。
在專案Python-Behave下建立一個名為“features”的目錄(這個目錄名稱是隨意的),可以在這個目錄下定義所有behave的檔案結構。
在features目錄下建立一個“.feature”檔案,這是一種叫作“Gherkin”的語言。它對非技術人員比較友好,可以使用自然語言編寫。
“.feature”檔案有兩個用途:檔案和自動化測試。一句話,在“.feature”裡編寫測試場景。
很多文章提到Gherkin語言必須用pycharm專業版才能編寫,但是我親測用pycharm社群版也是可以編寫的。
“.feature”檔案的結構:
主體由多個場景Scenario組成,可以選用Background和tag進行約束。
feature檔案的一個基本的結構為:
Feature: feature name Scenario: some scenario Given some condition When some operation Then some result is expected
如果有多個測試場景呢,就再加一個Scenario。如果Scenario下的Given/When/Then有多個呢?
可以用And或But表示。
所以
Scenario: Multiple Givens Given one thing Given another thing Given yet another thing When I open my eyes Then I see something Then I don't see something else
也可以這樣寫作
Scenario: Multiple Givens Given one thing And another thing And yet another thing When I open my eyes Then I see something But I don't see something else
這種方式閱讀會更流暢
當然,上面只是一個簡單的feature結構,更復雜一點的,比如說這樣:
@tags @tag Feature: feature name description further description Background: some requirement of this test Given some setup condition And some other setup action Scenario: some scenario Given some condition When some action is taken Then some result is expected. Scenario: some other scenario Given some other condition When some action is taken Then some other result is expected. Scenario: ...
Background由一系列類似於Scenario的步驟組成,它的目的是為Scenario新增上下文,在Scenario執行之前執行Background,用於設定Scenario的前提條件。
Scenario由一系列步驟組成,它描述了Feature的一種場景。如果一種場景有多種情況呢?
比如登入這個Scenario,不同的登入名和密碼,登入的結果不同。這種情況可以不需要寫多個Scenario描述,可以使用Scenario Outline和Examples來完成。
Scenario Outline: Blenders Given I put <thing> in a blender, when I switch the blender on then it should transform into <other thing> Examples: Amphibians | thing | other thing | | Red Tree Frog | mush | Examples: Consumer Electronics | thing | other thing | | iPhone | toxic waste | | Galaxy Nexus | toxic waste |
在上面這個例子中,用Scenario Outline描述“Blenders”場景,用多個Examples表示場景的多種型別,每個Examples下可以包含多種情況。不同情況的列舉在Scenario Outline用符號“<key>”表示,在Examples中用key列舉
Scenario由一系列步驟組成,步驟由關鍵字“Given”、“When”、“Then”、“And”、“But”為開頭。Python Behave實際執行的也是這些步驟。
具體實現是通過此專案下的steps目錄裡的“.py”檔案實現所有的Scenario的步驟。這裡要注意,steps目錄名是確定的不能改變的,但是裡面的py檔名是隨意的。
python behave專案的執行方式也並不是通過執行steps目錄裡的py檔案,而是通過命名behave呼叫“.feature”檔案,對映到py檔案裡的步驟下的函數,執行這些函數。
步驟描述要儘量簡潔,但有時會附帶一些文字text或表格table。如果python程式碼需要使用這些text或table,則可以通過存取屬性“context.text”或”context.table“來使用。
Text:
Scenario: some scenario Given a sample text loaded into the frobulator """ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. """ When we activate the frobulator Then we will find it similar to English
Table:
Scenario: some scenario Given a set of specific users | name | department | | Barry | Beer Cans | | Pudey | Silly Walks | | Two-Lumps | Silly Walks | When we count the number of people in each department Then we will find two people in "Silly Walks" But we will find one person in "Beer Cans"
Python中存取:
@given('a set of specific users') def step_impl(context): for row in context.table: model.add_user(name=row['name'], department=row['department'])
這個表格在python中是這樣的資料型別:
[{"name":"Barry", "department":"Beer Cans"},{"name":"Pudey", "department":"Silly Walks"},{"name":"Two-Lumps", "department":"Silly Walks"}]
認真體會下!!!
Tags:
tags用於標記Feature、Scenario或Scenario Outlook,可以選擇性的只執行被標記的。
例如:
Feature: Fight or flight In order to increase the ninja survival rate, As a ninja commander I want my ninjas to decide whether to take on an opponent based on their skill levels @slow Scenario: Weaker opponent Given the ninja has a third level black-belt When attacked by a samurai Then the ninja should engage the opponent Scenario: Stronger opponent Given the ninja has a third level black-belt When attacked by Chuck Norris Then the ninja should run for his life
如果只想執行Scenario: Weaker opponent,可以對它進行標記為@slow,然後執行“behave --tags=slow”。
如果想執行除標記@slow外的其他場景,可以執行“behave --tags=“not slow””。
組合使用tags標籤:
–tags=“wip or slow”,選擇所有標記為wip或slow的case
–tags=“wip and slow”,選擇所有標記為wip和slow的case
以上講的是如何用“.feature”檔案編寫所有測試場景。雖然是通過命令behave xxx.feature觸發,但實際的執行操作是在steps目錄下的“.py”實現。
所以,要如何把“.feature”裡的所有步驟對映到“.py”中,還必須按照順序不能出錯,這就成為了一個關鍵。
假設給定一個Senario:
Scenario: Search for an account Given I search for a valid account Then I will see the account details
記住,只對所有的步驟按順序實現,並不會對Scenario進行對映。
在python中實現如下:
@given('I search for a valid account') def step_impl(context): context.browser.get('http://localhost:8000/index') form = get_element(context.browser, tag='form') get_element(form, name="msisdn").send_keys('61415551234') form.submit() @then('I will see the account details') def step_impl(context): elements = find_elements(context.browser, id='no-account') eq_(elements, [], 'account not found') h = get_element(context.browser, id='account-head') ok_(h.text.startswith("Account 61415551234"), 'Heading %r has wrong text' % h.text)
按照“.feature”中的步驟的順序,將步驟的前面的關鍵字,在python中用裝飾器匹配(@give、@when、@then),()裡面是步驟描述。
如果是And或But,在python中用它們被重新命名以前的關鍵字。也就是說,在python中,不可能有@and或@but。
然後在裝飾器下方定義函數,函數名隨意。函數體就是步驟的具體實現。
如果你想在某個步驟裡執行另一個步驟,只需要用context物件呼叫execute_steps()函數,裡面傳入被呼叫步驟。
@when('I do the same thing as before') def step_impl(context): context.execute_steps(''' when I press the big red button and I duck ''')
如果你想把“.feature”的步驟上的資訊傳遞到“.py”中,可以在py檔案中用中括號加關鍵字表示“{key}”。
比如存取百度首頁:
Scenario: 存取百度網頁 Given: 開啟網頁 When: 輸入網址www.baidu.com Then:顯示百度首頁
關於其中輸入百度網址,在python中就可以這樣實現:
@when(輸入網址{baidu}) def step_imp1(context, baidu): context.driver.get(baidu)
Context:
聰明的你一定注意到了,在py檔案中每個步驟下的函數內第一個引數是context,它是Feature或Scenario的範例化,可以用來傳遞資訊。
如何傳遞呢,這裡我們暫且按下不表,先思考一個問題。
如果我有一個場景,開啟百度網頁,輸入關鍵字搜尋,然後檢視搜尋結果。
在feature檔案中如何描述,這個我們應該已經學會了。在py檔案中如何實現,我們也不陌生了。
Scenario: 開啟百度網頁並輸入關鍵字 Given: 開啟百度網頁http://www.baidu.com When: 輸入關鍵字大美女 Then:驗證返回的搜尋結果標題是大美女_百度搜尋
@given(開啟百度網頁{baidu}) def step_imp1(context, baidu): context.driver.get(baidu) @when(輸入關鍵字{keyword}) def step_imp1(context, keyword): context.driver.find_element_by_xpath('//*[@id="kw"]').send_keys(keyword) ...
後面我就不寫了。現在只看given的步驟,你應該就能發現問題,context.driver哪來的,從已知的上下文中並沒有相關資訊。
如果你再仔細的思考一下,就會發現這裡少了一步,我們在開啟百度網站前,是不是應該先開啟瀏覽器,然後才是輸入百度網址。
如果你有多個關於網頁搜尋的場景,你是不是應該每次執行Scenario前都要開啟瀏覽器,執行完畢關閉瀏覽器。這個操作類似於python unittester中的setup()和teardown()的用法。
那python behave框架中,對於操作前和操作後的前置條件和後置條件,是放在了“environment.py”檔案中定義。
它有以下幾種:
那上面的例子中,在environment.py中實現開啟和關閉瀏覽器的操作,要這樣實現:
# environment.py from selenium import webdriver def before_scenario(context, scenario): context.driver = webdriver.Chrome(r"/usr/local/bin/chromedriver") def after_scenario(context, scenario): context.driver.close()
前置條件和後置條件在environment.py中用上面列舉的函數直接定義,函數名和形參必須符合規範。
可以看出,如果environment.py中的資訊、變數或物件需要在steps中的py檔案中被使用,可以用context來儲存。
這裡就把開啟的瀏覽器物件賦值給了context下定義的driver屬性,然後在py檔案中直接可以使用context.driver,就相當於使用這個瀏覽器了。
注意注意,environment.py檔案在python behave專案中的位置是哪裡?是steps目錄中嗎?
不是的,environment.py檔案是和“.feature”檔案、steps目錄並列在同一目錄下的。而且它的名稱必須是environment.py。
現在回頭看下一個完整的python behave專案的最低結構要求:
+--features/ | +--steps/ # -- Steps directory | | +-- *.py # -- Step implementation or use step-library python files. | +-- *.feature # -- Feature files.
更復雜的目錄為:
+-- features/ | +-- steps/ | | +-- website_steps.py | | +-- utils.py | | | +-- environment.py # -- Environment file with behave hooks, etc. | +-- signup.feature | +-- login.feature | +-- account_details.feature
最後,如何執行behave的程式?
不是執行的steps目錄裡的py檔案,而是通過cmd開啟命令列視窗,執行:“behave xxx.feature”。
這樣也很麻煩,有沒有一種方式可以在py檔案的主入口裡執行"behave xxx.feature",這樣可以封裝成exe程式,雙擊執行exe,即可執行behave。
在python behave專案目錄下建立一個py檔案(也就是和feature檔案、steps目錄檔案在同一級下),命名為main.py,然後寫一個主入口程式:
# main.py from behave.__main__ import main as behave_main import os if __name__ == "__main__": # 獲取main.py的當前目錄 featurefile_dir = os.path.dirname(os.path.realpath(__file__)) # 獲取feature檔案的絕對路徑 featurefile_path = os.path.join(featurefile_dir, "Behave.feature") # 用behave.__main__下的main函數,傳入feature檔案路徑,實現behave xxx.feature相同的效果 # 但是這裡有個主要點,傳入feature檔案的路徑不能是以這樣「」或這樣「\」的表示方式,必須要改成這種「/」 featurefile_path = featurefile_path.replace("\", "/") behave_main(featurefile_path) # 或者你不轉成「」,那麼你就不能直接傳入feature檔案路徑了,必須把檔案路徑放入一個list中,然後把list傳入 # 如果你傳入list,相當於傳入多個引數,這時候除了檔案路徑,還可以傳入tags引數,以執行標記的功能或場景 cmd_order = [] cmd_order.append(featurefile_path) # 把feature檔案路徑新增為list的第一個元素 cmd_order.append("-t @slow") # 把tag標籤新增為list的第二個元素 behave_main(cmd_order) # 傳入參數列
到此這篇關於Python Behave框架學習的文章就介紹到這了,更多相關Python Behave框架內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45