我是個初級測試人員,看到大牛們經驗分享life is short, test in Python。問問怎麼把python用於測試中?比如測試網頁,測試介面?最好能舉個好用的框架或者舉幾個栗子。


python在測試方面簡直是無孔不入,從單元到介面,從自動化到性能...

性能測試工具nGrinder介紹?

china-testing.github.io圖標

這個可以用java寫的python即jython做性能測試,類似的還有:

使用jython進行dubbo介面及ngrinder性能測試?

china-testing.github.io

python本身有性能測試工具或可以開發性能測試工具

性能測試工具locustio?

www.jianshu.com圖標性能測試工具boom?

www.jianshu.com

multi-mechanize性能測試工具?

www.jianshu.com圖標性能測試工具開發基礎:python庫介紹-multiprocessing:多進程?

www.jianshu.com

高效靈活的Java及python性能測試工具Grinder?

www.jianshu.com

安全測試的工具很多是python寫的,參考下:

滲透測試工具簡介2入侵工具?

www.jianshu.com圖標

selenium等可以做web自動化測試,appium基於selenium可以做手機端自動化測試。

selenium自動化測試工具python筆試面試項目實戰7 書籍下載?

www.jianshu.com圖標

python還有pytest等功能強大的單元測試框架,介面,自動化測試都經常使用它做測試執行。

自動化測試框架pytest教程 - 目錄?

china-testing.github.io

自動化測試框架pytest教程 - 目錄

自動化測試框架pytest教程 - 目錄?

china-testing.github.io

軟體測試工具書籍與面試題匯總下載(持續更新)?

www.jianshu.com圖標

介面測試:

python工具庫介紹-requests:人性化的HTTP?

www.jianshu.com

介面協議工具thrift1快速入門?

www.jianshu.com圖標

還可以開發測試平臺:

flask工具構建自動化測試平臺1-hello?

www.jianshu.com圖標

python是軟體測試使用最廣泛的語言,太多東東可以用於測試了, 還有海量的測試開發庫參見:

https://github.com/china-testing/python-api-tesing?

github.com

歡迎點贊,並關注

知乎用戶?

www.zhihu.com圖標

謝謝


看了題主提的問題, 看來要走的路還挺長啊........

首先你要去學習Python基礎, 然後自動化測試使用Python+Selenium, 介面測試使用Python+Requests+Unittest框架.

這裡有一些資料, 可以分享給你哈

祝自動化測試之路順利哈


先練好基本功,再去學大牛。

大牛們的經驗並不是說Python絕對的好,而是在大牛們的經歷中,跟其他語言或工具相比,覺得Python特別好用。問題就來了,你要處理的問題,跟大牛們一樣嗎?

如你所說的測試網頁、測試介面,都不是直接用Python寫代碼去測的,都是需要靠工具、靠框架、靠庫。自己搜索一下就有,例如:PythonTestingToolsTaxonomy

這裡首先需要澄清幾個概念,理清思路。

我們從你說的介面測試和web ui測試來入手,這是測試需求和手段。實現某種測試手段的,是某一種語言的一個基礎類庫。

例如,http介面收發可以使用python的requests庫,而web ui元素定位和操作可以用selenium的web driver

但實際上其他語言也可能有等價的類庫,例如java就有http request和response庫,selenium是支持大部分語言的。

使用這樣的類庫進行一定的action,把結果進行verify,這就是一條測試用例,或者叫做測試腳本。

而測試框架是在做什麼呢?

測試框架可以幫助你編排測試用例,處理公用方法,變數,處理數據準備和清理,日誌,報告等等。例如,python的pytest就是最廣泛使用的python測試框架。

其他語言也有類似的測試框架,例如java的testng,golang的ginkgo。

同時,一個測試框架可以跟測試手段,以及基礎類庫無關。也就是說pytest既可以做介面測試,也可以做ui測試,也可以做性能測試,甚至可以在一套框架裡面並存。

測試框架是幫助你組織測試的,沒有測試框架,你自己寫一個main函數作為入口的測試腳本,顯然也是可以的。

所以,技術選型的時候,要兼顧兩條思維路線。

第一條路線:

你要測什麼

你要用什麼手段測

你所選擇的語言,是否有好用的對應的基礎類庫,能實現這個測試手段

第二條路線:

你要怎麼測

你是否有複雜的測試組織需求,例如,並發,串列,數據準備和清理,參數化,報告等

你所選的語言,是否具備滿足上述能力的測試框架

推薦的工具或框架,我加粗寫在上面了


python是現在相對交火的一門語言,多用於軟體自動化測試,但是像題主這個情況,個人建議你還是先把python學好學精再去考慮用它去經行測試,可以去聽聽相關的公開課,讀讀相關的書籍

發佈於 2018-10-10繼續瀏覽內容知乎發現更大的世界打開Chrome繼續CSDNCSDN成就一億技術人

之前CSDN編譯過一篇文章,貼出來,希望對你有幫助。

近年來測試驅動開發(TDD)受到越來越多的關注。這是一個持續改進的過程,能從一開始就形成規範,幫助提高代碼質量。這是切實可行的而非天馬行空的。

TDD的全過程是非常簡單的。藉助TDD,代碼質量會得到提升,同時可以讓你保持清晰的思路。TDD與敏捷開發可謂強強聯合,特別是在進行結對編程的時候。本文主要介紹了TDD的核心概念,還有結合nosetest單元測試包進行Python示例簡析。另外還會介紹一些Python備用包。

TDD是什麼?

使用該方法可讓你少走前人的彎路

顧名思義,TDD即進行編程時先把測試部分寫好,當發現不能通過時,再進行編程以使測試通過。然後在這基礎上適當地調整測試代碼以實現更多功能,最後再編寫代碼使之實現。

TDD看起來非常像一個環,首先是要不斷調整測試代碼,然後是編碼,改進,最後直至完成。先實現測試部分的做法會使你自然養成把問題放在首位的思維習慣。當真正去構建代碼時,就不得不想清楚該如何把設計做好;比方說,該方法有何返回值?當遇到異常時該怎麼辦?諸如此類。

以這樣的方式進行開發,意味著要想出不同的代碼實現路徑,並在測試中進行實踐。這樣做可使你少走前人的彎路:陷入一個問題後寫出毫不相關的解決方案。

該過程可描述如下:

  • 寫出一個缺陷單元測試
  • 使該單元測試通過
  • 重構

與敏捷開發結合

TDD與敏捷開發並行不悖甚至1+1遠大於2,這裡指的是代碼質量而不是數量。

「這意味著結對雙方都會參與其中,著重於當前工作,然後在每個環節進行互檢。」

然而在結對編程時TDD是單獨進行的。如果能把雙方的開發流程混合好,互相都能理解就最好不過了。例如,其中一人寫出單元測試,當測試通過後,另外一人可以編寫不同的測試以之通過。

任何時候結對雙方都可以互換角色,每半天或天。這意味著結對雙方都會參與其中,每人都把精力放在當前任務上,然後在每個環節進行交叉互檢。這難道不是一個雙贏的做法嗎?

TDD也可以是行為驅動開發過程中的組成部分,同樣地,首先寫出測試,只不過這裡指的是接受測試。這樣有助於把工作從頭到尾都保持規範。

單元測試語法

進行單元測試時,使用到的Python方法如下:

  • assert: 編寫個人聲明的基本方式
  • assertEqual(a,b):檢查a和b的是否等價
  • assertNotEqual(a,b):檢查a和b的是否非等價
  • assertIn(a,b):檢查是否存在b中
  • assertNotIn(a,b): 檢查是否不存在b中
  • assertFalse(a):檢查a的值是否為False
  • assertTrue(a):檢查a的值是否為Ture
  • assertIsInstance(a,TYPE):檢查a是否為「TYPE」類型
  • assertRaises(ERROR,a,args):以參數args調用a時,檢查是否會出現ERROR

以上是實際當中使用頻率最高的方法,更多的方法請查閱Python單元測試文檔。

安裝並使用Python Nose

進行下面的練習前,請把nosetest測試運行包安裝好。使用標準pip語句進行安裝是最直接的做法。此外在項目中使用VirtualEnv(Python虛擬環境)也是不錯的做法,因為它可確保所有包在不同項目中是獨立的。假如對pip或VirtualEnv瞭解不多,不妨先查閱相關文檔:VirtualEnv,PIP。

pip語句十分簡潔:

"pip install nose"

安裝完成後,可以執行單個測試文件

$ nosetests example_unit_test.py

或者可以直接執行文件夾中的文件組

$ nosetests /path/to/tests

這裡要注意的是每個測試方法都應以「test_」為開頭,這樣nosetest運行機才能正確識別出目標測試文件。

可選參數

下面介紹幾個有用的命令行參數:

  • -v:輸出更多信息,包括正在執行的測試文件名
  • -s或-nocapture:進行PRINT語句輸出,一般情況下這是隱藏的。開啟後可方便調試。
  • --nologcapture:輸出日誌信息
  • --rednose:一個可選插件,請點擊這裡下載,輸出帶顏色的輸出信息。
  • --tags=TAGS:指定要執行的測試文件,而不是整個測試文件組

實例分析和測試驅動方法

接下來會結合一個簡單的計算器類例子例如相加/相減,來講述Python單元測試和TDD本概念。對於add相加功能,會嘗試編寫一個缺陷測試。

