• 13
  • 14
分享

不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果。今天笔者就总结下如何使用unittest单元测试框架来进行WEB自动化测试。

一、unittest模块的各个属性说明

点击返回目录

    先来聊一聊unittest模块的各个属性,所谓知己知彼方能百战百胜,了解unittest的各个属性,对于后续编写用例有很大的帮助。

1.unittest的属性如下:

['BaseTestSuite', 'FunctionTestCase', 'SkipTest', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult', 'TestSuite', 'TextTestResult',
'TextTestRunner', '_TextTestResult', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__unittest',
'case', 'defaultTestLoader', 'expectedFailure', 'findTestCases', 'getTestCaseNames', 'installHandler', 'loader', 'main',  'makeSuite', 
'registerResult', 'removeHandler', 'removeResult', 'result', 'runner', 'signals', 'skip', 'skipIf', 'skipUnless', 'suite', 'util']

说明:

1、unittest.TestCase:TestCase类,所有测试用例类继承的基本类。

class BaiduTest(unittest.TestCase):

2、unittest.main():使用她可以方便的将一个单元测试模块变为可直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中以“test”命名开头的测试方法,并自动执行他们。

(1)执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。

3、unittest.TestSuite():unittest框架的TestSuite()类是用来创建测试套件的。

4、unittest.TextTextRunner():unittest框架的TextTextRunner()类,通过该类下面的run()方法来运行suite所组装的测试用例,入参为suite测试套件。

5、unittest.defaultTestLoader(): defaultTestLoader()类,通过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件,因此可以直接通过run()方法执行discover。用法如下:

discover=unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')

6、unittest.skip():装饰器,当运行用例时,有些用例可能不想执行等,可用装饰器暂时屏蔽该条测试用例。一种常见的用法就是比如说想调试某一个测试用例,想先屏蔽其他用例就可以用装饰器屏蔽。

@unittest.skip(reason): skip(reason)装饰器:无条件跳过装饰的测试,并说明跳过测试的原因。
@unittest.skipIf(reason): skipIf(condition,reason)装饰器:条件为真时,跳过装饰的测试,并说明跳过测试的原因。
@unittest.skipUnless(reason): skipUnless(condition,reason)装饰器:条件为假时,跳过装饰的测试,并说明跳过测试的原因。
@unittest.expectedFailure(): expectedFailure()测试标记为失败。

2.TestCase类的属性如下:

['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'_addSkip', '_baseAssertEqual', '_classSetupFailed', '_deprecate', '_diffThreshold', '_formatMessage', '_getAssertEqualityFunc',
'_truncateMessage', 'addCleanup', 'addTypeEqualityFunc', 'assertAlmostEqual', 'assertAlmostEquals', 'assertDictContainsSub
set', 'assertDictEqual', 'assertEqual', 'assertEquals', 'assertFalse', 'assertGreater', 'assertGreaterEqual', 'assertIn', 'assertIs', 'assert
IsInstance', 'assertIsNone', 'assertIsNot', 'assertIsNotNone', 'assertItemsEqual', 'assertLess', 'assertLessEqual', 'assertListEqual',
'assertMultiLineEqual', 'assertNotAlmostEqual', 'assertNotAlmostEquals', 'assertNotEqual', 'assertNotEquals', 'assertNotIn', 
'assertNotIsInstance', 'assertNotRegexpMatches', 'assertRaises', 'assertRaisesRegexp', 'assertRegexpMatches', 'assertSequence
Equal', 'assertSetEqual', 'assertTrue', 'assertTupleEqual', 'assert_', 'countTestCases', 'debug', 'defaultTestResult', 'doCleanups', 
'fail', 'failIf', 'failIfAlmostEqual', 'failIfEqual', 'failUnless', 'failUnlessAlmostEqual', 'failUnlessEqual', 'failUnlessRaises', 'failureException',
'id', 'longMessage', 'maxDiff', 'run', 'setUp', 'setUpClass', 'shortDescription', 'skipTest', 'tearDown', 'tearDownClass']

说明:

1、setUp():setUp()方法用于测试用例执行前的初始化工作。如测试用例中需要访问数据库,可以在setUp中建立数据库连接并进行初始化。如测试用例需要登录web,可以先实例化浏览器。

2、tearDown():tearDown()方法用于测试用例执行之后的善后工作。如关闭数据库连接。关闭浏览器。

3、assert*():一些断言方法:在执行测试用例的过程中,最终用例是否执行通过,是通过判断测试得到的实际结果和预期结果是否相等决定的。

assertEqual(a,b,[msg='测试失败时打印的信息']):断言a和b是否相等,相等则测试用例通过。
assertNotEqual(a,b,[msg='测试失败时打印的信息']):断言a和b是否相等,不相等则测试用例通过。
assertTrue(x,[msg='测试失败时打印的信息']):断言x是否True,是True则测试用例通过。
assertFalse(x,[msg='测试失败时打印的信息']):断言x是否False,是False则测试用例通过。
assertIs(a,b,[msg='测试失败时打印的信息']):断言a是否是b,是则测试用例通过。
assertNotIs(a,b,[msg='测试失败时打印的信息']):断言a是否是b,不是则测试用例通过。
assertIsNone(x,[msg='测试失败时打印的信息']):断言x是否None,是None则测试用例通过。
assertIsNotNone(x,[msg='测试失败时打印的信息']):断言x是否None,不是None则测试用例通过。
assertIn(a,b,[msg='测试失败时打印的信息']):断言a是否在b中,在b中则测试用例通过。
assertNotIn(a,b,[msg='测试失败时打印的信息']):断言a是否在b中,不在b中则测试用例通过。
assertIsInstance(a,b,[msg='测试失败时打印的信息']):断言a是是b的一个实例,是则测试用例通过。
assertNotIsInstance(a,b,[msg='测试失败时打印的信息']):断言a是是b的一个实例,不是则测试用例通过。

3.TestSuite类的属性如下:(组织用例时需要用到)

['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 
'_addClassOrModuleLevelException', '_get_previous_module', '_handleClassSetUp', '_handleModuleFixture', '_handleModule
TearDown', '_tearDownPreviousClass', '_tests', 'addTest', 'addTests', 'countTestCases', 'debug', 'run']

说明:

addTest(): addTest()方法是将测试用例添加到测试套件中,如下方,是将test_baidu模块下的BaiduTest类下的test_baidu测试用例添加到测试套件。

                    suite = unittest.TestSuite()
suite.addTest(test_baidu.BaiduTest('test_baidu'))

4.TextTextRunner的属性如下:(组织用例时需要用到)

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_makeResult', 'buffer', 'descriptions',
'failfast', 'resultclass', 'run', 'stream', 'verbosity']

说明:

run(): run()方法是运行测试套件的测试用例,入参为suite测试套件。
runner = unittest.TextTestRunner()
runner.run(suite)

二、使用unittest框架编写测试用例思路

设计基本思路如下:

# coding=utf-8  #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行
#2.注释:包括记录创建时间,创建人,项目名称。
'''Created on 2016-7-27
@author: Jennifer
Project:使用unittest框架编写测试用例思路
'''
#3.导入unittest模块
import unittest
#4.定义测试类,父类为unittest.TestCase。
#可继承unittest.TestCase的方法,如setUp和tearDown方法,不过此方法可以在子类重写,覆盖父类方法。
#可继承unittest.TestCase的各种断言方法。
class Test(unittest.TestCase):
#5.定义setUp()方法用于测试用例执行前的初始化工作。#注意,所有类中方法的入参为self,定义方法的变量也要“self.变量”#注意,
输入的值为字符型的需要转为int型
    def setUp(self):
        self.number=raw_input('Enter a number:')
        self.number=int(self.number)
======================================================================最重要的一点
#6.定义测试用例,以“test_”开头命名的方法#注意,方法的入参为self#可使用unittest.TestCase类下面的各种断言方法用于对测试
结果的判断#可定义多个测试用例#最重要的就是该部分
    def test_case1(self):
        print self.number
        self.assertEqual(self.number,10,msg='Your input is not 10')
        
    def test_case2(self):
        print self.number
        self.assertEqual(self.number,20,msg='Your input is not 20')
 
    @unittest.skip('暂时跳过用例3的测试')
    def test_case3(self):
        print self.number
        self.assertEqual(self.number,30,msg='Your input is not 30')
=========================================================================
#7.定义tearDown()方法用于测试用例执行之后的善后工作。#注意,方法的入参为self
    def tearDown(self):
        print 'Test over'
#8如果直接运行该文件(__name__值为__main__),则执行以下语句,常用于测试脚本是否能够正常运行
if __name__=='__main__':
#8.1执行测试用例方案一如下:#unittest.main()方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们。
#执行顺序是命名顺序:先执行test_case1,再执行test_case2
    unittest.main()
                                                                                         
'''#8.2执行测试用例方案二如下:
#8.2.1先构造测试集
#8.2.1.1实例化测试套件
    suite=unittest.TestSuite()
#8.2.1.2将测试用例加载到测试套件中。
#执行顺序是安装加载顺序:先执行test_case2,再执行test_case1
    suite.addTest(Test('test_case2'))
    suite.addTest(Test('test_case1'))
#8.2.2执行测试用例
#8.2.2.1实例化TextTestRunner类
    runner=unittest.TextTestRunner()
#8.2.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
    runner.run(suite)'''
    
'''#8.3执行测试用例方案三如下:
#8.3.1构造测试集(简化了方案二中先要创建测试套件然后再依次加载测试用例)
#执行顺序同方案一:执行顺序是命名顺序:先执行test_case1,再执行test_case2
    test_dir = './'
    discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
#8.3.2执行测试用例
#8.3.2.1实例化TextTestRunner类
    runner=unittest.TextTestRunner()
#8.3.2.2使用run()方法运行测试套件(即运行测试套件中的所有用例)
    runner.run(discover)   
'''
使用方案一执行测试用例结果如下:
Enter a number:1010Test overEnter a number:.10Fs
Ran 3 tests in 6.092s
FAILED (failures=1, skipped=1)10Test over

因为先执行test_case1,再执行test_case2,所以第一次输入10时,执行通过,返回. 第二次输入10时,执行不通过,返回F,最终一个用例通过,一个用例失败,还有一个用例是直接跳过的(装饰器)。

 使用方案二执行测试用例结果如下:

Enter a number:10
10
Test over
Enter a number:F10.
Ran 2 tests in 4.973s
FAILED (failures=1) 
10
Test over

因为先执行test_case2,再执行test_case1,所以第一次输入10时,执行不通过,返回F , 第二次输入10时,执行通过,返回. ,最终一个用例通过,一个用例失败。

使用方案三执行测试用例结果如下(执行测试用例顺序同方案一):

Enter a number:10
10
Test over
Enter a number:.10
Fs
Ran 3 tests in 6.092s
FAILED (failures=1, skipped=1)
10
Test over

因为先执行test_case1,再执行test_case2,所以第一次输入10时,执行通过,返回. 第二次输入10时,执行不通过,返回F,最终一个用例通过,一个用例失败,还有一个用例是直接跳过的(装饰器)。

三、使用unittest框架编写测试用例实例

点击返回目录

目录结构:

1.png

百度搜索测试用例Test Case:

# coding=utf-8
'''Created on 2016-7-22
@author: Jennifer
Project:登录百度测试用例
'''
from selenium import webdriver
import unittest, time
 
class BaiduTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30) #隐性等待时间为30秒
        self.base_url = "https://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(3)
        title=driver.title
        self.assertEqual(title, u"unittest_百度搜索")
 
    def tearDown(self):
        self.driver.quit()
 
if __name__ == "__main__":
    unittest.main()

有道翻译测试用例Test Case:

# coding=utf-8
'''Created on 2016-7-22
@author: Jennifer
Project:使用有道翻译测试用例
'''
from selenium import webdriver
import unittest, time
 
class YoudaoTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30) #隐性等待时间为30秒
        self.base_url = "http://www.youdao.com"
    
    def test_youdao(self):
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.find_element_by_id("translateContent").clear()
        driver.find_element_by_id("translateContent").send_keys(u"你好")
        driver.find_element_by_id("translateContent").submit()
        time.sleep(3)
        page_source=driver.page_source
        self.assertIn( "hello",page_source)
 
    def tearDown(self):
        self.driver.quit()
 
if __name__ == "__main__":
    unittest.main()

web测试用例:通过测试套件TestSuite来组装多个测试用例。

# coding=utf-8
'''Created on 2016-7-26
@author: Jennifer
Project:编写Web测试用例
'''
import unittest
from test_case import test_baidu
from test_case import test_youdao
 
#构造测试集
suite = unittest.TestSuite()
suite.addTest(test_baidu.BaiduTest('test_baidu'))
suite.addTest(test_youdao.YoudaoTest('test_youdao'))
 
