`
sassds
  • 浏览: 154971 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

高效自动化 JavaScript 代码单元测试

    博客分类:
  • js
阅读更多

简介: 能在一个浏览器上运行的 JavaScript 并不一定能在其他浏览器上运行。如果没有对代码进行单元测试,那么在决定升级或支持新浏览器的时候,组织就需要花钱测试或重新测试 Web 应用程序。在本文中,了解 JavaScript 单元测试如何帮助您降低测试成本,轻松支持更多浏览器。

  一个损坏的 JavaScript 代码示例

  Web 应用程序面临的一个最大挑战是支持不同版本的 Web 浏览器。能在 Safari 上运行的 JavaScript 代码不一定能在 Windows® Internet Explorer (IE)、Firefox 或 Google Chrome 上运行。这个挑战的根源是呈现层中的 JavaScript 代码从一开始就没有进行测试。如果没有对代码进行单元测试,那么在升级或支持新浏览器后,组织可能需要花钱反复测试 Web 应用程序。本文将展示如何通过高效的 JavaScript 代码单元测试降低测试成本。

  一个常见用例是登录表单 JavaScript 验证。考虑 清单 1(登录表单) 中的表单。

       登陆表单代码

                
<FORM>
    
<table>
        
<tr>
            
<td>Username</td>
            <td><input type="text" id="username"/></td>
            
<td><span id="usernameMessage"></span></td>
        
</tr>
        <tr>
            
<td>Password</td>
            <td><input type="password" id="password"/></td>
            
<td><span id="passwordMessage"></span></td>
        
</tr>    
        <tr>
            
<td><input type="button" onclick="new appnamespace.
            ApplicationUtil().validateLoginForm()
" value="Submit"/></td>
        
</tr>
    </table>
</FORM>

   这个表单很简单,仅包含用户名和密码字段。单击提交按钮时,将通过 ApplicationUtil 执行一个特定的表单验证。以下是负责验证 HTML 表单的 JavaScript 对象。清单 2 显示了 ApplicationUtil 对象的代码。

      损坏的 ApplicationUtil 对象代码

appnamespace = {};

appnamespace.ApplicationUtil 
= function() {};

appnamespace.ApplicationUtil.prototype.validateLoginForm 
=  function(){
    
var error = true;
    document.getElementById(
"usernameMessage").innerText = "";
    document.getElementById(
"passwordMessage").innerText = "";    

    
if (!document.getElementById("username").value) {
        document.getElementById(
"usernameMessage").innerText = 
        
"This field is required";
        error 
= false;
    }
    
    
if (!document.getElementById("password").value) {
        document.getElementById(
"passwordMessage").innerText = 
        
"This field is required";
        error 
= false;
    }        

    
return error;        
};

  在清单 2 中,ApplicationUtil 对象提供一个简单验证:用户名和密码字段都已填充。如果某个字段为空,就会显示一条错误消息:This field is required。

  上面的代码能够在 Internet Explorer 8 和 Safari 5.1 上工作,但无法在 Firefox 3.6 上工作,原因是 Firefox 不支持 innerText 属性。通常,(上述代码和其他类似 JavaScript 代码中的)主要问题是不容易发现编写的 JavaScript 代码是不是跨浏览器兼容的。

  这个问题的一个解决方案是进行自动化单元测试,检查代码是不是跨浏览器兼容。

  JsTestDriver

  JsTestDriver library 是最好的 JavaScript 单元测试框架之一,它为 JavaScript 代码提供了跨浏览器测试。图 1 展示了 JsTestDriver 的架构。

  高效自动化 JavaScript 代码单元测试

  ▲JsTestDriver架构

  jsTestDriver 是开源项目

  jsTestDriver 是 Apache 2.0 许可 下的一个开源项目,托管在 Google Code 上,后者是一个类似于 SourceForge 的项目存储库。只要使用 Open Source Initiative 批准的 许可,开发人员就能在这个存储库中创建和管理公共项目。

  还有许多其他 JavaScript 单元测试工具,请参见下面的 参考资料 部分中的其他工具,比如 Dojo Objective Harness (DOH)。

  捕获不同的浏览器之后,服务器会负责将 JavaScript 测试用例运行程序代码加载到浏览器中。可以通过命令行捕获浏览器,也可以通过将浏览器指向服务器 URL 来捕获浏览器。一旦捕获到浏览器,该浏览器就被称为从属浏览器。服务器可以加载 JavaScript 代码,在每个浏览器上执行测试用例,然后将结果返回给客户端。

  客户端(命令行)需要以下两个主要项目:

  JavaScript 文件,即源文件和测试文件

  配置文件,用于组织源文件和测试文件的加载

  这个架构比较灵活,允许单个服务器从网络中的其他机器捕获任意数量的浏览器。例如,如果您的代码在 Linux 上运行但您想针对另一个 Windows 机器上的 Microsoft Internet Explorer 运行您的测试用例,那么这个架构很有用。

  要使用 JsTestDriver 库,请先下载最新版的 JsTestDriver 1.3.2

  编写单元测试代码

  现在开始编写 JavaScript 测试用例。为简单起见,我将测试以下用例:

  用户名和密码字段均为空。

  用户名为空,密码不为空。

  用户名不为空,密码为空。

  清单 3 显示了表示 TestCase 对象的 ApplicationUtilTest 对象的部分代码。

       ApplicationUtilTest 对象代码的一部分

ApplicationUtilTest = TestCase("ApplicationUtilTest");

ApplicationUtilTest.prototype.setUp 
= function () {
/*:DOC += <FORM action=""><table><tr><td>Username</td><td>
<input type="text" id="username"/></td><td><span id="usernameMessage">
</span></td></tr><tr><td>Password</td><td>
<input type="password" id="password"/></td><td><span id="passwordMessage"
></span></td></tr></table></FORM>
*/
};

ApplicationUtilTest.prototype.testValidateLoginFormBothEmpty 
= function () {
    
var applicationUtil = new appnamespace.ApplicationUtil();
    
    
/* Simulate empty user name and password */
    document.getElementById(
"username").value = "";
    document.getElementById(
"password").value = "";    
    
    applicationUtil.validateLoginForm();
    
    assertEquals(
"Username is not validated correctly!""This field is required"
    document.getElementById(
"usernameMessage").innerHTML);
    assertEquals(
"Password is not validated correctly!""This field is required"
    document.getElementById(
"passwordMessage").innerHTML);    
};

   ApplicationUtilTest 对象通过 JsTestDriver TestCase 对象创建。如果您熟悉 JUnit 框架,那么您肯定熟悉 setUp 和 testXXX 方法。setUp 方法用于初始化测试用例。对于本例,我使用该方法来声明一个 HTML 片段,该片段将用于其他测试用例方法。

  DOC 注释是一个 JsTestDriver 惯用语,可以用于轻松声明一个 HTML 片段。

  在 testValidateLoginFormBothEmpty 方法中,创建了一个 ApplicationUtil 对象,并在测试用例方法中使用该对象。然后,代码通过检索用户名和密码的 DOM 元素并将它们的值设置为空值来模拟输入空用户名和密码。可以调用 validateLoginForm 方法来执行实际表单验证。最后,将调用 assertEquals 来确保 usernameMessage 和 passwordMessage span 元素中的消息是正确的,即:This field is required。

  在 JsTestDriver 中,可以使用以下构件:

  fail("msg"):表明测试一定会失败,消息参数将显示为一条错误消息。

  assertTrue("msg", actual):断定实际参数正确。否则,消息参数将显示为一条错误消息。

  assertFalse("msg", actual):断定实际参数错误。否则,消息参数将显示为一条错误消息。

  assertSame("msg", expected, actual):断定实际参数与预期参数相同。否则,消息参数将显示为一条错误消息。

  assertNotSame("msg", expected, actual):断定实际参数与预期参数不相同。否则,消息参数将显示为一条错误消息。

  assertNull("msg", actual):断定参数为空。否则,消息参数将显示为一条错误消息。

  assertNotNull("msg", actual):断定实际参数不为空。否则,消息参数将显示为一条错误消息。

  其他方法的代码包含其他测试用例。清单 4 显示了测试用例对象的完整代码。

      ApplicationUtil 对象完整代码

ApplicationUtilTest = TestCase("ApplicationUtilTest");

ApplicationUtilTest.prototype.setUp 
= function () {
/*:DOC += <FORM action=""><table><tr><td>Username</td><td>
<input type="text" id="username"/></td><td><span id="usernameMessage">
</span></td></tr><tr><td>Password</td><td>
<input type="password" id="password"/></td><td><span id="passwordMessage"
></span></td></tr></table></FORM>
*/
};

ApplicationUtilTest.prototype.testValidateLoginFormBothEmpty 
= function () {
    
var applicationUtil = new appnamespace.ApplicationUtil();
    
    
/* Simulate empty user name and password */
    document.getElementById(
"username").value = "";
    document.getElementById(
"password").value = "";    
    
    applicationUtil.validateLoginForm();
    
    assertEquals(
"Username is not validated correctly!""This field is required"
    document.getElementById(
"usernameMessage").innerHTML);
    assertEquals(
"Password is not validated correctly!""This field is required"
    document.getElementById(
"passwordMessage").innerHTML);    
};

ApplicationUtilTest.prototype.testValidateLoginFormWithEmptyUserName 
= function () {
    
var applicationUtil = new appnamespace.ApplicationUtil();
    
    
/* Simulate empty user name and password */
    document.getElementById(
"username").value = "";
    document.getElementById(
"password").value = "anyPassword";    
    
    applicationUtil.validateLoginForm();
    
    assertEquals(
"Username is not validated correctly!"
    
"This field is required", document.getElementById("usernameMessage").innerHTML);
    assertEquals(
"Password is not validated correctly!"
    
"", document.getElementById("passwordMessage").innerHTML);    
};

ApplicationUtilTest.prototype.testValidateLoginFormWithEmptyPassword 
= function () {
    
var applicationUtil = new appnamespace.ApplicationUtil();
    
    document.getElementById(
"username").value = "anyUserName";
    document.getElementById(
"password").value = "";    
    
    applicationUtil.validateLoginForm();
    
    assertEquals(
"Username is not validated correctly!"
    
"", document.getElementById("usernameMessage").innerHTML);
    assertEquals(
"Password is not validated correctly!"
    
"This field is required", document.getElementById("passwordMessage").
    innerHTML);    
};

配置用于测试的不同浏览器

  测试 JavaScript 代码的一个推荐实践是将 JavaScript 源代码和测试代码放置在不同的文件夹中。对于 图 2 中的示例,我将 JavaScript 源文件夹命名为 "js-src",将 JavaScript 测试文件夹命名为 "js-test",它们都位于 "js" 父文件夹下。

  高效自动化 JavaScript 代码单元测试

  ▲JavaScript测试文件夹结构

  组织好源和测试文件夹后,必须提供配置文件。默认情况下,JsTestDriver 运行程序会寻找名为 jsTestDriver.conf 的配置文件。您可以从命令行更改配置文件名称。清单 5 显示了 JsTestDriver 配置文件的内容。 

      JsTestDriver 配置文件内容代码 

server: http://localhost:9876

load:
  
- js-src/*.js
  - js-test/*.js

   配置文件采用 YAML 格式。server 指令指定测试服务器的地址,load 指令指出了将哪些 JavaScript 文件加载到浏览器中以及加载它们的顺序。

现在,我们将在 IE、Firefox 和 Safari 浏览器上运行测试用例类。

  要运行测试用例类,需要启动服务器。您可以使用以下命令行启动 JsTestDriver 服务器:

java -jar JsTestDriver-1.3.2.jar --port 9876 --browser "[Firefox Path]",
          
"[IE Path]","[Safari Path]"

   使用这个命令行,服务器将以 Port 9876 启动,捕获您的机器上的 Firefox、IE 和 Safari 浏览器。

  启动并捕获浏览器后,可以通过以下命令行运行测试用例类:

java -jar JsTestDriver-1.3.2.jar --tests all

        运行命令后,您将看到第一轮结果,如 清单6(  第一轮结果)  所示。

         第一轮结果

Total 9 tests (Passed: 6; Fails: 3; Errors: 0) (16.00 ms)
  Firefox 
3.6.18 Windows: Run 3 tests (Passed: 0; Fails: 3; Errors 0) (8.00 ms)
    ApplicationUtilTest.testValidateLoginFormBothEmpty failed (
3.00 ms): 
    AssertError: Username is not validated correctly
! expected "This field 
    is required
" but was "" Error("Username is not validated correctly! 
    expected \"This field is required\" but was \"\"
")@:0()@http://localhost
    :9876/test/js-test/TestApplicationUtil.js:16

    ApplicationUtilTest.testValidateLoginFormWithEmptyUserName failed (
3.00 ms): 
    AssertError: Username is not validated correctly
! expected "This field is 
    required
" but was "" Error("Username is not validated correctly! expected 
    \"This field is required\" but was \"\"
")@:0()@http://localhost:9876/test
    /js-test/TestApplicationUtil.js:29

    ApplicationUtilTest.testValidateLoginFormWithEmptyPassword failed (
2.00 ms): 
    AssertError: Password is not validated correctly
! expected "This field is 
    required
" but was "" Error("Password is not validated correctly! expected 
    \"This field is required\" but was \"\"
")@:0()@http://localhost:9876/test/
    js-test/TestApplicationUtil.js:42
    
  Safari 
534.50 Windows: Run 3 tests (Passed: 3; Fails: 0; Errors 0) (2.00 ms)
  Microsoft Internet Explorer 
8.0 Windows: Run 3 tests (Passed: 3; Fails: 0
  Errors 
0) (16.00 ms)
Tests failed: Tests failed. See log 
for details.

  注意,在清单 6 中,主要问题出在 Firefox 上。测试在 Internet Explorer 和 Safari 上均可顺利运行。

         修复 JavaScript 代码并重新运行测试用例

  我们来修复损坏的 JavaScript 代码。我们将使用 innerHTML 替代 innerText。清单 7 显示了修复后的 ApplicationUtil 对象代码。

       修复后的 ApplicationUtil 对象代码

appnamespace = {};

appnamespace.ApplicationUtil 
= function() {};

appnamespace.ApplicationUtil.prototype.validateLoginForm 
=  function(){
    
var error = true;
    document.getElementById(
"usernameMessage").innerHTML = "";
    document.getElementById(
"passwordMessage").innerHTML = "";    

    
if (!document.getElementById("username").value) {
        document.getElementById(
"usernameMessage").innerHTML = 
        
"This field is required";
        error 
= false;
    }
    
    
if (!document.getElementById("password").value) {
        document.getElementById(
"passwordMessage").innerHTML = 
        
"This field is required";
        error 
= false;
    }        

    
return error;        
};

  使用 --test all 命令行参数重新运行测试用例对象。清单 8 显示了第二轮运行结果。

        第二轮运行结果

Total 9 tests (Passed: 9; Fails: 0; Errors: 0) (9.00 ms)
  Firefox 
3.6.18 Windows: Run 3 tests (Passed: 3; Fails: 0; Errors 0) (9.00 ms)
  Safari 
534.50 Windows: Run 3 tests (Passed: 3; Fails: 0; Errors 0) (5.00 ms)
  Microsoft Internet Explorer 
8.0 Windows: Run 3 tests (Passed: 3; Fails: 0; Errors0
  (
0.00 ms)

  如清单 8(第二轮运行结果) 所示,JavaScript 代码现在在 IE、Firefox 和 Safari 上都能正常运行。

  结束语

  在本文中,您了解了如何使用一个最强大的 JavaScript 单元测试工具 (JsTestDriver) 在不同的浏览器上测试 JavaScript 应用程序代码。还了解了什么是 JsTestDriver,如何配置它,以及如何在 Web 应用程序中使用它来确保应用程序的 JavaScript 代码的质量和可靠性。

源码下载地址:http://www.ibm.com/developerworks/apps/download/index.jsp?contentid=777136&filename=simple.zip&method=http&locale=zh_CN

关于下载方法的信息:http://www.ibm.com/developerworks/cn/whichmethod.html

分享到:
评论

相关推荐

    javascript代码自动生成

    JavaScript代码自动生成是一种提高开发效率和减少重复劳动的技术,它涉及到编程语言的元编程和自动化工具。在JavaScript中,代码自动生成通常通过模板引擎、代码生成库或构建工具实现,帮助开发者快速创建复杂的代码...

    自动化平台测试开发-包含pdf文档.zip

    首先,自动化测试平台的选择至关重要,常见的有Selenium用于Web应用测试,Appium针对移动应用,JUnit和PyTest适用于单元测试,而Jenkins和GitLab CI/CD则在构建和部署自动化方面表现出色。选择合适的平台需要考虑...

    JSUnit Javascript单元测试

    JSUnit是专为JavaScript设计的一个单元测试框架,它使得JavaScript应用程序的测试变得更加系统化和自动化。下面将详细介绍JSUnit以及其在JavaScript单元测试中的应用。 首先,让我们理解什么是单元测试。单元测试是...

    自动化测试案例自动化测试案例

    常见的自动化测试工具有Selenium(适用于Web应用)、Appium(移动应用测试)、Junit和TestNG(Java单元测试)、Postman(API测试)等。选择工具时应考虑其兼容性、易用性、社区支持和成本等因素。 三、编写测试脚本...

    JavaScript单元测试Jasmine源代码

    Jasmine是一款流行的JavaScript测试框架,尤其适用于前端开发者,它提供了丰富的断言库和易于理解的语法,使得JavaScript的单元测试变得简单且高效。 Jasmine的核心理念在于“行为驱动开发”(Behavior Driven ...

    JavaScript 自动化测试框架 Intern.zip

    总之,JavaScript 自动化测试框架 Intern 是一个全面的测试解决方案,它提供的强大功能和灵活性使得测试工作变得更加高效和可靠,无论是对于前端还是后端的 JavaScript 代码,都能提供有效的测试保障。

    基于javascript办公室自动化系统

    这个压缩包可能包含了一个完整的办公室自动化系统项目,包括前端代码、后端代码、配置文件、测试数据等。解压后,开发者可以通过阅读代码了解实际的实现方式,学习如何将上述功能点整合在一起,形成一个完整的系统。...

    基于机器学习的JavaScript恶意代码检测系统的研究与实现

    近年来,机器学习技术在恶意代码检测领域的应用越来越广泛,其高效的数据处理能力和自动化特征提取能力为解决上述问题提供了新的可能。本文研究并实现了一种基于机器学习的JavaScript恶意代码检测系统。系统首先通过...

    基于字符熵的JavaScript代码混淆自动检测方法.pdf

    通过这种方式,该方法能够快速、自动化地检测混淆的JavaScript代码,对于提升Web安全防护能力,尤其是对于及时发现和防御恶意JavaScript代码具有重要意义。此外,这种方法的计算复杂度相对较低,适合大规模代码库的...

    WEB前端自动化优化工具-代码语法检测-代码压缩

    同时,持续集成/持续部署(CI/CD)工具如Jenkins、Travis CI或者GitHub Actions可以自动化构建、测试和部署流程,确保每次代码提交都能通过质量检查,快速发布到生产环境。 总的来说,WEB前端的自动化优化工具通过...

    腾讯Android自动化测试实战电子书

    总的来说,“腾讯Android自动化测试实战电子书”会深入讲解如何结合腾讯的实际案例,运用以上提到的各种工具和技术,构建一套高效且稳定的Android自动化测试体系,提升软件质量和开发效率。这本书对于任何希望在...

    基于Python的Canvas画布元素定位在HolliView项目自动化测试中的应用.rar

    在HolliView项目的自动化测试中,使用Python进行Canvas画布元素定位是一种高效且灵活的方法。Canvas是HTML5中用于在网页上绘制图形的元素,它提供了丰富的API来创建动态、交互式的图形。Python则以其强大的库支持和...

    网站图文展示JavaScript代码

    本文将深入探讨如何利用JavaScript来创建一个高效的网站图文展示功能。 首先,我们要理解JavaScript的基本概念。JavaScript是一种解释型、跨平台的编程语言,主要应用于Web开发,用于增加网页的动态效果和交互性。...

    selenium自动化测试平台源码

    【Selenium自动化测试平台源码】是...总之,这个开源的Selenium自动化测试平台源码提供了一个学习自动化测试实践和代码组织的好机会,通过深入研究,可以提升你的自动化测试技能,并理解如何构建高效、灵活的测试框架。

    (安卓平台上的JavaScript自动化工具).zip

    总的来说,安卓平台上的JavaScript自动化工具为开发者提供了强大的能力,帮助他们更高效地完成测试和开发工作。无论是进行自动化测试,还是通过React Native等框架进行原生应用开发,JavaScript都在安卓生态系统中...

    python+selenium+unittest自动化测试demo

    Python+Selenium+Unittest自动化测试框架是一个强大的组合,用于高效地进行Web应用的自动化测试。在本示例中,我们看到一个基于这三个组件构建的自动化测试项目,它提供了丰富的功能,如测试用例管理、批量执行、...

    高效自动化测试框架:基于Wilsonic RemoteAPI的Python源码实现

    项目概述:高效自动化测试框架 本项目采用Python作为主要开发语言,集成了C、HTML、JavaScript、CSS、Lua和C++等多种编程语言,共包含15,431个文件。文件类型丰富,主要包括: - Python编译文件(pyc):6,303个 -...

    自动化测试示例TestDemo完善最新版本

    自动化测试在IT行业中扮演着至关重要的角色,它能够显著提高软件开发效率,减少手动测试的工作量,提升产品质量。本示例项目"TestDemo"的最新版本专注于自动化测试,集成了JUnit、HttpUnit、JMock以及JUnitEE,并且...

    Selenium自动化测试培训

    总的来说,Selenium自动化测试培训课程是一个全面且深入的学习路径,涵盖了从基础到高级的Selenium测试技术,旨在提升测试人员的自动化测试能力,推动高效、可靠的软件测试流程。通过系统学习,学员不仅能掌握...

    javascript 测试工具

    JavaScript测试工具是开发高质量JavaScript代码的关键组成部分。它们帮助开发者确保代码的正确性和稳定性,通过自动化测试来找出潜在的错误和缺陷。在JavaScript的世界里,有许多优秀的测试框架和库可供选择,其中...

Global site tag (gtag.js) - Google Analytics