在一個空白項目中,首先創建兩個python包app和test。然後在每個文件裏建立兩個名為_init_.py空白文件。這是Phthon工程的標準結構,完成後可以擁有一個可導入的文件結構。如果需要了解更多有關文檔架構的信息,請查閱Python包說明文檔。 在測試目錄裏創建一個test_calulator.py文件,其代碼如下:

import unittest

class TddInPythonExample(unittest.TestCase):def test_calculator_add_method_returns_correct_result(self):

calc = Calculator()

result = calc.add(2,2)self.assertEqual(4, result)

說明:

  • 首先,從Python標準庫裏導入標準的unittest模塊
  • 接著,創建一個含有不同測試用例的類
  • 最後,創建以「test_」為開頭的一個測試方法

完成後可著手編寫測試代碼了。執行方法前要先對計算器進行初始化,初始化完成後便可調用add方法,並把結果存入變數result中。完成後,使用unittest的assertEqual方法來確保add方法正常執行。

現在可以啟動nosetest來執行測試文件了。代碼如下:

if __name__ == __main__:

unittest.main()

標準的Python文件執行方式為$ python test_calculator.py,相比之下本文使用的nosetests方法功能更豐富,例如可以運行目錄中的全部測試文件。

$ nosetests test_calculator.py

E======================================================================

ERROR: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)

----------------------------------------------------------------------Traceback (most recent call last):File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 6, in test_calculator_add_method_returns_correct_resultcalc = Calculator()NameError: global name Calculator is not defined----------------------------------------------------------------------Ran 1 test in 0.001sFAILED (errors=1)

運行後可見出錯的原因是沒有導入Caculator。因為還沒有創建呢!創建的方法是在app目錄下建立calculator.py文件,然後導入:

class Calculator(object):

def add(self, x, y):pass[py] view plaincopyimport unittestfrom app.calculator import Calculatorclass TddInPythonExample(unittest.TestCase):def test_calculator_add_method_returns_correct_result(self):calc = Calculator()result = calc.add(2,2)self.assertEqual(4, result)if __name__ == __main__:unittest.main()

把Caculator構建好之後,再次運行看會出現什麼結果:

$ nosetests test_calculator.py

F======================================================================FAIL: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)----------------------------------------------------------------------Traceback (most recent call last):File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 9, in test_calculator_add_method_returns_correct_resultself.assertEqual(4, result)AssertionError: 4 != None----------------------------------------------------------------------Ran 1 test in 0.001sFAILED (failures=1)

很明顯,add方法返回了錯誤的值,因為還沒有為它指定行為。幸好nosetest會指出出錯的位置,方便進行修改。稍作改動後,測試便可通過了:

class Calculator(object):

def add(self, x, y):return x+y[py] view plaincopy$ nosetests test_calculator.py.----------------------------------------------------------------------Ran 1 test in 0.000sOK

雖然通過了,但是圍繞該方法還可以做更多的工作。

沉迷於某個案例很容易造成短視

如果進行非數字型數據相加會導致什麼後果呢?事實上Python是允許字元串或其它類型進行相加的,但在我們的例子裏不允許。接著嘗試就這個例子加入另一個缺陷測試,然後使用assertRaises方法來判斷是否有異常拋出:

import unittest

from app.calculator import Calculatorclass TddInPythonExample(unittest.TestCase):def setUp(self):self.calc = Calculator()def test_calculator_add_method_returns_correct_result(self):result = self.calc.add(2, 2)self.assertEqual(4, result)def test_calculator_returns_error_message_if_both_args_not_numbers(self):self.assertRaises(ValueError, self.calc.add, two, three)if __name__ == __main__:unittest.main()

以上代碼中,檢查了是否引起了ValueError錯誤,其實還可以進行更多的檢測,不過在這裡不作深入講述。此外,setup()方法用於推入計算對象。下面再看看nosetest會反饋什麼信息:

$ nosetests test_calculator.py

.F======================================================================FAIL: test_calculator_returns_error_message_if_both_args_not_numbers (test.test_calculator.TddInPythonExample)----------------------------------------------------------------------Traceback (most recent call last):File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 15, in test_calculator_returns_error_message_if_both_args_not_numbersself.assertRaises(ValueError, self.calc.add, two, three)AssertionError: ValueError not raised----------------------------------------------------------------------Ran 2 tests in 0.001sFAILED (failures=1)

顯然nosetests告訴我們ValueError沒有被拋出。現在我們有了一個新的缺陷測試,接著嘗試編碼進行解決:

class Calculator(object):

def add(self, x, y):number_types = (int, long, float, complex)if isinstance(x, number_types) and isinstance(y, number_types):return x + yelse:raise ValueError

代碼中使用了isinstance方法是為了確保輸入的是數字型數據。

