在初始python单元测试框架unittest与webdriver的关系(一)中,介绍了unittest与自动化的结合,下面介绍测试套件TestSuite()
当有多个或者几百测试用例的时候,我们必须需要一个集合,来把测试用例放在该集合中,来进行执行,幸运的是,unittest模块中提供了TestSuite类来生成测试套件,使用该类的构造函数可以生成一个测试套件的实例,该类提供了addTest来把单元测试用例加入到测试套件中,测试代码使用TestSuite的addTest进行更改,具体见如下的测试脚本:
#coding:utf-8
from selenium import webdriver
import unittest,sys,time
class BaiduTest(unittest.TestCase):
defsetUp(self):
self.driver=webdriver.Firefox()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
deftestTitle(self):
self.assertEqual(u'百度一下,你就知道',self.driver.title)
deftestUrl(self):
self.assertEqual('https://www.baidu.com/',self.driver.current_url)
deftearDown(self):
self.driver.quit()
if __name__=='__main__':
suite=unittest.TestSuite()
suite.addTest(BaiduTest('testTitle'))
suite.addTest(BaiduTest('testUrl'))
unittest.TextTestRunner(verbosity=2).run(suite)
字体加粗的部分就是构建测试容器(测试套件)后,把测试用例添加到测试容器,来进行执行,这样的一个好处就是测试用例是按顺序的来执行。我们可以把suite写成一个静态方法来进行调用,那么如上实现的测试脚本就为:
#coding:utf-8
from seleniumimport webdriver
importunittest,sys,time
classBaiduTest(unittest.TestCase):
def setUp(self):
self.driver=webdriver.Firefox()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
def testTitle(self):
self.assertEqual(u'百度一下,你就知道',self.driver.title)
def testUrl(self):
self.assertEqual('https://www.baidu.com/',self.driver.current_url)
def tearDown(self):
self.driver.quit()
@staticmethod
def suite():
suite=unittest.TestSuite()
suite.addTest(BaiduTest('testTitle'))
suite.addTest(BaiduTest('testUrl'))
return suite
if __name__=='__main__':
unittest.TextTestRunner(verbosity=2).run(BaiduTest.suite())
二、makeSuite()
利用addTest()可以实现测试用例的顺序执行,但是在自动化的测试中,每个case在一个测试容器中,应该是随机执行的,更加容易让人接受,这样也就每个case之间不会有互相依赖和牵制,另外一方面,在一个测试容器中,测试的case的数量最小在十以内,最多可能在几百或者几千,如果采用addTest的方法,那么对每个case都要进行添加,从而导致很多垃圾代码,如suite.addTest(BaiduTest('case'))
...
很显然,这样的代码,并不是我们想要的最好的结果,后期维护测试代码,也会带来无谓的时间浪费和增加人力的成本,自动化的优点就是符合在敏捷的规格中,来达到测试的结果,从而达到保障质量。可性的是,unittest提供了makeSuite的方法,makeSuite可以实现测试用例类内所有的测试用例组成的测试容器TestSuite,我们可以把如上的代码使用makeSuite来调整下,调整后的代码见如下:
#coding:utf-8
from selenium import webdriver
import unittest,sys,time
class BaiduTest(unittest.TestCase):
defsetUp(self):
self.driver=webdriver.Firefox()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
deftestTitle(self):
self.assertEqual(u'百度一下,你就知道',self.driver.title)
deftestUrl(self):
self.assertEqual('https://www.baidu.com/',self.driver.current_url)
deftearDown(self):
self.driver.quit()
if __name__=='__main__':
suite=unittest.TestSuite(unittest.makeSuite(BaiduTest))
unittest.TextTestRunner(verbosity=2).run(suite)
这样,我们就不需要考虑测试容器中有多少case,也就没有了利用addTest产生的烦恼。我们把suite写成一个静态方法,来重构代码:
#coding:utf-8
from selenium import webdriver
import unittest,sys,time
class BaiduTest(unittest.TestCase):
defsetUp(self):
self.driver=webdriver.Firefox()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
deftestTitle(self):
self.assertEqual(u'百度一下,你就知道',self.driver.title)
deftestUrl(self):
self.assertEqual('https://www.baidu.com/',self.driver.current_url)
deftearDown(self):
self.driver.quit()
@staticmethod
def suite():
suite=unittest.TestSuite(unittest.makeSuite(BaiduTest))
return suite
if __name__=='__main__':
unittest.TextTestRunner(verbosity=2).run(BaiduTest.suite())
三、TestLoader()
TestLoader用于创建类和模块的测试套件,一般的情况下,使用TestLoader().loadTestsFromTestCase(TestClass)来加载测试类。见如下使用TestLoader调整的测试脚本:
#coding:utf-8
from selenium import webdriver
import unittest,sys,time
class BaiduTest(unittest.TestCase):
defsetUp(self):
self.driver=webdriver.Firefox()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
deftestTitle(self):
self.assertEqual(u'百度一下,你就知道',self.driver.title)
deftestUrl(self):
self.assertEqual('https://www.baidu.com/',self.driver.current_url)
deftearDown(self):
self.driver.quit()
if __name__=='__main__':
suite=unittest.TestLoader().loadTestsFromTestCase(BaiduTest)
unittest.TextTestRunner(verbosity=2).run(suite)
我们把suite进行封装下,那么调整后的测试代码为:
#coding:utf-8
from selenium import webdriver
import unittest,sys,time
class BaiduTest(unittest.TestCase):
defsetUp(self):
self.driver=webdriver.Firefox()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
deftestTitle(self):
self.assertEqual(u'百度一下,你就知道',self.driver.title)
deftestUrl(self):
self.assertEqual('https://www.baidu.com/',self.driver.current_url)
deftearDown(self):
self.driver.quit()
@staticmethod
def suite():
suite=unittest.TestLoader().loadTestsFromTestCase(BaiduTest)
return suite
if __name__=='__main__':
unittest.TextTestRunner(verbosity=2).run(BaiduTest.suite())
四、discover()
discover是通过递归的方式到其子目录中从指定的目录起始,找到所有测试模块并返回一个包含他们对象的TestSuite,然后进行加载与模式匹配唯一的测试文件。如下的实例就是在'D:/git/PyCharm/TestCase的目录下,存在test_share.py和test_share2模块的测试文件,我们利用正则表达式,程序会在'D:/git/PyCharm/TestCase的目录下,寻找到test_*.py的文件,然后进行加载并执行测试对象,见如下的测试代码:
#coding:utf-8
from selenium import webdriver
import unittest,sys,time
class BaiduTest(unittest.TestCase):
defsetUp(self):
self.driver=webdriver.Firefox()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
deftestTitle(self):
self.assertEqual(u'百度一下,你就知道',self.driver.title)
deftestUrl(self):
self.assertEqual('https://www.baidu.com/',self.driver.current_url)
deftearDown(self):
self.driver.quit()
@staticmethod
def suite():
suite=unittest.defaultTestLoader.discover(
'D:/git/PyCharm/TestCase',
pattern='test_*.py',
top_level_dir=None
)
return suite
if __name__=='__main__':
unittest.TextTestRunner(verbosity=2).run(BaiduTest.suite())
见执行后的测试结果: