
測試框架
什么是框架?
框架(Framework)是整個或部分系統的可重用設計,
框架是用來解決代碼的組織及運行控制問題的。
在我們編寫自動化腳本的時候,經常需要讀取配置文件,讀取數據文件,發送請求,記錄日志,連接並對比數據庫數據。每個腳本里都重寫一遍各種方法不僅工作量大而且易錯。所以我們需要把公共的方法提取出來,封裝成單獨的模塊,放到公用方法包里。另外配置文件,數據文件,日志等我們也需要分類存到不同的文件夾下。這種對公共方法的封裝及對腳本及配置文件怎么組織的設計就叫做框架。
同時,一般框架除了完成對代碼及配置文件的組織之外還要提供運行的控制功能。比如批量執行,分模塊執行,生成報告,異常處理等等。
總結為以下3點:
- 封裝公共方法
- 代碼及配置文件的組織
- 執行控制
什么是測試框架?
一個完整的測試腳本(用例)一般包含以下幾個步驟:
- 環境准備或檢查
- 執行業務操作
- 斷言結果
- 清理環境
而測試框架一般還要完成用例加載,批量執行,異常控制,結果輸出等功能。基礎的測試框架一般只提供執行控制方面的功能。
測試框架應具有的特點
- 易用性:編寫用例,執行用例,生成報告及定位問題方便
- 健壯性:穩定,比如timeout機制等
- 擴展性:插件
- 靈活性:用例組織或執行的靈活性,Fixture功能(不同范圍的setUp和tearDown)等
- 定制性:二次開發方便
unittest,pytest,nose,robot framework簡介
- unittest: Python自帶,最基礎的單元測試框架
- nose: 基於unittest開發,易用性好,有許多插件
- pytest: 同樣基於unittest開發,易用性好,信息更詳細,插件眾多
- robot framework:一款基於Python語言的關鍵字驅動測試框架,有界面,功能完善,自帶報告及log清晰美觀
項目 | unittest | nose | pytest | robot framework |
---|---|---|---|---|
用例編寫 | 繼承unittest.TestCase類需要組織各種testSuite斷言種類繁多 | test開頭的方法即可 | test開頭的方法即 | 可 robot格式,文本文件 |
執行器 | 自己寫run_all_tests+discover+CommandParser+... | nosetests ... | py.test ... | pybot ... |
用例發現Discover | 支持 | 支持 | 支持 | 支持 |
跳過用例 | unittest.skip()unittest.skipIf()raise uniitest.SkipTest | from nose.plugins.skip import SkipTestraise SkipTest | @pytest.mark.skipif( condition)@pytest.mark.xfail | - |
Fixtures | setUp/tearDown@classmethodsetUpClass... | 支持 | @pytest.fixture(session="session", autouse=True)fixture的作用域:function、module、session ,autouse=True使得函數將默認執行 | [Setup] ...[Teardown] ... |
用例標簽tags | 借助unittest.skip()+comandParser實現 | attrib標簽from nose.plugins.attrib import attr@attr(speed='slow')def test_big_download(): pass$ nosetests -a speed=slow | @pytest.mark.webtest自定義一個mark,如下,然后 py.test -v -m webtest 只運行標記了webtest的函數, py.test -v -m "not webtest" 來運行未標記webtest的 | [Tags] test level1pybot -i/--include tagName C:\TF-Testpybot -e/--exculde level1 *.robot排除 |
超時機制Timeout | 自己實現 | from nose.tools import timedimport time@timed(1)def test_lean_5():time.sleep(2)pass | pip install pytest-timeout@pytest.mark.timeout(60)或 pytest --timeout=300 | [Timeout] 3 seconds |
參數化 | 結合ddt使用 | 結合ddt使用 | @pytest.mark.parametrize("a,b,expected", testdata)def test_timedistance_v0(a, b, expected):diff = a - bassert diff == expected | [Template] 1 2 3 |
報告 | HTMLTestRunner | pip install nose-htmloutput--with-html --html-file= | pip install -U pytest-htmlpy.test --html=./report.html | 支持,默認自動生成 |
日志log | 自己實現 | --nologcapture 不使用log--logging-format=FORMAT使用自定義的格式顯示日志--logging-datefmt=FORMAT 和上面類類似,多了日期格式--logging-filter=FILTER日志過濾,一般很少用,可以不關注--logging-clear-handlers 也可以不關注--logging-level=DEFAULT log的等級定義 | pytest test_add.py --resultlog=./log.txtpytest test_add.py --pastebin=all | 支持,默認自動生成 |
只列出用例collect-only | 無 | nosetests --collect-onlynosetests -v --with-id | --collect-only -v | - |
失敗用例重跑rerun failures | 無 | nosetests -v --failed | pip install -U pytest-rerunfailures@pytest.mark.flaky(reruns=5)py.test --rerun=3 | robot --rerunfailed |
baseline對比 | 無 | 無 | 無 | 無 |
並發 | 改造unittest使用協程並發,或使用線程池+Beautiful Report | 命令行並發 | pytest-xdist:分發到不用的cpu或機器上 | 命令行並發 |
xml報告 | 無 | --with-xunit | --xunit-file=... /pytest+Allure | --junit-xml= |
Selenium支持 | 無 | 無 | pytest-selenium | robotframework-seleniumlibraryrobotframwork-selenium2library |
總結:總體來說,unittest比較基礎,二次開發方便,適合高手使用;pytest/nose更加方便快捷,效率更高,適合小白及追求效率的公司;robot framework由於有界面及美觀的報告,易用性更好,靈活性及可定制性略差。
參考框架設計方案
unittest
上海一悠悠: selenium+python自動化91-unittest多線程生成報告(BeautifulReport)
pytest