由於兩個變數的類型有多種組合,為了進行完整的測試,所以需要把可能出現的組合進行統籌並進行處理:

import unittest

from app.calculator import Calculatorclass TddInPythonExample(unittest.TestCase):def setUp(self):self.calc = Calculator()def test_calculator_add_method_returns_correct_result(self):result = self.calc.add(2, 2)self.assertEqual(4, result)def test_calculator_returns_error_message_if_both_args_not_numbers(self):self.assertRaises(ValueError, self.calc.add, two, three)def test_calculator_returns_error_message_if_x_arg_not_number(self):self.assertRaises(ValueError, self.calc.add, two, 3)def test_calculator_returns_error_message_if_y_arg_not_number(self):self.assertRaises(ValueError, self.calc.add, 2, three)if __name__ == __main__:unittest.main()

至此我們可以運行所有的測試了,所要實現的需求也都滿足了。

其它的單元測試包

py.test

pytest的作用與nosetest類似,不過可以在單獨的區域裏輸出信息,這意味著能夠使我們很快地看清楚命令行中出現的列印信息。這對於只運行單個測試的情況是很有用的。

$ nosetests test_calculator.py

....----------------------------------------------------------------------Ran 4 tests in 0.001sOK

安裝pytest的方式與nosetest差不多,命令是$ pip install pytes。執行的命令是$ pip install pytes或者指定要執行的測試文件$ py.test test/calculator_tests.py。

$ py.test test/test_calculator.py

================================================================= test session starts =================================================================platform darwin -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4collected 4 itemstest/test_calculator.py ....============================================================== 4 passed in 0.02 seconds ===============================================================

pytest運行後的結果如下。註:只有代碼含有錯誤或異常的情況下,pytest才會進行輸出。

$ py.test test/test_calculator.py

================================================================= test session starts =================================================================platform darwin -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4collected 4 itemstest/test_calculator.py F...====================================================================== FAILURES =======================================================================________________________________________ TddInPythonExample.test_calculator_add_method_returns_correct_result _________________________________________self = &def test_calculator_add_method_returns_correct_result(self):result = self.calc.add(3, 2)&> self.assertEqual(4, result)E AssertionError: 4 != 5test/test_calculator.py:11: AssertionError---------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------X value is: 3Y value is: 2Result is 5========================================================= 1 failed, 3 passed in 0.03 seconds ==========================================================

單元測試

如果不想安裝額外的包並想保持一個純凈的標準庫結構,使用Python內建的unittest單元測試包是不錯的選擇。其使用方法如下:

if __name__ == __main__:

unittest.main()使用python calculator_tests.py執行後,看會得到什麼結果:[py] view plaincopy$ python test/test_calculator.py....----------------------------------------------------------------------Ran 4 tests in 0.004sOK

使用PDB進行調試

以TDD方式開發,經常會遇到來自代碼或測試的問題。有時這些錯誤又是比較隱蔽的。因此,需要配合使用高明的調試技術。

以TDD方式進行開發出現問題時可能難以發現

幸運地,有不少的辦法來解決這些問題。其中最簡單的方式是透過增添print語句實現「斷點」輸出。

結合print語句進行調試

加法通過後,可以嘗試進行減法調試。把app/calculator.py中的add部分代碼作如下改動:

class Calculator(object):

def add(self, x, y):number_types = (int, long, float, complex)if isinstance(x, number_types) and isinstance(y, number_types):return x - yelse:raise ValueError

這裡不妨嘗試使用print語句進行輸出,來監視值是怎樣變化的。

class Calculator(object):

def add(self, x, y):number_types = (int, long, float, complex)if isinstance(x, number_types) and isinstance(y, number_types):print X is: {}.format(x)print Y is: {}.format(y)result = x - yprint Result is: {}.format(result)return resultelse:raise ValueError

現在可以使用nosetest來執行並查看結果,可見這樣的工整輸出結構,對調試是十分有幫助的。

$ nosetests test/test_calculator.py

F...======================================================================FAIL: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)----------------------------------------------------------------------Traceback (most recent call last):File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 11, in test_calculator_add_method_returns_correct_resultself.assertEqual(4, result)AssertionError: 4 != 0-------------------- &>&> begin captured stdout &X is: 2Y is: 2Result is: 0--------------------- &>&> end captured stdout &----------------------------------------------------------------------Ran 4 tests in 0.002sFAILED (failures=1)

PDB進階調試

如果遇到更複雜的調試環節,僅僅依靠print語句是不夠的。其中最經常使用的進階調試工具是pdb(Python Debugger)。該工具包含在標準庫中,使用的時候只需加入一行代碼到「斷點」位置。請看下面的代碼:

class Calculator(object):

def add(self, x, y):number_types = (int, long, float, complex)if isinstance(x, number_types) and isinstance(y, number_types):import pdb; pdb.set_trace()return x - yelse:raise ValueError

