unittest組成部分:
TestCase:測試用例,測試用例里面會有很多測試方法,是單元測試中最小維度的測試行為
Test Fixure:測試固件,測試固件是執行測試時的准備工作和收尾工作(打開和關閉瀏覽器,鏈接和關閉數據庫)
TestSuite:測試套件,是測試用例的集合
TestRunner:測試運行器,運行測試用例
TestReport:將測試結果呈現給用戶,生成測試報告
測試斷言:期望結果
1、在unittest單元測試框架中,提供了兩種單元測試的加載方法:
A、直接通過unittest.main()方法加載單元測試的測試模塊,所有的測試方法執行順序都是按照方法名的字符串表示的ASCII碼升序排序;
B、將所有的單元測試用例添加到測試套件集合中,然后一次性加載所有測試對象;
2、忽略某個測試方法:
#coding=utf-8
import random
import unittest
import sys
class TestSequenceFunctions(unittest.TestCase):
a=1
def setUp(self):
self.seq=range(10)
@unittest.skip("skipping") #無條件忽略該測試方法
def test_shuffle(self):
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq,list(range(10)))
self.assertRaises(TypeError,random.shuffle,(1,2,3))
@unittest.skipIf(a>5,"contain is not satisfied!") #如果該變量a>5則忽略該測試方法
def test_choice(self):
element=random.choice(self.seq)
self.assertTrue(element in self.seq)
#除非執行測試用例的平台是Windows平台,否則忽略該測試方法
@unittest.skipUnless(sys.platform.startswith("linux"),"requeire Windows")
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq,20)
for element in random.sample(self.seq,5):
self.assertTrue(element in self.seq)
if __name__=='__main__':
testCases=unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
suite=unittest.TestSuite(testCases)
unittest.TextTestRunner(verbosity=2).run(suite)
3、調用測試用例方法:
if __name__=='__main__':
#根據給定的測試類,獲取其中所有以“test”開頭的測試方法,並返回一個測試套件
testcase1=unittest.TestLoader().loadTestsFromTestCase(TestSequencesFunctions)
testcase2=unittest.TestLoader().loadTestsFromTestCase(TestshulleFuction)
#將多個測試類加載到測試組件中
suite=unittest.TestSuite(testcase1,testcase2)
#設置verbosi=2可以打印出更詳細的執行信息
unittest.TextTestRunner(verbosity=2).run(suite)
if __name__=='__main__':
#獲取TestSuite的實例對象
testsuite=unittest.TestSuite()
#將測試用例添加到測試容器中
testsuite.addTest(MyTest("test_add"))
testsuite.addTest(MyTest("test_sub"))
#創建TextTestRunner類的實例對象
runner=unittest.TextTestRunner()
runner.run(testsuite)
if __name__=='__main__':
#加載當前目錄下所有有效的測試模塊.“表示當前目錄下”
testSuite=unittest.TestLoader().discover('.')
unittest.TextTestRunner(verbosity=2).run(testSuite)
備注:
A、設置verbosity<=0的數字,輸出結果中不提示執行成功的用例數;
B、設置verbosity=1的數字,輸出結果中僅以點表示執行成功的用例數;
C、設置verbosity>=2的數字,可以輸出每個用例執行的詳細信息,特別是大批量時,能夠顯示具體執行出錯的用例;
4、運用命令執行測試用例:
A、通過命令直接運行整個測試模塊:python -m unittest test_module1 test_module1;
B、執行某個模塊中的某個測試類:python -m unittest test_module1.TestClass;
C、執行某個模塊中某個測試類下的某個測試方法:python -m unittest test_module1.TestClass.test_method;
5、軟件測試中最基本的組成單元是測試用例,unittest框架通過TestCase類來構建測試用例,並要求所有自定義的測試類都必須繼承該類,它是所有測試用例的基類,傳入一個測試方法名,將返回一個測試用例實例。
6、TestCase類的幾個特殊方法如下:
A、setUp():每個測試方法運行前運行,測試前的初始化操作;
B、tearDown():每個測試方法運行結束后運行,測試后的清理工作;
C、setUpClass():所有的測試方法運行前運行,單元測試前期准備,必須使用@classmethod裝飾器進行修飾,setUp()函數之前執行,整個測試過程只執行一次;
D、tearDownClass():所有的測試方法運行結束后執行,單元測試后期清理,必須使用@classmethod裝飾器進行修飾,tearDown之后執行,整個測試過程中只執行一次;
7、測試集合
# coding = utf-8
import unittest
import random
class TestSequence(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def test_sequence(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
class TestShuffle(unittest.TestCase):
def setUp(self):
self.seq = list(range(10))
def test_shuffle(self):
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, list(range(10)), "數值不相等")
self.assertRaises(TypeError, random.shuffle, (1, 2, 3))
if __name__ == '__main__':
suitetest1 = unittest.TestLoader().loadTestsFromTestCase(TestSequence)
suitetest2 = unittest.TestLoader().loadTestsFromTestCase(TestShuffle)
suite=unittest.TestSuite([suitetest1, suitetest2])
unittest.TextTestRunner(verbosity=2).run(suite)
備注:
TestLoader類:測試用例加載器,返回一個測試用例集合;
LoadTestsFromTestCase類:根據給定的測試類,獲取其中的所有的以test開頭的測試方法,並返回一個測試集合;
TestSuite類:組裝測試用例的實例,支持添加和刪除用例,最后將傳遞給testrunner進行測試執行;
TextTestRunner類:測試用例執行類,其中的Text表示以文本形式輸出測試結果;
更多說明:
設置verbosity<=0:輸出結果中不提示執行成功的用例數;
設置verbosity=1:輸出結果中僅以.表示執行成功的用例數;
設置verbosity>=2:可以輸出每個測試用例的執行信息,特別是在大批量時能夠清楚的定位出錯的測試用例;
8、按照特定順序執行測試用例:
# coding = utf-8
import unittest
class Calc(object):
def sum(self, x, y, *d):
result = x+y
for i in d:
result += i
return result
def sub(self, x, y, *d):
result = x-y
for i in d:
result -= i
return result
@classmethod
def mul(cls, x, y, *d):
result = x*y
for i in d:
result = result*i
return result
@classmethod
def div(cls, x, y, *d):
if y != 0:
result = x/y
else:
return -1
for i in d:
if i != 0:
result = result/i
else:
return -1
return result
class Mytest(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.c = Calc()
@classmethod
def tearDownClass(cls):
pass
def setUp(self):
print("開始")
def test_sum(self):
print("run sum")
self.assertEqual(Mytest.c.sum(1,2), 3, "sum error")
def test_sub(self):
print("run sub")
self.assertEqual(Mytest.c.sub(1,2), -1, "sub error")
def test_mul(self):
print("run mul")
self.assertEqual(Calc.mul(1,2), 2, "mul error")
def test_div(self):
print("run div")
self.assertEqual(Calc.div(2,1), 2, "div error")
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTest(Mytest("test_sum"))
suite.addTest(Mytest("test_sub"))
suite.addTest(Mytest("test_mul"))
suite.addTest(Mytest("test_div"))
runner = unittest.TextTestRunner()
runner.run(suite)
#unittest.TextTestRunner.run()
# unittest.main()
9、忽略某個測試方法:
# coding = utf-8
import unittest
import random
import sys
class TestSequenceFunctions(unittest.TestCase):
a = 1
def setUp(self):
self.seq = range(10)
#無條件忽略該測試用例
@unittest.skip("skipping")
def test_shuffle(self):
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, list(range(10)))
#如果變量a>5則忽略該測試方法
@unittest.skipIf(a>5, "Conditons is not satisfied")
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
self.assertRaises(TypeError, random.shuffle, (1, 2, 3))
#除非執行測試用例的平台是Windows平台,否則忽略該測試平台
@unittest.skipUnless(sys.platform.startswith("Linux"), "require windows")
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
if __name__ == '—__main__':
testCases = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
suite = unittest.TestSuite(testCases)
unittest.TextTestRunner(verbosity=2).run(suite)
10、批量執行測試模塊
import unittest
if __name__=='__main__':
testsuite = unittest.TestLoader().discover('.')
unittest.TextTestRunner(verbosity=2).run(testsuite)
11、命令行模式執行測試用例:
前提是先在cmd中切換到當前工作目錄:
A、通過命令直接運行某個測試模塊:python -m unittest test_module1 test_module2;
B、執行某個測試模塊中某個測試類:python -m unittest -v test_module.TestClass;
C、執行測試模塊中某個測試類下的某個測試方法:python -m unittest test_module.TestClass.test_method;
D、批量執行命令:python -m unittest discover;
E、參數-v:輸出詳細的測試信息,比如python -m unittest discover -v;
F、參數-s:執行發現測試腳本的目錄,默認為當前目錄,比如python -m unittest discover -v -s 'D:\PyhtonProject\project_discover';
G、參數-p:模式匹配測試文件:python -m unittest discover -p “test*.py”;
12、使用HTMLTestRunner生成HTML測試日報:
# coding = utf-8
import unittest
import HTMLTestRunner
import math
import os.path
class Calc(object):
def add(self, x, y, *d):
result = x+y
for i in d:
result +=i
return result
def sub(self, x, y, *d):
result = x-y
for i in d:
result -=i
return result
class SuiteTestCalc(unittest.TestCase):
def setUp(self):
self.c = Calc()
def test_sub(self):
print("sub")
self.assertEqual(self.c.sub(5, 2), 3, "error")
def test_add(self):
print("add")
self.assertEqual(self.c.add(1, 2), 3, "error")
class SuiteTestPow(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def pow(self):
print("pow")
self.assertEqual(pow(2,3), 8, "error")
def hasatrr(self):
print("hasatrr")
self.assertTrue(hasattr(math, 'pow'))
if __name__ == '__main__':
suite1 = unittest.TestLoader().loadTestsFromTestCase(SuiteTestCalc)
suite2 = unittest.TestLoader().loadTestsFromTestCase(SuiteTestPow)
suite = unittest.TestSuite([suite1, suite2])
filename = "d:\\test.html"
fp = open(filename,'wb')
runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title ="report_title", description='Report_description')
runner.run(suite)
13、操作JavaScript的Alert彈框:
# coding = utf-8
import unittest
import time
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
class test(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path="D:\\software\\chromedriver")
def test_alert(self):
self.driver.get("http://localhost:63342/pydj/practice/alert.html?_ijt=n2pc3ulopem47bbv08ltt53hfb")
time.sleep(2)
self.driver.find_element_by_id("button").click()
try:
alert = self.driver.switch_to_alert()
time.sleep(2)
self.assertNotEqual(alert.text, u"這是一個alert彈出框")
alert.accept()
except NoAlertPresentException:
print(NoAlertPresentException)
if __name__ == '__main__':
unittest.main()
14、使用JavaScript操作prompt彈窗
# coding = utf-8
import unittest
import time
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
class test(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path="D:\\software\\chromedriver")
def test_alert(self):
self.driver.get("http://localhost:63342/pydj/practice/alert.html?_ijt=n2pc3ulopem47bbv08ltt53hfb")
time.sleep(2)
self.driver.find_element_by_id("button").click()
try:
alert = self.driver.switch_to_alert()
time.sleep(2)
self.assertNotEqual(alert.text, u"這是一個prompt彈出框")
alert.accept()
alert.dismiss()
except NoAlertPresentException:
print(NoAlertPresentException)
if __name__ == '__main__':
unittest.main()
15、使用JavaScript操作confirm彈窗
# coding = utf-8
import unittest
import time
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
class test(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome(executable_path="D:\\software\\chromedriver")
def test_alert(self):
self.driver.get("http://localhost:63342/pydj/practice/alert.html?_ijt=n2pc3ulopem47bbv08ltt53hfb")
time.sleep(2)
self.driver.find_element_by_id("button").click()
try:
alert = self.driver.switch_to_alert()
time.sleep(2)
self.assertNotEqual(alert.text, u"這是一個prompt彈出框")
alert.accept()
alert.dismiss()
except NoAlertPresentException:
print(NoAlertPresentException)
if __name__ == '__main__':
unittest.main()
16、無人工干預地自動下載某個文件:
17、無人工干預地自動上傳附件
18、模擬鍵盤操作上傳文件:
19、使用第三方工具AutoIt上傳:
20、右鍵另存為下載文件:
21、禁用Firefox瀏覽器中的CSS、Flash及Image加載:
# coding = utf-8
import unittest
from selenium import webdriver
import time
class TestDemo(unittest.TestCase):
def setUp(self):
# 創建Firefox瀏覽器的一個Options實例對象
profile = webdriver.FirefoxProfile()
# 禁用CSS加載
profile.set_preference("permissions.default.stylesheet", 2)
# 禁用image加載
profile.set_preference("permissions.default.image", 2)
# 禁用Flash加載
profile.set_preference("dom.ipc.plugins.enabled.libflashplayer.so", False)
# 啟動帶有自定義設置的Firefox瀏覽器
self.driver = webdriver.Firefox(executable_path="c:\\geckdriver", firefox_options=profile)
def test_forbidImage(self):
self.driver.get("http://www.baidu.com")
time.sleep(2)
def tearDown(self):
self.driver.quit()
if __name__=='__main__':
unittest.main()