高效 JavaScript 单元测试.docx
- 文档编号:23091617
- 上传时间:2023-04-30
- 格式:DOCX
- 页数:12
- 大小:91.37KB
高效 JavaScript 单元测试.docx
《高效 JavaScript 单元测试.docx》由会员分享,可在线阅读,更多相关《高效 JavaScript 单元测试.docx(12页珍藏版)》请在冰豆网上搜索。
高效JavaScript单元测试
高效JavaScript单元测试
来源:
IBMdeveloperWorks 发布时间:
2011-12-0113:
26
摘要:
能在一个浏览器上运行的JavaScript并不一定能在其他浏览器上运行。
如果没有对代码进行单元测试,那么在决定升级或支持新浏览器的时候,组织就需要花钱测试或重新测试Web应用程序。
在本文中,了解JavaScript单元测试如何帮助您降低测试成本,轻松支持更多浏览器。
一个损坏的JavaScript代码示例
Web应用程序面临的一个最大挑战是支持不同版本的Web浏览器。
能在Safari上运行的JavaScript代码不一定能在Windows®InternetExplorer(IE)、Firefox或GoogleChrome上运行。
这个挑战的根源是呈现层中的JavaScript代码从一开始就没有进行测试。
如果没有对代码进行单元测试,那么在升级或支持新浏览器后,组织可能需要花钱反复测试Web应用程序。
本文将展示如何通过高效的JavaScript代码单元测试降低测试成本。
一个常见用例是登录表单JavaScript验证。
考虑清单1中的表单。
清单1.登录表单
这个表单很简单,仅包含用户名和密码字段。
单击提交按钮时,将通过 ApplicationUtil 执行一个特定的表单验证。
以下是负责验证HTML表单的JavaScript对象。
清单2显示了 ApplicationUtil 对象的代码。
清单2.损坏的ApplicationUtil对象代码
appnamespace={};
appnamespace.ApplicationUtil=function(){};
appnamespace.ApplicationUtil.prototype.validateLoginForm=function(){
varerror=true;
document.getElementById("usernameMessage").innerText="";
document.getElementById("passwordMessage").innerText="";
if(!
document.getElementById("username").value){
document.getElementById("usernameMessage").innerText=
"Thisfieldisrequired";
error=false;
}
if(!
document.getElementById("password").value){
document.getElementById("passwordMessage").innerText=
"Thisfieldisrequired";
error=false;
}
returnerror;
};
在清单2中,ApplicationUtil 对象提供一个简单验证:
用户名和密码字段都已填充。
如果某个字段为空,就会显示一条错误消息:
Thisfieldisrequired。
上面的代码能够在InternetExplorer8和Safari5.1上工作,但无法在Firefox3.6上工作,原因是Firefox不支持 innerText 属性。
通常,(上述代码和其他类似JavaScript代码中的)主要问题是不容易发现编写的JavaScript代码是不是跨浏览器兼容的。
这个问题的一个解决方案是进行自动化单元测试,检查代码是不是跨浏览器兼容。
JsTestDriver
JsTestDriverlibrary是最好的JavaScript单元测试框架之一,它为JavaScript代码提供了跨浏览器测试。
图1展示了JsTestDriver的架构。
图1.JsTestDriver架构
捕获不同的浏览器之后,服务器会负责将JavaScript测试用例运行程序代码加载到浏览器中。
可以通过命令行捕获浏览器,也可以通过将浏览器指向服务器URL来捕获浏览器。
一旦捕获到浏览器,该浏览器就被称为从属浏览器。
服务器可以加载JavaScript代码,在每个浏览器上执行测试用例,然后将结果返回给客户端。
客户端(命令行)需要以下两个主要项目:
1.JavaScript文件,即源文件和测试文件
2.配置文件,用于组织源文件和测试文件的加载
这个架构比较灵活,允许单个服务器从网络中的其他机器捕获任意数量的浏览器。
例如,如果您的代码在Linux上运行但您想针对另一个Windows机器上的MicrosoftInternetExplorer运行您的测试用例,那么这个架构很有用。
要使用JsTestDriver库,请先下载最新版的 JsTestDriver1.3.2。
jsTestDriver是开源项目
jsTestDriver是 Apache2.0许可 下的一个开源项目,托管在GoogleCode上,后者是一个类似于SourceForge的项目存储库。
只要使用OpenSourceInitiative批准的 许可,开发人员就能在这个存储库中创建和管理公共项目。
还有许多其他JavaScript单元测试工具,请参见下面的 参考资料 部分中的其他工具,比如DojoObjectiveHarness(DOH)。
编写单元测试代码
现在开始编写JavaScript测试用例。
为简单起见,我将测试以下用例:
∙用户名和密码字段均为空。
∙用户名为空,密码不为空。
∙用户名不为空,密码为空。
清单3显示了表示TestCase对象的 ApplicationUtilTest 对象的部分代码。
清单3.ApplicationUtilTest对象代码的一部分
ApplicationUtilTest=TestCase("ApplicationUtilTest");
ApplicationUtilTest.prototype.setUp=function(){
/*:
DOC+= >
*/Username Password
};
ApplicationUtilTest.prototype.testValidateLoginFormBothEmpty=function(){
varapplicationUtil=newappnamespace.ApplicationUtil();
/*Simulateemptyusernameandpassword*/
document.getElementById("username").value="";
document.getElementById("password").value="";
applicationUtil.validateLoginForm();
assertEquals("Usernameisnotvalidatedcorrectly!
","Thisfieldisrequired",
document.getElementById("usernameMessage").innerHTML);
assertEquals("Passwordisnotvalidatedcorrectly!
","Thisfieldisrequired",
document.getElementById("passwordMessage").innerHTML);
};
ApplicationUtilTest 对象通过JsTestDriver TestCase 对象创建。
如果您熟悉JUnit框架,那么您肯定熟悉 setUp 和 testXXX 方法。
setUp 方法用于初始化测试用例。
对于本例,我使用该方法来声明一个HTML片段,该片段将用于其他测试用例方法。
DOC 注释是一个JsTestDriver惯用语,可以用于轻松声明一个HTML片段。
在 testValidateLoginFormBothEmpty 方法中,创建了一个 ApplicationUtil 对象,并在测试用例方法中使用该对象。
然后,代码通过检索用户名和密码的DOM元素并将它们的值设置为空值来模拟输入空用户名和密码。
可以调用 validateLoginForm 方法来执行实际表单验证。
最后,将调用 assertEquals 来确保usernameMessage 和 passwordMessage span元素中的消息是正确的,即:
Thisfieldisrequired。
在JsTestDriver中,可以使用以下构件:
∙fail("msg"):
表明测试一定会失败,消息参数将显示为一条错误消息。
∙assertTrue("msg",actual):
断定实际参数正确。
否则,消息参数将显示为一条错误消息。
∙assertFalse("msg",actual):
断定实际参数错误。
否则,消息参数将显示为一条错误消息。
∙assertSame("msg",expected,actual):
断定实际参数与预期参数相同。
否则,消息参数将显示为一条错误消息。
∙assertNotSame("msg",expected,actual):
断定实际参数与预期参数不相同。
否则,消息参数将显示为一条错误消息。
∙assertNull("msg",actual):
断定参数为空。
否则,消息参数将显示为一条错误消息。
∙assertNotNull("msg",actual):
断定实际参数不为空。
否则,消息参数将显示为一条错误消息。
其他方法的代码包含其他测试用例。
清单4显示了测试用例对象的完整代码。
清单4.ApplicationUtil对象完整代码
ApplicationUtilTest=TestCase("ApplicationUtilTest");
ApplicationUtilTest.prototype.setUp=function(){
/*:
DOC+= >
*/Username Password
};
ApplicationUtilTest.prototype.testValidateLoginFormBothEmpty=function(){
varapplicationUtil=newappnamespace.ApplicationUtil();
/*Simulateemptyusernameandpassword*/
document.getElementById("username").value="";
document.getElementById("password").value="";
applicationUtil.validateLoginForm();
assertEquals("Usernameisnotvalidatedcorrectly!
","Thisfieldisrequired",
document.getElementById("usernameMessage").innerHTML);
assertEquals("Passwordisnotvalidatedcorrectly!
","Thisfieldisrequired",
document.getElementById("passwordMessage").innerHTML);
};
ApplicationUtilTest.prototype.testValidateLoginFormWithEmptyUserName=function(){
varapplicationUtil=newappnamespace.ApplicationUtil();
/*Simulateemptyusernameandpassword*/
document.getElementById("username").value="";
document.getElementById("password").value="anyPassword";
applicationUtil.validateLoginForm();
assertEquals("Usernameisnotvalidatedcorrectly!
",
"Thisfieldisrequired",document.getElementById("usernameMessage").innerHTML);
assertEquals("Passwordisnotvalidatedcorrectly!
",
"",document.getElementById("passwordMessage").innerHTML);
};
ApplicationUtilTest.prototype.testValidateLoginFormWithEmptyPassword=function(){
varapplicationUtil=newappnamespace.ApplicationUtil();
document.getElementById("username").value="anyUserName";
document.getElementById("password").value="";
applicationUtil.validateLoginForm();
assertEquals("Usernameisnotvalidatedcorrectly!
",
"",document.getElementById("usernameMessage").innerHTML);
assertEquals("Passwordisnotvalidatedcorrectly!
",
"Thisfieldisrequired",document.getElementById("passwordMessage").
innerHTML);
};
配置用于测试的不同浏览器
测试JavaScript代码的一个推荐实践是将JavaScript源代码和测试代码放置在不同的文件夹中。
对于图2中的示例,我将JavaScript源文件夹命名为"js-src",将JavaScript测试文件夹命名为"js-test",它们都位于"js"父文件夹下。
图2.JavaScript测试文件夹结构
组织好源和测试文件夹后,必须提供配置文件。
默认情况下,JsTestDriver 运行程序会寻找名为jsTestDriver.conf的配置文件。
您可以从命令行更改配置文件名称。
清单5显示了 JsTestDriver 配置文件的内容。
清单5.JsTestDriver配置文件内容
server:
http:
//localhost:
9876
load:
-js-src/*.js
-js-test/*.js
配置文件采用YAML格式。
server 指令指定测试服务器的地址,load 指令指出了将哪些JavaScript文件加载到浏览器中以及加载它们的顺序。
现在,我们将在IE、Firefox和Safari浏览器上运行测试用例类。
要运行测试用例类,需要启动服务器。
您可以使用以下命令行启动 JsTestDriver 服务器:
java-jarJsTestDriver-1.3.2.jar--port9876--browser"[FirefoxPath]",
"[IEPath]","[SafariPath]"
使用这个命令行,服务器将以Port9876启动,捕获您的机器上的Firefox、IE和Safari浏览器。
启动并捕获浏览器后,可以通过以下命令行运行测试用例类:
java-jarJsTestDriver-1.3.2.jar--testsall
运行命令后,您将看到第一轮结果,如清单6所示。
清单6.第一轮结果
Total9tests(Passed:
6;Fails:
3;Errors:
0)(16.00ms)
Firefox3.6.18Windows:
Run3tests(Passed:
0;Fails:
3;Errors0)(8.00ms)
ApplicationUtilTest.testValidateLoginFormBothEmptyfailed(3.00ms):
AssertError:
Usernameisnotvalidatedcorrectly!
expected"Thisfield
isrequired"butwas""Error("Usernameisnotvalidatedcorrectly!
expected\"Thisfieldisrequired\"butwas\"\"")@:
0()@http:
//localhost
:
9876/test/js-test/TestApplicationUtil.js:
16
ApplicationUtilTest.testValidateLoginFormWithEmptyUserNamefailed(3.00ms):
AssertError:
Usernameisnotvalidatedcorrectly!
expected"Thisfieldis
required"butwas""Error("Usernameisnotvalidatedcorrectly!
expected
\"Thisfieldisrequired\"butwas\"\"")@:
0()@http:
//localhost:
9876/test
/js-test/TestApplicationUtil.js:
29
ApplicationUtilTest.testValidateLoginFormWithEmptyPasswordfailed(2.00ms):
AssertError:
Passwordisnotvalidatedcorrectly!
expected"Thisfieldis
required"butwas""Error("Passwordisnotvalidatedcorrectly!
expected
\"Thisfieldisrequired\"butwas\"\"")@:
0()@http:
//localhost:
9876/test/
js-test/TestApplicationUtil.js:
42
Safari534.50Windows:
Run3tests(Passed:
3;Fails:
0;Errors0)(2.00ms)
MicrosoftInternetExplorer8.0Windows:
Run3tests(Passed:
3;Fails:
0;
Errors0)(16.00ms)
Testsfailed:
Testsfailed.Seelogfordetails.
注意,在清单6中,主要问题出在Firefox上。
测试在InternetExplorer和Safari上均可顺利运行。
修复JavaScript代码并重新运行测试用例
我们来修复损坏的JavaScript代码。
我们将使用 innerHTML 替代 innerText。
清单7显示了修复后的 ApplicationUtil 对象代码。
清单7.修复后的ApplicationUtil对象代码
appnamespace={};
appnamespace.ApplicationUtil=function(){};
appnamespace.ApplicationUtil.prototype.validateLoginForm=function(){
va
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 高效 JavaScript 单元测试