請注意,如果使用nosetest執行測試,請務必使用-s標記,否則nosetest會繼續對輸出進行抓取,這樣會使pdb無法正常運行。如果是使用unittest或pytest則無需這樣做。

如果測試停止並有pdb提示,請使用list命令來進行當前代碼定位。

$ nosetests -s

&> /Users/user/PycharmProjects/tdd_in_python/app/calculator.py(7)add()-&> return x - y(Pdb) list2 def add(self, x, y):3 number_types = (int, long, float, complex)45 if isinstance(x, number_types) and isinstance(y, number_types):6 import pdb; pdb.set_trace()7 -&> return x - y8 else:9 raise ValueError[EOF](Pdb)

出現提示後是可以進行交互操作的,比方說想在這個時候檢閱x和y的值:

(Pdb) x

2(Pdb) y2

如果想了解更多命令,可以鍵入 help來查看。經常使用的命令如下所示:

  • n: 步進到下個執行
  • list: 顯示當前位置
  • args: 顯示在當前執行點上用到的變數
  • continue:運行代碼直至結束
  • jump &: 運行並跳轉到行號位置
  • quit/exit:停止pdb

寫在最後

TDD模式十分有趣同時能幫助提高代碼質量。不論是大型團隊還是個人開發,TDD都可運用其中。此外,成功的缺陷測試設計是非常有滿足感的。所以,不妨從今天起嘗試把TDD引入到日常工作中,親身體驗試驗前後會有什麼變化。

發佈於 2018-10-16繼續瀏覽內容知乎發現更大的世界打開Chrome繼續testerTechnologytesterTechnology

怎麼做python自動化,清楚下python在那些層次能做:

不管做ui的python+selenium+unittest、python+appium+unittest;

還是做介面的python+requests

還是做平臺開發的python有flask和django


之前CSDN編譯過一篇文章,貼出來,希望對你有幫助。

近年來測試驅動開發(TDD)受到越來越多的關注。這是一個持續改進的過程,能從一開始就形成規範,幫助提高代碼質量。這是切實可行的而非天馬行空的。

TDD的全過程是非常簡單的。藉助TDD,代碼質量會得到提升,同時可以讓你保持清晰的思路。TDD與敏捷開發可謂強強聯合,特別是在進行結對編程的時候。本文主要介紹了TDD的核心概念,還有結合nosetest單元測試包進行Python示例簡析。另外還會介紹一些Python備用包。

TDD是什麼?

使用該方法可讓你少走前人的彎路

顧名思義,TDD即進行編程時先把測試部分寫好,當發現不能通過時,再進行編程以使測試通過。然後在這基礎上適當地調整測試代碼以實現更多功能,最後再編寫代碼使之實現。

TDD看起來非常像一個環,首先是要不斷調整測試代碼,然後是編碼,改進,最後直至完成。先實現測試部分的做法會使你自然養成把問題放在首位的思維習慣。當真正去構建代碼時,就不得不想清楚該如何把設計做好;比方說,該方法有何返回值?當遇到異常時該怎麼辦?諸如此類。

以這樣的方式進行開發,意味著要想出不同的代碼實現路徑,並在測試中進行實踐。這樣做可使你少走前人的彎路:陷入一個問題後寫出毫不相關的解決方案。

該過程可描述如下:

  • 寫出一個缺陷單元測試
  • 使該單元測試通過
  • 重構

與敏捷開發結合

TDD與敏捷開發並行不悖甚至1+1遠大於2,這裡指的是代碼質量而不是數量。

「這意味著結對雙方都會參與其中,著重於當前工作,然後在每個環節進行互檢。」

然而在結對編程時TDD是單獨進行的。如果能把雙方的開發流程混合好,互相都能理解就最好不過了。例如,其中一人寫出單元測試,當測試通過後,另外一人可以編寫不同的測試以之通過。

任何時候結對雙方都可以互換角色,每半天或天。這意味著結對雙方都會參與其中,每人都把精力放在當前任務上,然後在每個環節進行交叉互檢。這難道不是一個雙贏的做法嗎?

TDD也可以是行為驅動開發過程中的組成部分,同樣地,首先寫出測試,只不過這裡指的是接受測試。這樣有助於把工作從頭到尾都保持規範。

單元測試語法

進行單元測試時,使用到的Python方法如下:

  • assert: 編寫個人聲明的基本方式
  • assertEqual(a,b):檢查a和b的是否等價
  • assertNotEqual(a,b):檢查a和b的是否非等價
  • assertIn(a,b):檢查是否存在b中
  • assertNotIn(a,b): 檢查是否不存在b中
  • assertFalse(a):檢查a的值是否為False
  • assertTrue(a):檢查a的值是否為Ture
  • assertIsInstance(a,TYPE):檢查a是否為「TYPE」類型
  • assertRaises(ERROR,a,args):以參數args調用a時,檢查是否會出現ERROR

以上是實際當中使用頻率最高的方法,更多的方法請查閱Python單元測試文檔。

安裝並使用Python Nose

進行下面的練習前,請把nosetest測試運行包安裝好。使用標準pip語句進行安裝是最直接的做法。此外在項目中使用VirtualEnv(Python虛擬環境)也是不錯的做法,因為它可確保所有包在不同項目中是獨立的。假如對pip或VirtualEnv瞭解不多,不妨先查閱相關文檔:VirtualEnv,PIP。

pip語句十分簡潔:

"pip install nose"

安裝完成後,可以執行單個測試文件

$ nosetests example_unit_test.py

或者可以直接執行文件夾中的文件組

$ nosetests /path/to/tests

這裡要注意的是每個測試方法都應以「test_」為開頭,這樣nosetest運行機才能正確識別出目標測試文件。

可選參數

下面介紹幾個有用的命令行參數:

  • -v:輸出更多信息,包括正在執行的測試文件名
  • -s或-nocapture:進行PRINT語句輸出,一般情況下這是隱藏的。開啟後可方便調試。
  • --nologcapture:輸出日誌信息
  • --rednose:一個可選插件,請點擊這裡下載,輸出帶顏色的輸出信息。
  • --tags=TAGS:指定要執行的測試文件,而不是整個測試文件組

實例分析和測試驅動方法

接下來會結合一個簡單的計算器類例子例如相加/相減,來講述Python單元測試和TDD本概念。對於add相加功能,會嘗試編寫一個缺陷測試。

在一個空白項目中,首先創建兩個python包app和test。然後在每個文件裏建立兩個名為_init_.py空白文件。這是Phthon工程的標準結構,完成後可以擁有一個可導入的文件結構。如果需要了解更多有關文檔架構的信息,請查閱Python包說明文檔。 在測試目錄裏創建一個test_calulator.py文件,其代碼如下:

import unittest

class TddInPythonExample(unittest.TestCase):def test_calculator_add_method_returns_correct_result(self):calc = Calculator()result = calc.add(2,2)self.assertEqual(4, result)

說明:

  • 首先,從Python標準庫裏導入標準的unittest模塊
  • 接著,創建一個含有不同測試用例的類
  • 最後,創建以「test_」為開頭的一個測試方法

完成後可著手編寫測試代碼了。執行方法前要先對計算器進行初始化,初始化完成後便可調用add方法,並把結果存入變數result中。完成後,使用unittest的assertEqual方法來確保add方法正常執行。

現在可以啟動nosetest來執行測試文件了。代碼如下:

if __name__ == __main__:

unittest.main()

標準的Python文件執行方式為$ python test_calculator.py,相比之下本文使用的nosetests方法功能更豐富,例如可以運行目錄中的全部測試文件。

$ nosetests test_calculator.py

E======================================================================ERROR: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)----------------------------------------------------------------------Traceback (most recent call last):File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 6, in test_calculator_add_method_returns_correct_resultcalc = Calculator()NameError: global name Calculator is not defined----------------------------------------------------------------------Ran 1 test in 0.001sFAILED (errors=1)

運行後可見出錯的原因是沒有導入Caculator。因為還沒有創建呢!創建的方法是在app目錄下建立calculator.py文件,然後導入:

class Calculator(object):

def add(self, x, y):pass[py] view plaincopyimport unittestfrom app.calculator import Calculatorclass TddInPythonExample(unittest.TestCase):def test_calculator_add_method_returns_correct_result(self):calc = Calculator()result = calc.add(2,2)self.assertEqual(4, result)if __name__ == __main__:unittest.main()

把Caculator構建好之後,再次運行看會出現什麼結果:

$ nosetests test_calculator.py

F======================================================================FAIL: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)----------------------------------------------------------------------Traceback (most recent call last):File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 9, in test_calculator_add_method_returns_correct_resultself.assertEqual(4, result)AssertionError: 4 != None----------------------------------------------------------------------Ran 1 test in 0.001sFAILED (failures=1)

很明顯,add方法返回了錯誤的值,因為還沒有為它指定行為。幸好nosetest會指出出錯的位置,方便進行修改。稍作改動後,測試便可通過了:

class Calculator(object):

def add(self, x, y):return x+y[py] view plaincopy$ nosetests test_calculator.py.----------------------------------------------------------------------Ran 1 test in 0.000sOK

雖然通過了,但是圍繞該方法還可以做更多的工作。

沉迷於某個案例很容易造成短視

