OpenStackTesting&DebuggingNick03/15/2014OpenStackTest[1]OpenStackTests•测试介绍•测试框架•单元测试•集成测试•单步调试测试介绍•SmallTests•MediumTests•LargeTests测试介绍:SmallTests•单元测试•特点•针对执行单元:Function•资源访问•不访问数据库、文件系统和网络•隔离•单元测试用例间互相隔离,互不影响•依赖•单元测试用例间没有依赖关系测试介绍:MediumTests•功能测试•特点•针对功能模块•资源访问•访问数据库、文件系统和网络•测试用例设计•单个测试用例涉及多个功能实现•集成环境+单个功能点的测试测试介绍:LargeTests•系统集成测试•特点•针对整个子系统模块•资源访问•访问数据库、文件系统和网络•自动化测试功能点测试介绍•测试框架和相关技术•单元测试框架•nose•模拟测试框架•mock•功能测试环境•devstack•集成测试框架•tempestNoseReview[2]单元测试框架•Nosenose项目是于2005年发布的,也就是py.test改名后的一年。它是由JasonPellerin编写的,支持与py.test相同的测试习惯做法,但是这个包更容易安装和维护。尽管py.test在某些方面有所进步,目前也很容易安装,但是nose仍然保持了易用性方面的声誉。•Nose的安装•pipinstallnoseNose安装安装完成后,测试一下:编写简单Nose用例defTestfunc():a=1b=2asserta==b把上面的文件保存到一个目录下(注意:测试文件命令以Test或test开头),然后在该目录下在命令行里执行nosetests简单的测试Setup和tearDownSetup和tearDownsetup:在测试用例开始时被执行tearDown:在测试用例结束后被执行可支持如下级别:1.模块的setUp和tearDown2.测试函数的setUp和tearDown3.测试类的的setUp和tearDown4.package的setUp和tearDown模块的Setup和tearDown测试代码defsetUp():print'testsetup'deftearDown():print'testteardown'deftest_func_1():print'test_func_1'assertTruedeftest_func_2():print'test_func_2'assertTrue执行结果:分析:nose在文件中如果找到函数setup,setup_module,setUp或者setUpModule等,那么会在该模块的所有测试执行之前执行该函数。如果找到函数teardown,tearDown,teardown_module或者tearDownModule等,那么会在该模块所有的测试执行完之后执行该函数。对于上面的代码,nose实际的执行过程是这样的:setUp()-Testfunc1()-Testfunc2()-tearDown()测试函数的Setup和tearDowndefsetUp():print'testsetup'deftearDown():print'testteardown'deffunc_1_setup():print'test_func_1setup'deffunc_1_teardown():print'test_func_1_teardown'deftest_func_1():print'test_func_1run'assertTruetest_func_1.setUp=func_1_setuptest_func_1.tearDown=func_1_teardown测试代码测试函数的Setup和tearDown执行结果结果分析nose对上面代码的具体执行顺序如下:setUp()-func_1_setup()-test_func_1()-func_1_teardown()-tearDown()测试类的Setup和tearDownclassTestCase():var1=0var2=0defsetUp(self):self.var1=1self.var2=2printTestCasesetupdeftearDown(self):self.var1=0self.var2=0printTestCaseteardown测试代码deftest_func_1(self):assertself.var1==self.var2deftest_func_2(self):assertself.var1!=self.var2测试类的Setup和tearDown执行结果结果分析这里nose会对每个类的测试方法单独创建类的实例,并且有单独的setUp和tearDown。nose对上面测试的顺序如下:setUp()-Testfunc1()-TearDown()-setUp()-Testfunc2()-TearDown()package的setUp和tearDownpackage的setUp和tearDown方法需要放在__init__.py这个文件中,整个package只执行一次setUp和一次tearDownnosetest常用的命令行参数a)-s,不捕获输出,会让你的程序里面的一些命令行上的输出显示出来。例如print所输出的内容。b)-v,查看nose的运行信息和调试信息。例如会给出当前正在运行哪个测试。c)-x,在第一次失败时就停止执行。nosetestinOpenStack•自动化测试•所有用例:${project_dir}/run_tests.sh•Pep8代码规范:${project_dir}/run_tests.sh-p•手动测试单个的用例•${project_dir}/nosetestsneutron/tests/unit/test_agent_config.py-sMockReview[3]PythonMock介绍•模拟测试框架•Python3.3标准库的一部分PythonMock应用场景•真实对象具有不可确定的行为•真实对象很难被创建•真实对象的某些行为很难触发•真实情况令程序的运行速度很慢•真实对象有用户界面•测试需要询问真实对象它是如何被调用的•真实对象实际上并不存在PythonMockDemo•删除文件功能#!/usr/bin/envpython#-*-coding:utf-8-*-importosdefrm(filename):os.remove(filename)PythonMockDemo•删除文件测试用例-1tmpfilepath=os.path.join(tempfile.gettempdir(),tmp-testfile)defsetUp(self):withopen(self.tmpfilepath,wb)asf:f.write(Deleteme!)deftest_rm(self):rm(self.tmpfilepath)self.assertFalse(os.path.isfile(self.tempfile),Failedtoremovethefile.)PythonMockDemo•删除文件测试用例-2@mock.patch('mymodule.os')deftest_rm(self,mock_os):rm(“anypath”)mock_os.remove.assert_called_with(anypath)PythonMockDemoimportcollectionsimportmockthing=collections.Counter()thing.method=mock.MagicMock(return_value=3)thing.method(3,4,5,key='value')thing.method.assert_called_with(3,4,5,key='value')thing.method.assert_called_with(3,4,6,key='value')Traceback(mostrecentcalllast):Filestdin,line1,inAssertionError:Expectedcall:mock(3,4,6,key='value')Actualcall:mock(3,4,5,key='value')PythonMockDemomock_side=mock.Mock(side_effect=KeyError(‘foo’))mock_side()Traceback(mostrecentcalllast):Filestdin,line1,inmoduleFile/usr/lib/python2.7/site-packages/mock.py,line955,in__call__return_mock_self._mock_call(*args,**kwargs)File/usr/lib/python2.7/site-packages/mock.py,line1010,in_mock_callraiseeffectKeyError:'foo'DevstackReview[4]Devstack介绍•OpenStack开发、系统测试平台•自动化部署系统•自动化清理环境•与master分支保持一致Devstack安装和配置•gitclone•cddevstack&&./stack.sh•User/Group:stack•配置文件:•local.conf•localrcDevstack构成•stack.sh•clean.sh•/opt/stack•logs/stack.sh.log•logs/screen$./stack.shsniplotsofoutput!horizonisnowavailableat://127.0.0.1:5000/v2.0/examplesonusingnovaclientcommandlineisinexercise.shthedefaultusersare:adminanddemothepassword:4f9a953e98ee57d922d9Thisisyourhostip:127.0.0.1stack.shcompletedin79seconds.Devstack运行TempestReview[5]Tempest•OpenStack集成测试项目•基于unittest2和nose单元测试框架开发•基本执行流程:•调用各个OpenStack组件的API•验证API返回的结果•测试环境通过配置文件构建nick@awcloud:~/repos/tempest$./tempest/tools/conf_from_devstack-D../devstack/-oetc/tempest.confOutputfilealreadyexists.Overwrite?[y/N]Ynick@awcloud:~/repos/tempest$catetc/tempest.conf[nova]host=127.0.0.1port=5000apiVer=v2.0path=tokensuser=adminapi_key=4f9a953e98ee57d922d9tenant_name=adminssh_timeout=300build_interval=10build_timeout=600[environment]image_ref=3712ca26-f926-4725-9132-08ec1f6e452eimage_ref_alt=4flavor_ref=1flavor