Selenium2 Python 自動化測試實戰學習筆記(四)
第五章 自動化測試模型
一個自動化測試框架就是一個整合體系,在這一體系中包含測試功能的函式庫、測試資料來源、測試物件識別標準,以及種可重用的模組。自動化測試框架在發展的過程中經歷了幾個階段,線性測試、模組驅動測試、資料驅動測試、關鍵字驅動測試。
Python 提供了以下幾種讀取檔案的方式。
l read() 讀取整個檔案。
l readline() 讀取一行資料。
l readlines() 讀取所有行的資料。
下面通過讀取csv 檔案的方法來解決這個每次要讀取多個資訊的問題。
首先建立userinfo.csv 檔案,通過WPS 表格或Excel 建立表格,檔案另存為選擇CSV 格式進行儲存,注意不要直接修改Excel 的字尾名來建立CSV 檔案,這樣創建出來的並非真正的CSV 檔案。
loop_reader.py
#coding=utf-8
import csv
my_file='userinfo.csv'
data=csv.reader(file(my_file,'rb'))
for user in data:
print user
第六章 unittest 單元測試框架
6.1 分析帶unittest 自動化測試指令碼
Baidu_with_unittes.py
# -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys importKeys from selenium.webdriver.support.ui importSelect from selenium.common.exceptions importNoSuchElementException from selenium.common.exceptions importNoAlertPresentException import unittest, time, re class BaiduTest(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.implicitly_wait(30) self.base_url = "http://www.baidu.com/" self.verificationErrors = [] self.accept_next_alert = True def test_baidu(self): driver = self.driver driver.get(self.base_url + "/") driver.find_element_by_id("kw").clear() driver.find_element_by_id("kw").send_keys("seleniumide") driver.find_element_by_id("su").click() def is_element_present(self, how, what): try: self.driver.find_element(by=how, value=what) except NoSuchElementException, e: return False return True def is_alert_present(self): try: self.driver.switch_to_alert() except NoAlertPresentException, e: return False return True def close_alert_and_get_its_text(self): try: alert = self.driver.switch_to_alert() alert_text = alert.text if self.accept_next_alert: alert.accept() else: alert.dismiss() return alert_text finally: self.accept_next_alert = True def tearDown(self): self.driver.quit() self.assertEqual([], self.verificationErrors) if __name__ == "__main__": unittest.main()
import unittest:首先要引入unittest框架包。
class BaiduTest(unittest.TestCase): Baidu 類繼承unittest.TestCase類,從TestCase 類繼承是告訴unittest 模組的方式,這是一個測試案例。
setUp 用於設定初始化工作,在每一個測試用例前先被執行,它與tearDown方法相呼應,後者在每一個測試用例執行後被執行。這裡的初始化工作定義了瀏覽器啟動和基礎URL 地址。
定義空的verificationErrors 陣列,指令碼執行時的錯誤資訊將被列印到這個陣列中。
定義accept_next_alert 變數,表示是否繼續接受下一個警告,初始化狀態為Ture。
test_baidu 中放置的就是我們的測試指令碼.
is_element_present 方法用來查詢頁面元素是否存在,通過find_element()來接收元素的定位方法(how)和定位值(what),如果定位到元素返回Ture,否則出現異常並返回Flase.
is_alert_present()方法用來處理彈出的警告框,用WebDriver 所提供的switch_to_alert()方法來捕捉警告框。如果捕捉到警告框返回Ture,否則異常,返回Flase。
close_alert_and_get_its_text()關閉警告並且獲得警告資訊。首先通過switch_to_alert()獲得警告,通過.text 獲得警告框資訊。接著通過if 語句判斷accept_next_alert 的狀態,在setUp()已經初始化狀態為Ture,如果為Ture,通過accept()接受警告。否則dismiss()忽略此警告。
tearDown 方法在每個測試方法執行後呼叫,這個方法用於完成測試用例執行後的清理工作,如退出瀏覽器、關閉驅動,恢復用例執行狀態等。
在setUp()方法中定義了verificationErrors 為空陣列,這裡通過assertEqual()比較其是否為空,如果為空說明用例執行的過程過程中沒有出現異常,否則將丟擲AssertionError 異常。
if __name__ == "__main__":
unittest.main()
整個測試過程整合在unitest.main()模組中,其預設執行以test 開頭的方法。
.py 檔案有兩種使用方式:作為模組被呼叫和直接使用。如果它等於"__main__"就表示是直接執行。
6.2unittest 單元測試框架解析
單元測試負責對最小的軟體設計單元(模組)進行驗證,它使用軟體設計文件中對模組的描述作為指南,對重要的程式分支進行測試以發現模組中的錯誤。在Python 語言下有諸多單元測試框架,如unittest、Pytest、nose 等,其中unittest框架(原名PyUnit 框架)為Python 語言自帶的單元測試框架,從Python 2.1 及其以後的版本都將PyUnit 作為一個標準模組放入Python 開發包中。
6.2.1 認識單元測試
單元測試本身就是通過一段程式碼去驗證另一個程式碼,所以不用單元測試框架也可以寫單元測試.
count.py
#coding=utf-8
class Count:
def __init__(self,a,b):
self.a=a
self.b=b
de fadd(self):
returnself.a+self.b
def sub(self):
return self.a-self.b
程式非常簡單,建立一個Count 類用來計算兩個數,通過__init__()方法對兩個數進行初始化,接著常見add()方法返回兩個數相加的結果, 接著常見sub()方法返回兩個數相減的結果。
通過手工方式所進行的單元測試可能是下面(testCount.py)這個樣子的:
#coding=utf-8
from count import Count
class TestCount:
def test_add(self):
try:
c=Count(4,5)
add=c.add()
assert(add==9),'Integer addition result error!'
excep tAssertionError,msg:
printmsg
else:
print"test pass!"
def test_sub(self):
try:
c=Count(9,2)
sub=c.sub()
assert(sub==7),'Integer addition result error!'
except AssertionError,msg:
printmsg
else:
print"test pass!"
mytest=TestCount()
mytest.test_add()
mytest.test_sub()
首先,引入count 檔案下的Count 類,在test_add()方法中呼叫Count 類並傳入兩個引數4,5,呼叫Count類中的add()方法對兩個引數做加法運算,通過assert()方法進行比較返回結果add 是否等於9;在test_sub()方法中呼叫Count 類並傳入兩個引數9,2,呼叫Count類中的sub()方法對兩個引數做加法運算,通過assert()方法進行比較返回結果add 是否等於7,如果不相等則丟擲自定義的“Integer addition result error!”異常資訊,如果相等則列印“testpass!”。
由於測試程式碼甚至比被測試的程式碼還多,則是要採用unittest 這一自動測試框架來構造單元測試用例。通過unittest 來寫單元測試:test_with_unittest.py
#coding=utf-8
from count import Count
import unittest
class TestCount(unittest.TestCase):
def setUp(self):
self.j=Count(4,5)
def test_add(self):
self.add=self.j.add()
self.assertEqual(self.add,9)
def test_sub(self):
self.sub=self.j.sub()
self.assertEqual(self.sub,-1)
def tearDown(self):
pass
if __name__=="__main__":
unittest.main()
用import 語句引入unittest 模組。在setUp()方法中進行測試前的初始化工作,這裡初始化了Count 類。在tearDown()方法中執行測試後的清除工作,因為沒什麼可清理的工作,通過pass 表示其為一個空的方法,什麼也不做。setUp()和tearDown()都是TestCase類中定義的方法。
在test_add()中呼叫assertEqual()方法,對Count 類中的add()方法的返回值和預期值進行比較,確保兩者是相等的,assertEqual()也是TestCase 類中定義的方法。
Unittest 提供了全域性的main()方法,使用它可以很方便地將一個單元測試模組變成可以直接執行的測試指令碼,main()方法使用TestLoader 類來搜尋所有包含在該模組中的測試方法,並自動執行它們。
6.2.2 unittest 中的概念
unittest 的文件中開篇就介紹了4 個重要的概念:test fixture, test case, test suite, test runner,我覺得只有理解了這幾個概念,才能真正的理解單元測試的基本原理。
Test case: 一個TestCase 的例項就是一個測試用例, 就是一個完整的測試流程,包括測試
前準備環境的搭建(setUp),實現測試過程的程式碼(run),以及測試後環境的還原(tearDown)。元測試(unittest)的本質也就在這裡,一個測試用例是一個完整的測試單元,通過執行這個測試單元,可以對某一個功能進行驗證。
test suite: 對一個功能的驗證往往是需要多測試用例的,可以把多的測試用例集合在一起執行,這就產生了測試套件TestSuite 的概念,它用來組裝單個測試用例,而且TestSuite 也可以巢狀TestSuite。
test runner: TextTestRunner 是來執行測試用例的,其中的run(test)用來執行TestSuite/TestCase。測試的結果會儲存到TextTestResult 例項中,包括運行了多少測試用例,成功了多少,失敗了多少等資訊。
test fixture: 對一個測試用例環境的搭建和銷燬,是一個fixture,通過覆蓋TestCase 的setUp()和tearDown()方法來實現.
TestSuit.py
#coding=utf-8
from count import Count
import unittest
class TestCount(unittest.TestCase):
def setUp(self):
self.j=Count(4,5)
def test_add(self):
self.add=self.j.add()
self.assertEqual(self.add,9)
def test_sub(self):
self.sub=self.j.sub()
self.assertEqual(self.sub,-1)
def tearDown(self):
pass
if __name__=="__main__":
suite=unittest.TestSuite()
suite.addTest(TestCount("test_add"))
suite.addTest(TestCount("test_sub"))
runner=unittest.TextTestRunner()
runner.run(suite)
首先呼叫unittest所提供的TESTSuite()類,通過它下面的addTest()方法來新增TestCount類下面的test_add()測試方法。接著呼叫TextTestRunner()類,通過它下面的run()方法來執行suite所組裝的測試用例。
6.2.3 編寫單元測試用例
unittest 框架的TestCase 類提供一些方法用檢查比較和報告失敗。
方法 檢查
assertEqual(a,b) a==b
assertNotEqual(a,b) a!=b
assertTrue(x) x is True
assertFalse(x) x is False
assertIs(a,b) a is b
assertIsNot(a,b) a is not b
assertIsNotNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a,b) a in b
assertNotIn(a,b) a not in b
assertIsInstance(a,b) isinstance(a,b)
assertNotInstance(a,b) notisinstance(a,b)
assertEqual(first, second, msg=None): 測試第一個和第二個是否是相等的,如果值不相等測試失敗。msg 是否可選有引數,用於定義測試失敗所要提示的資訊。
assertNotEqual(first, second, msg=None): 它用於判斷第一個與第二個是否是不相等的,如果相等測試失敗。
asserEqual.py
#coding=utf-8
import unittest
classTest(unittest.TestCase):
def setUp(self):
number=input("Enter anumber:")
self.number=number
def test_case_10(self):
self.assertEqual(self.number,10,msg='Your input is not 10!')
def test_case_0(self):
self.assertNotEqual(self.number,0,msg='Yourinput is not 0!')
def tearDown(self):
pass
if__name__=="__main__":
unittest.main()
#suit=unittest.TestSuite()
#suit.addTest(Test("test_case_10"))
#suit.addTest(Test("test_case_0"))
#runner=unittest.TextTestRunner()
#runner.run(suit)
assertTrue(expr, msg=None)
assertFalse(expr, msg=None)
用於測試表達式是true(或false)。
下面來實現一個判斷是否為質數功能,所謂的質數(又叫素數)是指只能被1 和它本身整除的數。
Count.py
#coding=utf-8
def is_prime(m):
if m<=1:
return False
for i in range(2,m):
if m%i==0:
return False
return True
關於判斷是否為質數的實現很簡單,當拿到一個數後如果能整除從2 與自身減1 之間的任意一個數說明其不為質數,返回False,否則返回Ture。
assertTrue.py
#coding=utf-8
import sys
sys.path.append("Lib")
from Lib import count
from count import is_prime
import unittest
class Test(unittest.TestCase):
def setUp(self):
pass
def test_is_prime(self):
self.prime=is_prime(4)
self.assertTrue(self.prime,msg="Is not prime!")
def tearDown(self):
pass
if __name__=="__main__":
unittest.main()
通過assertTrue()比較的結果一定不是Ture,那麼msg 中所定義的資訊將會被列印輸出。
assertIn(first, second, msg=None)
assertNotIn(first, second, msg=None)
測試第一個是否在第二個中,反過來講第二個是否包含第一個。
定義字串a 為“hello”,b 為“hello world”。通過assertIn 判斷b 是否包含a,如果不包含將列印msg 的定義的資訊。
assertIn.py
#coding=utf-8
import unittest
class Test(unittest.TestCase):
def setUp(self):
pass
def AssertIn_1(self):
self.a="hello"
self.b="helloworld"
self.assertIn(self.a,self.b,msg="a is not b")
def AssertNotIn_1(self):
self.a="good"
self.b="god god"
self.assertNotIn(self.a,self.b,msg="a is b")
def AssertIn_2(self):
self.a="hello"
self.b="hellworld"
self.assertIn(self.a,self.b,msg="a is not b")
def AssertNotIn_2(self):
self.a="good"
self.b="good god"
self.assertNotIn(self.a,self.b,msg="a is b")
def tearDown(self):
pass
if __name__=="__main__":
# unittest.main()
suite=unittest.TestSuite()
suite.addTest(Test("AssertIn_1"))
suite.addTest(Test("AssertNotIn_1"))
suite.addTest(Test("AssertIn_2"))
suite.addTest(Test("AssertNotIn_2"))
runner=unittest.TextTestRunner()
runner.run(suite)
定義字串a 為“hello”,b 為“hello world”。通過assertIn 判斷b 是否包含a,如果不包含將列印msg 的定義的資訊。
在使用單元測試框架時,我們只寫了一個用例,這顯然是不符合實際需求的,在實際的測試過程中真對一個功能,我們甚至要編寫幾個,甚至幾十個測試用例。下面就來介紹如何組織這些測試用例。
呼叫了TestSuite()類和TextTestRunner()分別來組織和執行測試用例。這樣做的好處是可以通過addTest()方法自由的新增想要被執行的用例。
assertIs(first, second, msg=None)
assertIsNot(first, second, msg=None)
測試第一個和第二個是否為同一物件。
assertIsNone(expr, msg=None)
assertIsNotNone(expr, msg=None)
測試表達式是否為None 物件。
assertIsInstance(obj, cls, msg=None)
assertNotIsInstance(obj, cls, msg=None)
測試物件(obj)是否有一個例項(cls)。
6.2.4 discover 更多測試用例
單元測試用例可能就會達到上百個,對於這種情況test.py檔案會變得很臃腫,需要把這些測試用例進行劃分,分散到不同的檔案中,這樣便於維護。
對test.py檔案的測試用例進行拆分,拆分的目錄結構如下:
../test_object/all_testcase.py
/testadd.py
/testsub.py
/lib/count.py
testadd.py
import sys
sys.path.append("TestFun")
from TestFun import count
from count import Count
import unittest
class TestAdd(unittest.TestCase):
def setUp(self):
pass
def test_add(self):
self.j=Count(2,3)
self.add=self.j.add()
self.assertEqual(self.add,5,msg='The two integer result not equal')
def test_add1(self):
self.j=Count(2.3,3.6)
self.add=self.j.add()
self.assertEqual(self.add,5.9,msg='The two float sum is not equal')
def test_add2(self):
self.j=Count("hello"," world")
self.add=self.j.add()
self.assertEqual(self.add,"hello world",msg='The two stringresult is not equal')
def tearDown(self):
pass
testSub.py
import sys
sys.path.append("TestFun")
from TestFunimport count
from countimport Count
import unittest
class TestSub(unittest.TestCase):
def setUp(self):
pass
def test_sub(self):
self.j=Count(2,3)
self.sub=self.j.sub()
self.assertEqual(self.sub,-1,msg='The two integer result not equal')
def test_sub1(self):
self.j=Count(4.3,3.3)
self.sub=self.j.sub()
self.assertEqual(self.sub,1,msg='The two float resutl is not equal')
def tearDown(self):
pass
All_project.py
#coding=utf-8
import unittest
from testAdd import TestAdd
from testSub import TestSub
suite=unittest.TestSuite()
suite.addTest(TestAdd("test_add"))
suite.addTest(TestAdd("test_add1"))
suite.addTest(TestAdd("test_add2"))
suite.addTest(TestSub("test_sub"))
suite.addTest(TestSub("test_sub1"))
if__name__=="__main__":
runner=unittest.TextTestRunner()
runner.run(suite)
TestFun/__init__.py
import count
TestFun/count.py
#coding=utf-8
class Count:
def __init__(self,a,b):
self.a=a
self.b=b
def add(self):
return self.a+self.b
def sub(self):
return self.a-self.b
在上同的程式碼中,建立testadd.py 和testsub.py 分別用於測試count.py 中的add()和subtraction()兩個方法。在每個測試檔案中,可以通過addTest()任意的載入當前要執行測試用例。
接著建立all_test.py 檔案,在這個檔案中首先匯入不同的測試檔案,通過addTest()來載入所有的測試檔案下面的測試類下面的測試用例,最終通過TextTestRunner()類來執行所有用例。
這樣的設計看上去很完美,當用例達到成百上千條時在all_test.py 檔案中addTest()測試用例就變成了一條純的體力活兒,那麼有沒有更好的辦法unittest 可以自己識別不同測試檔案不同測試類下面的測試用例呢。在TestLoader類中提供了discover()方法可以解決這個問題。
TestLoader:該類根據各種標準負責載入測試用例,並它們返回給測試套件。正常情況下沒有必要建立這個類的例項。unittest 提供了可以共享了defaultTestLoader 類,可以使用其子類和方法建立例項,所以我們可以使用其下面的discover()方法來建立一個例項。
discover(start_dir,pattern='test*.py',top_level_dir=None)
找到指定目錄下所有測試模組,並可遞迴查到子目錄下的測試模組,只有匹配到檔名才能被載入。如果啟動的不是頂層目錄,那麼頂層目錄必須要單獨指定。
start_dir :要測試的模組名或測試用例目錄。
pattern='test*.py' :表示用例檔名的匹配原則。星號“*”表示任意多個字元。
top_level_dir=None:測試模組的頂層目錄。如果沒頂層目錄(也就是說測試用例不是放在多級目錄中),預設為None。
Discover.py
#coding=utf-8
importunittest
def creatSuite():
testunit=unittest.TestSuite()
test_dir='C:\\Users\\ewang\\Desktop\\Python_Selenium2\\UnitTest\\Test_project'
discover=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',top_level_dir=None)
for test_suite in discover:
for test_case in test_suite:
testunit.addTest(test_case)
print testunit
return testunit
if__name__=="__main__":
alltestname=creatSuite()
runner=unittest.TextTestRunner()
runner.run(alltestname)
建立creatsuite()函式用於查詢指定條件的下的所有測試用例,並將其組裝到測試套件中。呼叫discover()方法,首先通過test_dir 定義查詢測試檔案的目錄,pattern 用來定義匹配測試檔案的檔名,如果檔名以test 開頭的.py 檔案,那麼就認為它是一個測試檔案。top_level_dir 預設為None。discover()只能找到了測試檔案,接下來通過for 迴圈來找到測試檔案下的每一個測試用例,並且將其新增測試套件中。
說明一個測試用例的建立規則:我們在實際的測試用開發中用例的建立也應該分兩個階段,
用例剛在目錄下被建立,可命名為aa.py ,當用例建立完成並且執行穩定後再新增到測試套件中。那麼可以將aa.py 重新命名為start_aa.py ,那麼測試套件在執行時只識別並執行start 開頭的.py 檔案。對於檔名的匹配規則完全由discover()方法中的pattern 引數決定。
6.3用unittest 編寫web 自動化
在動手寫指令碼之後前,我們先來簡單的規劃一個測試專案的目錄:
.../test_project/all_test.py
/test_case/test_baidu.py
All_test.py/test_case/test_youdao.py
/report/log.txt
#coding=utf-8
import unittest
def creatSuite():
testunit=unittest.TestSuite()
test_dir="C:\\Users\\ewang\\Desktop\\Python_Selenium2\\UnitTest\\Project\\test_case"
discover=unittest.defaultTestLoader.discover(test_dir,pattern="test*.py",top_level_dir=None)
for test_suit in discover:
for test_case in test_suit:
testunit.addTest(test_case)
return testunit
if __name__=="__main__":
alltest=creatSuite()
runner=unittest.TextTestRunner()
runner.run(alltest)
或者run_all.py:
import unittest
import sys
sys.path.append("test_case")
from test_case import testBaidu
from test_case import testYoudao
suite=unittest.TestSuite()
suite.addTest(testBaidu.MyTest("test_baidu"))
suite.addTest(testYoudao.MyTest("test_youdao"))
if __name__=="__main__":
runner=unittest.TextTestRunner()
runner.run(suite)
test_case/__init__.py
import testBaidu,testYoudao
/test_case/test_baidu.py
#coding=utf-8
from selenium importwebdriver
import unittest,time
classMyTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(10)
self.base_url ="http://www.baidu.com"
def test_baidu(self):
driver = self.driver
driver.get(self.base_url +"/")
driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys("unittest")
driver.find_element_by_id("su").click()
time.sleep(2)
title = driver.title
self.assertEqual(title,u"unittest_百度搜索")
def tearDown(self):
self.driver.quit()
/test_case/test_youdao.py
#coding=utf-8
from selenium importwebdriver
import unittest,time
classMyTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(10)
self.base_url ="http://www.youdao.com"
def test_youdao(self):
driver = self.driver
driver.get(self.base_url +"/")
driver.find_element_by_id("query").clear()
driver.find_element_by_id("query").send_keys("webdriver")
driver.find_element_by_id("qb").click()
time.sleep(2)
title = driver.title
self.assertEqual(title,u"webdriver- 有道搜尋")
def tearDown(self):
self.driver.quit()
儲存測試結果:
首先開啟Windows 命令提示符,進入到.../test_project/目錄下執行名命令:
>Python all_test.py >> report/log.txt2>&1
Python all_test.py 通過Python 執行all_test 檔案
>>report/log.txt 將測試輸出寫入到report目錄下的log.txt 檔案中
file 2>&1 標準輸出被重定向到檔案file,然後錯誤輸出也重定向到和標準輸出一樣,所以錯誤輸出也寫入檔案file。
6.4 用例執行的疑惑
用例執行的順序:首先是同步測試問題,不同測試類測試方法的執行順序的,同一目錄下不同測試檔案的執行順序。
預設載入順序是根據ASCII 碼的順序,數字與字母的順序為:0~9,A~Z,a~z
通過測試套件的addTest()根據需求來載入,可以確定執行順序,但這隻限制於單個檔案,如果用例多了,最省力的還是直接使用main()來載入測試用例。discover()方法載入用例也是按照ASCII 碼的從小到大的順序來載入同一目錄下測試檔案的,這個就更難控制了,我們唯一能做的就是通過測試檔案的命名來為其排列執行順序。
有時候測試的業務多了就要對測試用例進行劃分目錄,例如我們下面的測試目錄:
.../test_case/test_aa.py
/test_aaa/test_a.py
/test_aaa/test_ccc/test_c.py
/test_bbb/test_b.py
對於上面的目錄結構,如果將discover()方法中start_dir 引數定義為“.../test_case/”目錄,只能執行test_aa.py 檔案,對於“/test_aaa/”、“/test_aaa/test_ccc/”和“/test_bbb/”等二級、三級目錄下的用例將不會被執行。如果想被discover()讀取執行非常簡單,在目錄下新增__init__.py 檔案。
.../test_case/test_aa.py
/test_aaa/test_a.py
/test_aaa/__init__.py
/test_aaa/test_ccc/test_c.py
/test_aaa/test_ccc/__init__.py
/test_bbb/test_b.py
/test_bbb/__init__.py
Test_project/All_project.py
#coding=utf-8
import unittest
from testAdd import TestAdd
from testSub import TestSub
suite=unittest.TestSuite()
suite.addTest(TestAdd("test_add"))
suite.addTest(TestAdd("test_add1"))
suite.addTest(TestAdd("test_add2"))
suite.addTest(TestSub("test_sub"))
suite.addTest(TestSub("test_sub1"))
if __name__=="__main__":
runner=unittest.TextTestRunner()
runner.run(suite)
Test_project/discover.py
#coding=utf-8
import unittest
def creatSuite():
testunit=unittest.TestSuite()
test_dir='C:\\Users\\ewang\\Desktop\\Python_Selenium2\\UnitTest\\Test_project'
discover=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',top_level_dir=None)
for test_suite in discover:
for test_case in test_suite:
testunit.addTest(test_case)
print testunit
return testunit
if __name__=="__main__":
alltestname=creatSuite()
runner=unittest.TextTestRunner()
runner.run(alltestname)
Test_project/run_all.py
#coding=utf-8
import unittest
def creatSuite():
testunit=unittest.TestSuite()
test_dir='C:\\Users\\ewang\\Desktop\\Python_Selenium2\\UnitTest\\Test_project\\TestCase'
discover=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',top_level_dir=None)
for test_suite in discover:
for test_case in test_suite:
testunit.addTest(test_case)
print testunit
return testunit
if __name__=="__main__":
alltestname=creatSuite()
runner=unittest.TextTestRunner()
runner.run(alltestname)
Test_project/testAdd.py
import sys
sys.path.append("TestFun")
from TestFun import count
from count import Count
import unittest
class TestAdd(unittest.TestCase):
def setUp(self):
pass
def test_add(self):
self.j=Count(2,3)
self.add=self.j.add()
self.assertEqual(self.add,5,msg='The two integer result not equal')
def test_add1(self):
self.j=Count(2.3,3.6)
self.add=self.j.add()
self.assertEqual(self.add,5.9,msg='The two float sum is not equal')
def test_add2(self):
self.j=Count("hello"," world")
self.add=self.j.add()
self.assertEqual(self.add,"hello world",msg='The two string result is not equal')
def tearDown(self):
pass
Test_project/testSub.py
import sys
sys.path.append("TestFun")
from TestFun import count
from count import Count
import unittest
class TestSub(unittest.TestCase):
def setUp(self):
pass
def test_sub(self):
self.j=Count(2,3)
self.sub=self.j.sub()
self.assertEqual(self.sub,-1,msg='The two integer result not equal')
def test_sub1(self):
self.j=Count(4.3,3.3)
self.sub=self.j.sub()
self.assertEqual(self.sub,1,msg='The two float resutl is not equal')
def tearDown(self):
pass
.../test_case/test_aa.py
#coding=utf-8
import sys
sys.path.append("TestFun")
from TestFun import count
from count import Count
import unittest
class TestBdd(unittest.TestCase):
def setUp(self):
pass
def test_aa(self):
self.j = Count(2,3)
self.add = self.j.add()
self.assertEqual(self.add,5)
print 'test1'
def tearDown(self):
pass
/test_aaa/test_a.py
#coding=utf-8
import sys
sys.path.append("TestFun")
from TestFun import count
from count import Count
import unittest
class TestAdd(unittest.TestCase):
def setUp(self):
pass
def test_a(self):
self.j = Count(2.5,3)
self.add = self.j.add()
self.assertEqual(self.add,5.5)
print 'test1'
def tearDown(self):
pass
/test_aaa/__init__.py
import test_a
/test_aaa/test_ccc/test_c.py
#coding=utf-8
import sys
sys.path.append("TestFun")
from TestFun import count
from count import Count
import unittest
class TestAdd(unittest.TestCase):
def setUp(self):
pass
def test_c(self):
self.j = Count("hello"," world")
self.add = self.j.add()
self.assertEqual(self.add,"hello world")
print 'test1'
def tearDown(self):
pass
/test_aaa/test_ccc/__init__.py
import test_c
/test_bbb/test_b.py
#coding=utf-8
import sys
sys.path.append("TestFun")
from TestFun import count
from count import Count
import unittest
class TestAdd(unittest.TestCase):
def setUp(self):
pass
def test_b(self):
self.j = Count("hello 123"," world")
self.add = self.j.add()
self.assertEqual(self.add,"hello world")
print 'test1'
def tearDown(self):
pass
/test_bbb/__init__.py
import test_b
Test_project/TestFun/count.py
#coding=utf-8
class Count:
def __init__(self,a,b):
self.a=a
self.b=b
def add(self):
return self.a+self.b
def sub(self):
return self.a-self.b
Test_project/TestFun/__init__.py
import count
相關推薦
Selenium2 Python 自動化測試實戰學習筆記(四)
第五章 自動化測試模型 一個自動化測試框架就是一個整合體系,在這一體系中包含測試功能的函式庫、測試資料來源、測試物件識別標準,以及種可重用的模組。自動化測試框架在發展的過程中經歷了幾個階段,線性測試、模組驅動測試、資料驅動測試、關鍵字驅動測試。 Pytho
Selenium2 Python 自動化測試實戰學習筆記
第一章 自動化測試基礎 1.1 軟體測試分類 軟體測試 V 模型: 需求分析---設計---編碼 驗收測試--------系統測試---整合測試—單元測試 單元測試:是對程式中的單個子程式或具有獨立功能的程式碼段進行測試的過程 整合測試:檢查模組之間的介面是否正確 系統
Web自動化測試Selenium 學習筆記(一)
1、Web自動化測試簡介自動化基礎:自動化用例編寫、Selenium優勢及原理、自動化環境搭建Selenium基礎:常見8大元素定位(表格)、常見元素處理、下拉框元素處理、不同視窗切換、元素進階、元素等待需求到框架 需求分析-用例設計-基礎指令碼-登入/購物指令碼重構-
Spark (Python版) 零基礎學習筆記(四)—— Spark概覽
結合了《Learning Spark: Lightning-Fast Big Data Analysis》和官方2.02版本的Spark Document總結了關於Spark概念性的一些知識。幫助大家對Spark有一個總體上的認知 一、Spark的兩個核心概念
船長帶你看書——《selenium2 python 自動化測試實戰》(2)瀏覽器操作
python lin div 看書 名稱 ext ice 微信公眾號 很難 瀏覽器操作 # coding: utf-8 from selenium import webdriver from time import sleep driver = webdriver.Fi
《selenium2 python 自動化測試實戰》(5)——鍵盤事件
display 技術 添加 lan data- vbs nbsp .cn images 鍵盤事件,就是鍵盤上的一些操作,比如Ctrl +C,Ctrl+V,Ctrl+X等。 對鍵盤的操作需要導入另一個鍵盤的庫: from selenium.webdriver.commo
《selenium2 python 自動化測試實戰》(13)——上傳文件
dml 實戰 文件的 -c pbm erl sel png flow 看代碼: # coding: utf-8 from selenium import webdriver from time import sleep driver = webdriver.Fir
《selenium2 python 自動化測試實戰》(21)——unittest單元測試框架解析
nbsp add pic post 二維碼 mage ron 而且 aaa unittest是展開自動化測試的基礎——這個框架很重要! 我們先自己寫一個測試類: 1、被測試類 Widthget.py: # coding: utf-8class Wi
《selenium2 python 自動化測試實戰》(20)——Selenium工具介紹
命令 aic 插件 rhui 所有 key 框架 地址欄 uga (一)Selenium IDE Firefox的一個插件,有助於我們理解測試框架。在附加組件裏搜索下載,一般搜的結果裏前幾個都不是,得點那個查看更多才行,找到這個: 安裝以後瀏覽器工具欄會有
Python自動化學習筆記(四)——Python資料型別(集合set,元組tuple)、修改檔案、函式、random常用方法
1.修改檔案的兩種方式 1 #第一種 2 with open('users','a+') as fw: #用a+模式開啟檔案,使用with這種語法可以防止忘記close檔案 3 fw.seek(0) #移動檔案指標到最前面,然後才能讀到內容 4 result=fw.read()
Python資料探勘學習筆記(12)淘寶圖片爬蟲實戰
所謂圖片爬蟲,即是從網際網路中自動把對方伺服器上的圖片爬下來的爬蟲程式。 一、圖片爬蟲前的網頁連結分析 1.首先開啟淘寶首頁,在搜尋框中輸入關鍵詞,如“神舟”,在搜尋結果介面中點選下一頁,分別開啟第一頁,第二頁,第三頁的搜尋結果,並記下每一頁結果的URL至記
Python資料分析與挖掘實戰學習筆記(一)
資料預處理1. 資料清洗(1)缺失值處理三種方法:刪除記錄、資料插補、不處理常見插補方法:均值/中位數/眾數插補、使用固定值/期望值、迴歸方法(根據已有資料和其他與其有關變數等建立擬合模型來預測)、插值法(利用已知點建立合適的插值函式,如拉格朗日函式)我們以餐廳銷量資
python框架之 Tornado 學習筆記(一)
tornado pythontornado 一個簡單的服務器的例子:首先,我們需要安裝 tornado ,安裝比較簡單: pip install tornado 測試安裝是否成功,可以打開python 終端,輸入: import tornado.https
Python學習筆記(四) 列表生成式_生成器
rec triangle 小寫 ont 無限 end clas 普通 執行過程 筆記摘抄來自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431
Selenium2+python自動化56-unittest之斷言(assert)【轉載】
用例 lists tca enc whether set .py exce req 前言 在測試用例中,執行完測試用例後,最後一步是判斷測試結果是pass還是fail,自動化測試腳本裏面一般把這種生成測試結果的方法稱為斷言(assert)。 用unittest組件測試用例的
Selenium2+python自動化49-判斷文本(text_to_be_present_in_element)【轉載】
cvpr cor 搜索 odin present u+ 3ds ndb wii 前言 在做結果判斷的時候,經常想判斷某個元素中是否存在指定的文本,如登錄後判斷頁面中是賬號是否是該用戶的用戶名。 在前面的登錄案例中,寫了一個簡單的方法,但不是公用的,在EC模塊有個方法是可以專
python學習筆記(四)-數據類型
rand 兩個 urn 浪費 line 平年 randint .com .cn 0. 在 Python 中的數據類型詳解 http://www.cnblogs.com/scios/p/8026576.html 1. 為什麽布爾類型(bool)的 True 和 False 分
python學習筆記(四)字符串及字符串操作
默認 小寫字母 是不是 swap git 查找字符 英文 去掉 title 字符串 字符串可以存任意類型的字符串,比如名字,一句話等等。 字符串還有很多內置方法,對字符串進行操作,常用的方法如下: 1 name1=‘hello world‘ 2 print(nam
day3-python學習筆記(四)
end tar upper date update size upd sdi reat 字符串方法 #字符串這些方法都不會改變原來字符串的值name = ‘beSTtest‘# new_name = name.strip()#默認是去掉空格和換行符# new_name =
Python第三周 學習筆記(2)
學習筆記選擇排序: 時間復雜度O(n**2) 沒有辦法知道當前輪是否已經達到排序要求,但是可以知道極值是否在目標索引位置上 遍歷次數1,...,n-1之和n(n-1)/2 對比冒泡法:減少了交換次數,提高了效率,性能略好 方法三、四實際上降低的是平均時間復雜度 方法一: nums = [1, 2, 6,