如果進行非數字型數據相加會導致什麼後果呢?事實上Python是允許字元串或其它類型進行相加的,但在我們的例子裏不允許。接著嘗試就這個例子加入另一個缺陷測試,然後使用assertRaises方法來判斷是否有異常拋出:

import unittest

from app.calculator import Calculatorclass TddInPythonExample(unittest.TestCase):def setUp(self):self.calc = Calculator()def test_calculator_add_method_returns_correct_result(self):result = self.calc.add(2, 2)self.assertEqual(4, result)def test_calculator_returns_error_message_if_both_args_not_numbers(self):self.assertRaises(ValueError, self.calc.add, two, three)if __name__ == __main__:unittest.main()

以上代碼中,檢查了是否引起了ValueError錯誤,其實還可以進行更多的檢測,不過在這裡不作深入講述。此外,setup()方法用於推入計算對象。下面再看看nosetest會反饋什麼信息:

$ nosetests test_calculator.py

.F======================================================================FAIL: test_calculator_returns_error_message_if_both_args_not_numbers (test.test_calculator.TddInPythonExample)----------------------------------------------------------------------Traceback (most recent call last):File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 15, in test_calculator_returns_error_message_if_both_args_not_numbersself.assertRaises(ValueError, self.calc.add, two, three)AssertionError: ValueError not raised----------------------------------------------------------------------Ran 2 tests in 0.001sFAILED (failures=1)

顯然nosetests告訴我們ValueError沒有被拋出。現在我們有了一個新的缺陷測試,接著嘗試編碼進行解決:

class Calculator(object):

def add(self, x, y):number_types = (int, long, float, complex)if isinstance(x, number_types) and isinstance(y, number_types):return x + yelse:raise ValueError

代碼中使用了isinstance方法是為了確保輸入的是數字型數據。

由於兩個變數的類型有多種組合,為了進行完整的測試,所以需要把可能出現的組合進行統籌並進行處理:

import unittest

from app.calculator import Calculatorclass TddInPythonExample(unittest.TestCase):def setUp(self):self.calc = Calculator()def test_calculator_add_method_returns_correct_result(self):result = self.calc.add(2, 2)self.assertEqual(4, result)def test_calculator_returns_error_message_if_both_args_not_numbers(self):self.assertRaises(ValueError, self.calc.add, two, three)def test_calculator_returns_error_message_if_x_arg_not_number(self):self.assertRaises(ValueError, self.calc.add, two, 3)def test_calculator_returns_error_message_if_y_arg_not_number(self):self.assertRaises(ValueError, self.calc.add, 2, three)if __name__ == __main__:unittest.main()

至此我們可以運行所有的測試了,所要實現的需求也都滿足了。

其它的單元測試包

py.test

pytest的作用與nosetest類似,不過可以在單獨的區域裏輸出信息,這意味著能夠使我們很快地看清楚命令行中出現的列印信息。這對於只運行單個測試的情況是很有用的。

$ nosetests test_calculator.py

....----------------------------------------------------------------------Ran 4 tests in 0.001sOK

安裝pytest的方式與nosetest差不多,命令是$ pip install pytes。執行的命令是$ pip install pytes或者指定要執行的測試文件$ py.test test/calculator_tests.py。

$ py.test test/test_calculator.py

================================================================= test session starts =================================================================platform darwin -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4collected 4 itemstest/test_calculator.py ....============================================================== 4 passed in 0.02 seconds ===============================================================

pytest運行後的結果如下。註:只有代碼含有錯誤或異常的情況下,pytest才會進行輸出。

$ py.test test/test_calculator.py

================================================================= test session starts =================================================================platform darwin -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4collected 4 itemstest/test_calculator.py F...====================================================================== FAILURES =======================================================================________________________________________ TddInPythonExample.test_calculator_add_method_returns_correct_result _________________________________________self = &def test_calculator_add_method_returns_correct_result(self):result = self.calc.add(3, 2)&> self.assertEqual(4, result)E AssertionError: 4 != 5test/test_calculator.py:11: AssertionError---------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------X value is: 3Y value is: 2Result is 5========================================================= 1 failed, 3 passed in 0.03 seconds ==========================================================

單元測試

如果不想安裝額外的包並想保持一個純凈的標準庫結構,使用Python內建的unittest單元測試包是不錯的選擇。其使用方法如下:

if __name__ == __main__:

unittest.main()使用python calculator_tests.py執行後,看會得到什麼結果:[py] view plaincopy$ python test/test_calculator.py....----------------------------------------------------------------------Ran 4 tests in 0.004sOK

使用PDB進行調試

以TDD方式開發,經常會遇到來自代碼或測試的問題。有時這些錯誤又是比較隱蔽的。因此,需要配合使用高明的調試技術。

以TDD方式進行開發出現問題時可能難以發現

幸運地,有不少的辦法來解決這些問題。其中最簡單的方式是透過增添print語句實現「斷點」輸出。

結合print語句進行調試

加法通過後,可以嘗試進行減法調試。把app/calculator.py中的add部分代碼作如下改動:

class Calculator(object):

def add(self, x, y):number_types = (int, long, float, complex)if isinstance(x, number_types) and isinstance(y, number_types):return x - yelse:raise ValueError

這裡不妨嘗試使用print語句進行輸出,來監視值是怎樣變化的。

class Calculator(object):

def add(self, x, y):number_types = (int, long, float, complex)if isinstance(x, number_types) and isinstance(y, number_types):print X is: {}.format(x)print Y is: {}.format(y)result = x - yprint Result is: {}.format(result)return resultelse:raise ValueError

現在可以使用nosetest來執行並查看結果,可見這樣的工整輸出結構,對調試是十分有幫助的。

$ nosetests test/test_calculator.py

F...======================================================================FAIL: test_calculator_add_method_returns_correct_result (test.test_calculator.TddInPythonExample)----------------------------------------------------------------------Traceback (most recent call last):File "/Users/user/PycharmProjects/tdd_in_python/test/test_calculator.py", line 11, in test_calculator_add_method_returns_correct_resultself.assertEqual(4, result)AssertionError: 4 != 0-------------------- &>&> begin captured stdout &X is: 2Y is: 2Result is: 0--------------------- &>&> end captured stdout &----------------------------------------------------------------------Ran 4 tests in 0.002sFAILED (failures=1)

PDB進階調試

如果遇到更複雜的調試環節,僅僅依靠print語句是不夠的。其中最經常使用的進階調試工具是pdb(Python Debugger)。該工具包含在標準庫中,使用的時候只需加入一行代碼到「斷點」位置。請看下面的代碼:

class Calculator(object):

def add(self, x, y):number_types = (int, long, float, complex)if isinstance(x, number_types) and isinstance(y, number_types):import pdb; pdb.set_trace()return x - yelse:raise ValueError

請注意,如果使用nosetest執行測試,請務必使用-s標記,否則nosetest會繼續對輸出進行抓取,這樣會使pdb無法正常運行。如果是使用unittest或pytest則無需這樣做。

如果測試停止並有pdb提示,請使用list命令來進行當前代碼定位。

$ nosetests -s

&> /Users/user/PycharmProjects/tdd_in_python/app/calculator.py(7)add()-&> return x - y(Pdb) list2 def add(self, x, y):3 number_types = (int, long, float, complex)45 if isinstance(x, number_types) and isinstance(y, number_types):6 import pdb; pdb.set_trace()7 -&> return x - y8 else:9 raise ValueError[EOF](Pdb)

出現提示後是可以進行交互操作的,比方說想在這個時候檢閱x和y的值:

(Pdb) x

2(Pdb) y2

如果想了解更多命令,可以鍵入 help來查看。經常使用的命令如下所示:

  • n: 步進到下個執行
  • list: 顯示當前位置
  • args: 顯示在當前執行點上用到的變數
  • continue:運行代碼直至結束
  • jump &: 運行並跳轉到行號位置
  • quit/exit:停止pdb

寫在最後

TDD模式十分有趣同時能幫助提高代碼質量。不論是大型團隊還是個人開發,TDD都可運用其中。此外,成功的缺陷測試設計是非常有滿足感的。所以,不妨從今天起嘗試把TDD引入到日常工作中,親身體驗試驗前後會有什麼變化。

發佈於 2018-10-16繼續瀏覽內容知乎發現更大的世界打開Chrome繼續testerTechnologytesterTechnology

怎麼做python自動化,清楚下python在那些層次能做:

不管做ui的python+selenium+unittest、python+appium+unittest;

還是做介面的python+requests

還是做平臺開發的python有flask和django


怎麼做python自動化,清楚下python在那些層次能做:

不管做ui的python+selenium+unittest、python+appium+unittest;

還是做介面的python+requests

還是做平臺開發的python有flask和django


哥,要把python運用到實際工作中去,

總學python基礎語法,用不上。

直接跟教程做一個大項目,很難,跟不上!

要一步一步來,先學會python批處理腳本, 然後寫函數,再寫類。

現在的教程都有點浮誇!

可以看看武散人的《自拍教程》,我覺得比較適合測試人員,

尤其是那種對代碼很不敏感的測試同學[驚喜],比如我


首先是需要通過學習python學會編程,學會編程再談其它的應用。

python web測試,主要用在測試自動化上。有名的selenium 就用在web 自動化測試上。Selenium - Web Browser Automation從web測試,到性能測試,單元測試,持續集成等都可以用python寫代碼來完成。
先去找本python基礎書籍看看再說~
推薦閱讀:
相關文章