SimpleTest.docx
《SimpleTest.docx》由会员分享,可在线阅读,更多相关《SimpleTest.docx(50页珍藏版)》请在冰点文库上搜索。
![SimpleTest.docx](https://file1.bingdoc.com/fileroot1/2023-5/5/223c3cb9-2082-4e19-a29e-04173ee36d7d/223c3cb9-2082-4e19-a29e-04173ee36d7d1.gif)
SimpleTest
SimpleTest
SimleTest是Drupal的定制性测试框架。
SimpleTest已经成为Drual7开发周期中必不可少的工作流的一部分,它已作为测试模块并入内核。
它极大程度地增强了内核的开发、使对重大API的改进得到可能,并信心倍增。
在Drupal6中,它称为SimpleTest模块,存在contributed仓储中。
chx称:
"Drupal7"内核已经比以前任何一个版本稳定的多了”.
有了这个测试框架让drupal7增色不少。
Drupal7内核测试通常采用下面三种方法中的一种:
•功能性测试(Functiontest)是最常用的。
该方法安装一个新的数据库,在数据库中先产生专用测试数据,再按预期的结果来推测。
•单元测试(UnitTests)方法不需要在后台进行数据库安装。
该方法对于单个功能模块的测试很有用,不需要考虑大的系统开发的情况。
•升级测试(UpgradedTests)方法是导出老版本的数据库,再通过运行update.php导入后进行测试。
SimpleTest概述
测试方法
Drupal测试更关注于功能测试(functionaltesting)而不是单元(unittesting)测试。
也就是说,测试是对接口整体进行的,而不是针对个别模块功能或几段代码的测试。
Drupal关注功能测试因为这样可以使Drupal开发更为有效。
它至少和单元测试一样有效。
测试框架是以功能测试为导向的,本小结重点讲述如何进行功能测试。
建立独立的测试环境
测试框架会自动为每次测试实例产生一个独立的测试环境。
即每次会创建一个独立的文件夹目录和一套完全独立的数据库表格。
drupal安装在该环境中进行测试。
这样保证了每次测试都是干净的环境,不可能和其他测试混淆。
开发者也不需要每次测试后清理环境。
建立独立的测试环境是必要的,它保证了每次测试实例都是初始化的。
还有在本地开发环境中做的任何改变都不会带入到该测试环境中。
每个测试都要经过必要的安装配置(如:
创建内容、用户等)
测试实例布局
每一个测试实例只能用一个setup()和一个tearDown()来实现。
这就是说需要启用相同模块组及测试相同功能的所有测试要归并到一个测试组中。
不同安装的测试实例要分开,但是都保存在同一个测试文件中。
测试文件位置
对一个模块的所有测试应该统一存放到该模块目录下的测试文件中。
文件名格式为modulename.test。
比如:
节点模块的测试文件为:
modules/node/node.test。
如果像测试模块需要其他测试文件,要放到测试目录下,则该测试目录也应该放到该模块的目录下。
运行测试
测试系统提供了两种运行方法:
web接口方法和命令行脚本方法。
Web接口可以在站点构建(sitebuilding)菜单下的admin/build/testing中找到((Drupal6版本)。
或者配置菜单(configuration)下的admin/config/development/test下(drupal7版本)。
勾选需要测试的选项,然后点击运行按钮。
在页面下方会有一个进度条来显示完成的百分比和运行情况。
如果要用命令行脚本形式,则在scripts目录下有个名叫run-test.sh的脚本。
详细的方法可以参加相关文档,或者在console上直接运行./scripts/run-test.sh.
SimpleTest和测试模块
SimpleTest模块(Druapl6.x)或测试模块(drupal7.x及更高版本)提供了一个在Drupal中自动进行单元和功能测试的框架。
它可以用来验证代码更改前后的状态,或为开发者提供了一套编写和测试模块的方法。
初始模块是基于SimpleTestPHPlibrary的。
测试列表可以在(drupal6.x版本)管理(Administer)>>站点建设(Sitebuilding)>>SimpleTest下或在(Drupal7.x)管理(Administration)>>配置(Configuration)>>开发(Development)>>测试(Testing)下找到。
要进行全面测试就选择全部的测试选项,或单独选测试项以进行更有针对性地测试。
(注意:
全面测试可能要花上好几分钟时间,选则的测试项太多,也可能无法完成测试)。
测试完成后,在每个测试组边上会有消息条显示测试是否通过、失败、或有异常。
通过(pass)表示测试返回了预期结果,失败(fail)表示没有返回预期结果。
异常则说明有测试以外的错误,比如PHP警告或报警。
当失败或异常结果发生时,结果内容会扩展开来显示,通常以红色或粉色行显示。
(开发者)可以根据测试结果来优化代码、再此进行测试直到通过。
更多有关创建和修改测试的信息,请参阅Drupal手册中其他SimpleTest文档。
SimpleTest使用指南(Drupal7)
原文链接http:
//drupal.org/simpletest-tutorial-drupal7。
注:
本指南中引用代码来自ExamplesforDevelopersmodule,你可以:
∙从该模块中复制一份代码,编辑、修改然后进行测试.
∙报告所发现问题,进行修复,欢迎进行补丁修正和提出改进意见。
通过本指南,可以让你掌握基本的测试方法。
学习本节后你可以建立第一个测试!
在本例中,我们将创建一个叫“simplestexample”的dummy模块,它提供一个叫”simplest_example”的内容类型。
这个内容类型和任何基本Drupal节点类型(如:
’page’)一样。
本指南将阐述如何对这个simplest_example内容类型进行测试,从而保证其功能的有效实现。
准备工作
首先,我们要确保simpletest模块已安装。
在drupal7中,simpletest已是内核的一部分称为测试模块。
如果你还没有安装该模块,确保Simpletest模块已经启用。
在Drupal7中,SimpletestVerbose选项默认是打开的。
当然如果想确保它是否是打开的,,则可以去管理/配置/开发/设置(admin/config/development/testing/settings)下检查。
本指南所采用的例子取自http:
//drupal.org/project/examples
DrupalSimpletest如何工作
大多数Drupal功能是面向web的,因此演习这些功能是及其重要的。
Simpletest生成一份完整的安装和一个虚拟的web浏览器,通过这个虚拟浏览器来进行一系列测试,就如你手工一步步进行一样。
记住每次测试都是在运行一个完整的新的durpal实例是非常重要的。
换而言之,每一个测试实例是空的,没有进行过任何配置,建立过任何用户,除了默认的内核模块,其他模块都未开启。
如果你的测试需要一个有特权的用户,你就需要创建一个(这如同你手工创建一个测试环境一样)。
如果有需要的模块,你就需要开启他们。
如果需要配置,就要用simpletest来进行配置,因为在我们要测试的druapl实例中,该测试站点还未进行过任何配置,文件目录下也没有任何文件,也未安装过可选模块,也没有创建过任何用户。
在simpletest中,我们有神奇的命令去执行它们,稍后我们会做进一步讲解。
关于SimpletestExample模块
SimpletestExample模块给出了一个可配置的节点类型(如’page’或者’story’).该类型有一个标题和一个正文组成。
借此它给我们演示了测试内容创建的机会。
为了实现这个节点,我们需要用hook_node_info()钩子函数来创建节点类型,用hook_form()函数来创建表单。
我们需要为模块设置权限(为此你需要”createsimpletest_examplecontent”权限来创建,或者由”editownsimpletest_examplecontent”取得编剧权限)。
当然,我们需要准备一个simpletest_example.info文件。
注意,我们的模块中有一个bug:
它的权限处理是有问题的。
因此即使给予了’editownsimpletest_example’的字符串,simpletest_example_access()函数也不能正确处理,所以当我们赋予用户编辑节点权限室,实际上是不能实现的。
当然,手工测试时可能一直用用户1来测试,不会看到测试失败的情况,我们稍后会提到。
本代码在ExamplesforDevelopers模块中维护,它有助于在正式发布前,用dummy代码来进行测试、编辑和实践,.建议开发者取些模块,启用并练习。
思考何时需要测试
如果已经安装了simpletest_example模块,你可以按如下步骤一步步来进行,并思考何时需要测试。
访问内容->增加新内容->SimpletestExample节点类型(Content>Addnewcontent>SimpletestExampleNodeType),你会看到如下页面。
查看界面并选定要测试的内容。
仔细浏览确保你已经熟知接口间是如何工作的,在一个基本实例,而不是Simpletest操作中,功能可以实现。
如果你还没有理解原理,是不能写好测试代码的。
在本例中,我们来填上标题和正文内容,然后按保存按钮。
你将看到如下页面。
对simpletest_example构建测试
好,我们可以来测试了,我们会在simpletest_example.test文件中操作。
(该文件可从下载的模块中获得)
在drupal7中,如果对一个模块添加了一个新的.test文件,则需要在该模块的.info文件将它添加到files[]部分。
在我们的例子中,simpletest_example.info文件中在files[]下,就有simpletest_example.test的记录.
files[]=simpletest_example.test
如果.file文件添加在现有的模块中,则可能需要重刷cache,让drupal知道有新文件产生了。
要刷新cache,可以去admin/config/development/performance下点击“clearallchaches”按钮。
进行一个测试需要如下四个步骤:
∙创建结构(即产生一个从DrupalWebTestCase继承的类)
∙对任何用户创建或需要的配置的测试实例初始化
∙用测试实例产生真实测试
∙当然,要特别想清楚为什么我们的测试没有按预想地进行并调试测试(也许还有模块).
在开始前,我们需要模块扩展DrupalWebTestCase.
php
/**
*TeststhefunctionalityoftheSimpletestexamplecontenttype.
*/
classSimpletestExampleTestCaseextendsDrupalWebTestCase{
protected$privileged_user;
}
?
>
为了使Simpletest接口调用测试,我们来用getInfo()函数实现。
它提供了用户接口信息,并在刷新缓存后,显示在simpletest页面上。
下面就是非常重要的setup()函数了。
这里我们就要处理必须处理的,让该Drupal实例按我们的想法工作。
我们必须考虑:
“我们如何操作,才能从初始化安装到可以在哪里运行测试?
在我们的实例中,我们知道必须:
∙启用SimletestExmaple模块
∙创建一个有权限的用户,来产生一个simpletest_example节点
∙用该用户登陆
以上工作就是有setup()方法来实现的.
php
publicfunctionsetUp(){
//Enableanymodulesrequiredforthetest
parent:
:
setUp('simpletest_example');
//Createandloginourprivilegeduser.
$this->privileged_user=$this->drupalCreateUser(array(
'createsimpletest_examplecontent',
'extraspecialeditanysimpletest_example',
));
$this->drupalLogin($this->privileged_user);
}
?
>
注:
在Drupal6中,我们必须启用所有关联模块。
Drupal7会自动启用有关联的模块.
测试建立:
创建节点
现在让我们来创建测试实例练习模块。
刚才我们已经为我们的测试类建立了成员函数,每一个成员我们会来练习一个测试。
我们的第一个测试将通过node/add/simpletest-example中的form来创建一个新的simpletest_example节点.
php
/**
*TestscreationofaSimpletestexamplenode.
*/
publicfunctiontestSimpleTestExampleCreate(){
//Createnodetoedit.
$edit=array();
$edit['title']=$this->randomName(8);
$edit["body[und][0][value]"]=$this->randomName(16);
$this->drupalPost('node/add/simpletest-example',$edit,t('Save'));
$this->assertText(t('SimpletestExampleNodeType@titlehasbeencreated.',array('@title'=>$edit['title'])));
}
?
>
drupalPost,drupalGet和判断语句
以上代码在node/add/simpletest-example页面完成了一个简单的递交表单的功能。
它将字段定义到了一个数列中($edit数组产生随机值赋给title和body),然后递交表单,并声明在页面上找到了合适的文本.
大多数的测试将按如下形式来进行:
∙调用drupalGet()函数来跳转到一个页面或者用drupalPost()来递交表单
∙用一次或多次语句来检查内容是所见即所得的.
$this->drupalGet($path)可以非常容易的跳到指定页面
$this->drupalPost($path,$edit_fields,$submit_button_name)稍复杂些
还有几十种这样的语句。
最容易的一个是$this->assertText($text_to_find_on_page).当超越本指南知识后,你会想参阅更多的语句。
测试中的用户和内核环境
测试运行在一个独立的(沙盒)环境中。
在测试环境中,用$this->drupalLogin($account)来指定一个用户登陆。
像drupalGet和drupalPost的测试方法经常在沙盒中用到。
如果要调用内核API函数(如:
user_access),强烈建议将这个测试用户授权于内核环境中。
php
$account=$this->drupalCreateUser(array('accesscontent'));
$this->drupalLogin($account);
global$user;
$user=user_load($account->uid);
$this->assertFalse(user_access('accesscontent'));
?
>
在测试中,Simpletest将用户转换成uid1,并负责恢复用户,因此我们可以切换用户而不必考虑安全因素。
通过Web界面运行Simpletest
下面我们来运行测试。
这里我们将用web界面来运行。
在模块页面,找到你创建的模块,然后进入配置页面。
在打开的页面,你会看到有两个标签:
配置(Settings)和列表(List)。
在列表标签下,你会看到可选择的测试列表。
选择你要创建的测试-它会归入”Examples”组—点击并运行”Runtests”(有时可能需要清除Drupal缓存才能在列表中见到)
测试运行后你就能见到是否通过(pass)的结果。
你也可以通过命令行运行。
更多的内容请参阅通过命令行来运行测试。
一个失败测试的演示
测试成功的例子没有必要多讲了,现在我们来举一个失败的例子。
还是用相同的类,这次来测试编辑节点的情况。
我们的模块有一个缺陷-它不能很好的处理”editownsimpletest_exple”权限,当用户仅有此权限时缺不能编辑它。
在本实例中我们将创建一个节点,然后来进行编辑。
运行测试并查看结果。
php
/**
*TestseditingaSimpletestexamplenode.
*/
publicfunctiontestSimpleTestExampleEdit(){
$settings=array(
'type'=>'simpletest_example',
'title'=>$this->randomName(32),
'body'=>array(LANGUAGE_NONE=>array(array($this->randomName(64)))),
);
$node=$this->drupalCreateNode($settings);
//Fordebugging,wemightoutputthenodestructurewith$this->verbose()
$this->verbose('Nodecreated:
'.var_export($node,TRUE));
//Itwouldonlybeoutputifthetestingsettingshad'verbose'set.
//We'llrunthistestnormally,butnotonthetestbot,asitwould
//indicatethattheexamplesmodulewasfailingtests.
if(!
$this->runningOnTestbot()){
//Thedebug()statementwilloutputinformationintothetestresults.
//ItcanalsobeusedinDrupal7anywhereincodeandwillcomeout
//asadrupal_set_message().
debug('WearenotrunningonthePIFRtestingserver,sowillgoaheadandcatchthefailure.');
$this->drupalGet("node/{$node->nid}/edit");
//Makesurewedon'tgeta401unauthorizedresponse:
$this->assertResponse(200,t('Userisallowedtoeditthecontent.'));
//Lookingfortitletextinthepagetodeterminewhetherwewere
//successfulopeningeditform.Notethattheoutputmessage
//"Foundtitleineditform"isnottranslatedwitht().
$this->assertText(t("@title",array('@title'=>$settings['title'])),"Foundtitleineditform");
}
}
?
>
单元测试
Simpletest也提供了DrupalUnitTestCase,来作为DrupalWebTestCase的可选类.
单元测试不会产生数据库表格和文件目录.所以单元测试要比功能测试初始化快,但这也意味着它不能访问数据库和文件目录。
调用任何一个需要数据库看函数会产生异常。
这些函数包括routine函数,比如watchdog(),module_implements(),module_invoke_all()等。
更多的编写单元测试的资料请参阅用Simpletest来进行单元测试。
何时在Simpletest中用t()函数
和Drupal中的大多数字符串不同,simpletest的字符串不经常用到t()函数。
这里有两个原因:
1许多simpletest的字符串仅仅是测试目的,不会用到网站上,因此不需要解释它们。
2当不同组件尽可能分开时,它能比较容易地提供永久、强大的覆盖面.(即:
不需要时的时候不需要从其他系统运行如t()的代码)
何时使用t()
在如下情况中需要用到t()函数:
∙当需要特别测试转义和定位功能时;
∙当测试用户界面中已经解释的字符串。
如:
当验证一个403页面”Accessdenied”信息是,采用如下代码
php
$this->assertText(t('Accessdenied'),'Accessdeniedmessagefoundonforbiddenfoopage.');
?
>
注意:
第一个字符串”Accessdenied”,由drupal_deliver_html_page()提供,用t()转义。
因此,我们也用这个t()函数来检查这条消息是否存在。
何时不使用t()函数
不要在如下情况中使用t():
∙getInfo()中含字符串.
∙测试语句消息,重复如上例子
php
$this->assertText(t('Accessdenied'),'Accessdeniedmessagefoundonforbiddenfoopage.');
?
>
第二个字符串’Accessdeniedmessagefoundonforbiddenfoopage’仅是注释信息,不要将它转义.
∙除非测试模块需要测试转义功能,否则对于测试模块和主题输出不要使用。
在如上例子中,如果需要设置格式或定制字符串输出,可以用format_string()函数
Simpletests调试
在测试设置中(admin/config/development/testing/settings),有一个选项“Provideverboseinformationwhenrunningtests".如果打开这个选项,则每个drupalGet()和drupalPost()函数将作为