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()