详解python单元测试框架unittest
一:unittest是python自带的一个单元测试框架,类似于java的junit,基本结构是类似的。
基本用法如下:
1.用importunittest导入unittest模块
2.定义一个继承自unittest.TestCase的测试用例类,如
classabcd(unittest.TestCase):
3.定义setUp和tearDown,这两个方法与junit相同,即如果定义了则会在每个测试case执行前先执行setUp方法,执行完毕后执行tearDown方法。
4.定义测试用例,名字以test开头,unittest会自动将test开头的方法放入测试用例集中。
5.一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。
6.调用unittest.main()启动测试
7.如果测试未通过,则会显示e,并给出具体的错误(此处为程序问题导致)。如果测试失败则显示为f,测试通过为.,如有多个testcase,则结果依次显示。
一个单testcase的简单的例子:
#-*-coding:UTF-8-*- ''' Createdon2015年3月24日 @author:Administrator ''' importunittest fromseleniumimportwebdriver importtime classTestCase1(unittest.TestCase): defsetUp(self): self.driver=webdriver.Firefox() self.base_url="http://www.baidu.com" deftearDown(self): self.driver.quit() deftestCase1(self): driver=self.driver driver.get(self.base_url) print"将窗口最大化" driver.maximize_window() time.sleep(10) if__name__=="__main__": unittest.main()
一个多testcase的例子:
#-*-coding:UTF-8-*- ''' Createdon @author:Administrator ''' fromseleniumimportwebdriver fromselenium.webdriver.common.byimportBy fromselenium.webdriver.common.keysimportKeys fromselenium.webdriver.common.action_chainsimportActionChains fromselenium.webdriver.support.uiimportWebDriverWait fromselenium.webdriver.support.uiimportSelect fromselenium.common.exceptionsimportNoSuchElementException,\ NoAlertPresentException importHTMLTestRunner #formselenium.common.exceptionsimportNoAlertPresentException importunittest,time,re classBaidu(unittest.TestCase): defsetUp(self): self.driver=webdriver.Firefox() self.driver.implicitly_wait(30) self.base_url="http://www.baidu.com/?tn=98012088_4_dg&ch=3" self.verificationErrors=[] self.accept_next_alert=True self.driver.get(self.base_url) deftest_baidu_search(self): '''百度搜索''' driver=self.driver #driver.get(self.base_url+"/") try: driver.find_element_by_id("kw").send_keys("seleniumwebdriver") driver.find_element_by_id("su").click() except: driver.get_screenshot_as_file('D:\\workspace\\python_prictise\\src\\error.png') time.sleep(2) driver.close() deftest_baidu_set(self): '''百度新闻''' driver=self.driver driver.find_element_by_name("tj_trnews").click() self.assertEqual(driver.title,u'百度新闻搜索——全球最大的中文新闻平台',"switchtobaidunewsfaile!") #time.sleep(2) defis_element_present(self,how,what): try:self.driver.find_element(by=how,value=what) exceptNoSuchElementException:returnFalse returnTrue defis_alert_present(self): try:self.driver.switch_to_alert() exceptNoAlertPresentException:returnFalse returnTrue defclose_alert_and_get_its_text(self): try: alert=self.driver.switch_to_alert() alert_text=alert.text ifself.accept_next_alert: alert.accept() else: alert.dismiss() returnalert_text finally:self.accept_next_alert=True deftearDown(self): self.driver.quit() self.assertEqual([],self.verificationErrors) if__name__=="__main__": unittest.main()
二:跳过单个testcase和testclass的方法
在unittest中也支持类似junit中的跳过单个测试case或者测试class的方法,如下:
@unittest.skip(reason)
无条件的跳过被修饰的testcase或者testclass,reason描述为何跳过该测试,为一个字符串;
@unittest.skipIf(condition,reason)
如果条件condition为真,则跳过该testcase或者testclass;
@unittest.skipUnless(condition,reason)
除非条件condition为真,否则跳过被修饰的testcase或者testclass;
@unittest.expectedFailure
标记测试为一个预期失败的测试,但不会作为失败测试统计在结果中;
三:断言
在unittest中用断言来判断是pass还是fail,常见的断言方法如下:
assertEqual(a,b)a==b
assertNotEqual(a,b)a!=b
assertTrue(x)bool(x)isTrue
assertFalse(x)bool(x)isFalse
assertIs(a,b)aisb
assertIsNot(a,b)aisnotb
assertIsNone(x)xisNone
assertIsNotNone(x)xisnotNone
assertIn(a,b)ainb
assertNotIn(a,b)anotinb
assertIsInstance(a,b)isinstance(a,b)
assertNotIsInstance(a,b)notisinstance(a,b)
assertAlmostEqual(a,b)round(a-b,7)==0
assertNotAlmostEqual(a,b)round(a-b,7)!=0
assertGreater(a,b)a>b2.7
assertGreaterEqual(a,b)a>=b2.7
assertLess(a,b)aassertLessEqual(a,b)a<=b2.7
assertRegexpMatches(s,re)regex.search(s)2.7
assertNotRegexpMatches(s,re)notregex.search(s)2.7
assertItemsEqual(a,b)sorted(a)==sorted(b)andworkswithunhashableobjs2.7
assertDictContainsSubset(a,b)allthekey/valuepairsinaexistinb2.7
assertMultiLineEqual(a,b)strings2.7
assertSequenceEqual(a,b)sequences2.7
assertListEqual(a,b)lists2.7
assertTupleEqual(a,b)tuples2.7
assertSetEqual(a,b)setsorfrozensets2.7
assertDictEqual(a,b)dicts2.7
assertMultiLineEqual(a,b)strings2.7
assertSequenceEqual(a,b)sequences2.7
assertListEqual(a,b)lists2.7
assertTupleEqual(a,b)tuples2.7
assertSetEqual(a,b)setsorfrozensets2.7
assertDictEqual(a,b)dicts2.7
其他断言方法请查阅官方文档
四:组成测试套件
1.添加数量较少的测试case,可以用如下方法:
suite=unittest.Testsuite()
suite.addTest(testclass(testcase))
这里testclass为测试类的名称,testcase为该测试类下的测试case的名称,为字符串。
2.对于有多个测试类的情况,可以用如下方法:
defcreatesuite(): testunit=unittest.TestSuite() discover=unittest.defaultTestLoader.discover(testdir,pattern='test_*.py',top_level_dir=None) printdiscover fortest_suiteindiscover: fortestsuitintest_suite: testunit.addTest(testsuit) returntestunit alltestnames=createsuite()
如此便可以将一个目录下多个测试文件中的testcase导入。