if __name__=='__main__':
    #执行测试
    runner = unittest.TextTestRunner()
    runner.run(suite)

测试结果:

说明:.代表用例执行通过,两个点表示两个用例执行通过。F表示用例执行不通过。


文章来源:百度文库

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 1、什么是mock测试Mock测试就是在测试活动中,对于某些不容易构造或者不容易获取的比较复杂的数据/场景,用一个虚拟的对象(Mock对象)来创建用于测试的测试方法。2、为什么要进行Mock测试Mock是为了解决不同的单元之间由于耦合而难于开发、测试的问题。所以,Mock既能出现在单元测试中,也会出现在集成测试、系统测试过程中。Mock最大的功能是帮你把单元测试的耦合分解开,如果你的代码对另一个类或者接口有依赖,它能够帮你模拟这些依赖,并帮你验证所调用的依赖的行为。3、Mock适用场景1. 需要将当前被测单元和其依赖模块独立开来,构造一个独立的测试环境,不关注被测单元的依赖对象,只关注被测单元...
            0 0 8097
            分享
          •   世界上最遥远的距离不是我说还是没说,而是我说了什么你却没明白是怎么回事。  最近小编有幸参加了一场金字塔原理的培训课程,金字塔原理帮助我们解决两大问题:思维混乱、逻辑不清,通过金字塔的学习,可以做到想清楚、说明白。下边小编通过小明的故事,跟大家分享一下金字塔原理的工作的方式。  一天,小明在电梯里遇到了部门领导,领导问:小明,好久不见,最近在忙什么?  小明瞬间脑袋空白,不知道如何回答,支支吾吾的说:还好,没忙什么,就是在做5.0版本的项目测试。  小明不开心的回到工位,看到了群群,群群帮他分忧,群群说:小明,你可以采用时间逻辑进行回答,比如我上个月在做一个创新项目升级策略的工具,这个月刚...
            0 0 2491
            分享
          •   据报道,最近,面对人工智能技术的新一轮火爆,马斯克等1000多名专家联合发表一封公开信,呼吁在确保安全之前暂缓先进人工智能的开发。日前,Meta的首席技术官安德鲁·博斯沃斯(AndrewBosworth)对公开信作出回应,表示这样的呼吁不切实际,也难以产生效果。  博斯沃斯表示,在人工智能领域,他认为投资于负责任的研发非常重要,Meta公司也一直在进行这样的研发和投资,但是,如果要停止某个技术的研发进程,然后要对未来进行的调整作出决策,这样是很难做到的。  博斯沃斯表示,在高科技面前,人类如果想知道如何保护自我、研发出安全可靠的技术,首先要了解新科技本身是怎样演进的。他认为,公开信呼吁暂停...
            0 0 568
            分享
          • 简介在业务运维场景中,需要对核心的API接口进行拨测。而各个接口需要传递的参数或者接口之间的依赖是比较复杂的,通常接口之间都是通过链式请求来完成一个业务场景。常见的就是先登录,拿到token以后,再进行后续的API请求。postman提供了基于GUI的方式完成这种场景适配,但是对于运维来讲,需要定时的基于策略的形式来对API进行监控。本篇文章就带你从0-1打造API监控体系。知识储备1. Postman使用方法2. Docker基础知识部署步骤1. 从postman导出collection以下文件以拨测httpbin.org为例,在Postman的GUI工具中导出拨测的json文件(httpb...
            0 0 3924
            分享
          •   WhatsApp 正在开发的一项新功能允许让用户使用人工智能生成个人资料照片。WABetaInfo 在最近发布的 WhatsApp 测试版(Android 版 v2.24.11.17)中发现了 AI 配置文件照片功能。  根据该网站分享的该功能的所谓截图,您可以通过向即时通讯应用程序提供文字提示来描述您想要生成的个人照片类型。该功能可以帮助创建独一无二的个性化个人照片,反映个性、兴趣和心情。  该网站指出,与该功能相关的一个好处是,可以在 WhatsApp 上分享人工智能生成的个人资料照片而不是真实照片,这样可以防止坏人滥用。该网站称,人工智能个人资料照片功能目前正在开发中,测试者还无法使...
            0 0 498
            分享
      • 51testing软件测试圈微信