分析JsUnit

2001年初,Edward Hieatt开始“移植”JUnit,目的是在浏览器中测试JavaScript。从那以后,JsUnit的下载次数已近10 000次,大约300人加入了JsUnit的新闻组。JsUnit支持一般的xUnit功能,完全用JavaScript编写,如果你习惯使用JUnit 或者类似的xUnit框架,就会发现JsUnit使用起来相当简单直观。

  JsUnit也有一些不同的地方:这里也有setUp()和tearDown(),不过现在作为函数,而不是方法;测试函数(而不是测试方法)分成多个测试页(而不是测试用例);另外JsUnit提供了自己的基于HTML的测试运行工具。表6-1对这两个框架做了比较。

  表1 JUnit与JsUnit的比较

JUnit         JsUnit
Test类扩展 TestCase         测试页包含jsUnitCore.js
测试方法         测试函数
Test类         基于HTML的测试页
TestSuites         基于HTML的测试集
多个测试运行工具         基于HTML/JavaScript的测试运行工具
setUp()和tearDown()方法         setUp()和tearDown()函数
在虚拟机中运行         在浏览器中运行
用Java编写         用JavaScript编写

  1 起步

  对于JsUnit,起步很简单,只需从JsUnit网站(www.edwardh.com/jsunit/)下载JsUnit zip文件。把这个压缩文件解开,会得到一个jsunit文件夹,可以把Web服务器放在这里,这样整个团队或者整个组织就能更容易地使用JsUnit。 JsUnit的大部分“核心”都在jsunit/app目录中,在这里可以看到jsUnitCore.js、jsUnitTracer.js和 jsUnitTestManager.js,另外还有其他一些文件。如果你想运行具体的JsUnit测试,可以使用testRunner.html来运行 jsunit/tests目录中找到的任何测试页。如果你在使用IntelliJ,而且想具体使用JsUnit,jsunit/intellij目录中包含了需要的所有适当文件。

  2 编写测试

  用JsUnit编写测试与用JUnit编写测试很相似。测试函数不能有任何参数,必须有一个前缀test,例如testDateValidation()。测试函数包含在一个测试页(test page)中,这类似于JUnit中的一个Test类。测试页必须包含jsUnitCore.js文件,解开JsUnit zip文件后,就会在jsunit/app目录中找到这个文件。包含这个JavaScript文件实际上就是把一个外部JavaScript文件增加到页面中;只需使用脚本元素<script language="JavaScript" src="jsUnitCore.js"></script>来引用这个文件,要记住,如果你的当前目录不是jsunit/app目录,则还需要提供jsUnitCore.js文件的相关路径信息。当然,在测试页中可以包含任意多个其他函数或JavaScript;实际上,把多个 JavaScript函数放在分开的文件中,是一个很好的做法。测试函数也可以放在单独的JavaScript文件中;不过,如果这样做,就需要使用 exposeTestFunctionNames()方法,这样JsUnit才能找到测试函数。实际上,如果需要针对不同的页面内容建立测试,可以把测试函数放在一个单独的文件中,这样能避免复制-粘贴问题带来的痛苦。

  一般地,JsUnit会自动发现测试函数,就像JUnit会发现所有测试方法一样。不过,有些操作系统/浏览器不能合作。如果你发现不能如你所愿地发现测试函数,使用exposeTestFunctionNames()方法就能解决这个问题。

  断言方法

  现在你对测试函数和测试页有一定的了解了,下面需要写一些实际的测试!与用JUnit一样,你可以使用断言方法(assert method)。断言方法是任何单元测试的基本模块,它们只是一些简单的布尔表达式,可以指示一个给定语句为true还是false。断言失败时,就会产生一个错误,这样将得到众所周知的红条。与JUnit不同,JsUnit没有提供那么丰富的断言方法,但是已经足够你测试JavaScript代码了。注意,除了fail()方法的注释外,其他断言方法的注释都是可选的(这与JUnit类似,甚至也“不正确”地把可选参数放在最前面,而不是最后)。
  assert([comment], booleanValue)
  assertTrue([comment], booleanValue)
  assertFalse([comment], booleanValue)
  assertEquals([comment], value1, value2)
  assertNotEquals([comment], value1, value2)
  assertNull([comment], value)
  assertNotNull([comment], value)
  assertUndefined([comment], value)
  assertNotUndefined([comment], value)
  assertNaN([comment], value)
  assertNotNaN([comment], value)
  fail(comment)

  要看这些方法怎么用于测试(象征性地从字面了解),只需看JsUnit下载包提供的测试页就行了。JsUnit还提供了一个变量:JSUNIT_UNDEFINED_VALUE,它映射到JavaScript中的undefined变量。

  我们说的已经够多的了!下面来看一个简单的测试!这个例子中有一个简单的函数,会让两个数相加,而且有两个测试:一个用于正整数的相加,另一个用于负整数相加。要测试这个函数,先创建一个简单的Web页面,如代码清单1所示,其中包含了jsUnitCore.js文件,另外包含了要测试的函数和测试函数[4]。当然,在生产代码中,可能不能把测试代码与所测试的函数混在一起,但是作为第一次尝试这样做未尝不可。
  代码清单1 简单的测试页
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  <title>A Simple Test Page</title>
  <script language="JavaScript" src="../jsunit/app/jsUnitCore.js"></script>
  <script language="JavaScript">
  function addTwoNumbers(value1, value2) {
  return value1 + value2;
  }
  function testValidArgs() {
  assertEquals("2 + 2 is 4", 4, addTwoNumbers(2, 2));
  }
  function testWithNegativeNumbers() {
  assertEquals("negative numbers: -2 + -2 is -4", -4,
  addTwoNumbers(-2, -2));
  }
  </script>
  </head>
  <body>
  This is a simple test page for addTwoNumbers(value1, value2).
  </body>
  </html>

  运行这些测试会得到图1所示的结果。(后面将更详细地介绍测试运行工具。)

  

      图1 简单测试的结果

  显然,不太可能把生产代码(函数)与测试函数混在同一个测试页中。你可能会把生产代码放在一个单独的JavaScript文件中,然后在测试页中包含这个文件。代码清单2就采用了这种方法。

  代码清单2 一种更典型的方法
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  <title>Another Test Page</title>
  <script language="JavaScript" src="../jsunit/app/jsUnitCore.js"></script>
  <script language="JavaScript" src="simpleJS.js"></script>
  <script language="JavaScript">
  function testValidArgs() {
  assertEquals("2 + 2 is 4", 4, addTwoNumbers(2, 2));
  }
  function testWithNegativeNumbers() {
  assertEquals("negative numbers: -2 + -2 is -4", -4,
  addTwoNumbers(-2, -2));
  }
  </script>
  </head>
  <body>
  This is a simple test page for the simpleJS file.
  </body>
  </html>

  JavaScript文件实际上相当简单,如代码清单3所示。

  代码清单3 simple.js
  function addTwoNumbers(value1, value2) {
  return parseInt(value1) + parseInt(value2);
  }

  不出所料,结果是一样的(见图2)。



  图2 采用典型方法的结果

  可以看到,两个测试函数会自动被发现,而且通常都是这样。不过,如果打开测试页,点击Run之后什么也没有发生,可能就需要使用exposeTestFunctionNames(),以确保JsUnit能找到你的测试,如代码清单4所示。

  代码清单4 使用exposeTestFunctionNames()
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
  <head>
  <title>A Test Page With exposeTestFunctions</title>
  <script language="JavaScript" src="../jsunit/app/jsUnitCore.js"></script>
  <script language="JavaScript" src="simpleJS.js"></script>
  <script language="JavaScript">
  function testValidArgs() {
  assertEquals("2 + 2 is 4", 4, addTwoNumbers(2, 2));
  }
  function testWithNegativeNumbers() {
  assertEquals("negative numbers: -2 + -2 is -4", -4,
  addTwoNumbers(-2, -2));
  }
  function exposeTestFunctionNames() {
  var tests = new Array(2);
  tests[0] = "testValidArgs";
  tests[1] = "testWithNegativeNumbers";
  return tests;
  }
  </script>
  </head>
  <body>
  This is a simple test page that uses exposeTestFunctionNames.
  </body>
  </html>

  如你所愿,这样就能工作了(见图3)。

  如果看到如图4中所示的错误消息,说明你可能忘了在测试页中包含jsUnitCore.js,或者文件的路径不对。请检查测试页,再运行一次。

你可能感兴趣的:(JavaScript,html,浏览器,JUnit,单元测试)