运用D.O.H进行Javascript应用程序测试(一)

20 篇文章 0 订阅
13 篇文章 0 订阅

D.O.H的文档不太多,最重要的两篇(没有更多的了)应该是Unit testing Web 2.0 applications using the Dojo Objective Harness或者Unit Testing Custom Code with the Dojo Objective Harness。本篇先从Unit testing Web 2.0 applications using the Dojo Objective Harness(以下简称篇一)的例子入手,再沿着Unit Testing Custom Code with the Dojo Objective Harness的思路解析一下DOH框架的运用。

篇一给出的例子如下:

被测试代码:

dojo.provide("demo.doh.demoFunctions");

//This file contains a collection of helper functions that are not
//part of any defined dojo class.

demo.doh.demoFunctions.alwaysTrue = function() {
  //  summary:
  //    A simple demo helper function that always returns the boolean true when 
  //    called.
  //  description:
  //    A simple demo helper function that always returns the boolean true when 
  //    called.
  return true; // boolean.
};

demo.doh.demoFunctions.alwaysFalse = function() {
  //  summary:
  //    A simple demo helper function that always returns the boolean false when 
  //    called.
  //  description:
  //    A simple demo helper function that always returns the boolean false when 
  //    called.
  return false; // boolean.
};

demo.doh.demoFunctions.isTrue = function(/* anything */ thing) {
  //  summary:
  //    A simple demo helper function that returns true if the thing passed in is
  //     logically true.
  //  description:
  //    A simple demo helper function that returns true if he thing passed in is 
  //    logically true.
  //    This means that for any defined objects, or Boolean  values of true, it 
  //    should return true,
  //    For undefined, null, 0, or false, it returns false.
  //  thing:
  //    Anything.  Optional argument.
  var type = typeof thing;
  if (type === "undefined" || thing === null || thing === 0 || thing === false) {
    return false; //boolean
  }
  return true; // Boolean
};

demo.doh.demoFunctions.asyncEcho = function(/* function */ callback,
                                                    /* string */ message){ 
  //  summary:
  //    A simple demo helper function that does an asynchronous echo 
//     of a message.
  //  description:  
  //    A simple demo helper function that does an asynchronous echo 
//      of a message.
  //    The callback function is called and passed parameter 'message' 
//       two seconds 
  //    after this helper is called.
  //  callback:
  //    The function to call after waiting two seconds.  Takes one
//       parameter, 
  //    a string message.
  //  message:
  //    The message to pass to the callback function.
  if (dojo.isFunction(callback)) {
    var handle;
    var caller = function() {
      callback(message);
      clearTimeout(handle);
      handle = null;
    };
    handle = setTimeout(caller, 2000);
  }
};


测试代码是:

dojo.provide("demo.doh.tests.functions.demoFunctions");

//Import in the code being tested.
dojo.require("demo.doh.demoFunctions");

doh.register("demo.doh.tests.functions.demoFunctions", [
     function test_alwaysTrue(){
          //     summary:
          //          A simple test of the alwaysTrue function
          //     description:
          //          A simple test of the alwaysTrue function
          doh.assertTrue(demo.doh.demoFunctions.alwaysTrue());
     },
     function test_alwaysFalse(){
          //     summary:
          //          A simple test of the alwaysFalse function
          //     description:
          //          A simple test of the alwaysFalse function
          doh.assertTrue(!demo.doh.demoFunctions.alwaysFalse());
     },
     function test_isTrue(){
          //     summary:
          //          A simple test of the isTrue function
          //     description:
          //          A simple test of the isTrue function with multiple permutations of 
           //          calling it.
          doh.assertTrue(demo.doh.demoFunctions.isTrue(true));
          doh.assertTrue(!demo.doh.demoFunctions.isTrue(false));
          doh.assertTrue(demo.doh.demoFunctions.isTrue({}));
          doh.assertTrue(!demo.doh.demoFunctions.isTrue());
          doh.assertTrue(!demo.doh.demoFunctions.isTrue(null));
          doh.assertTrue(!demo.doh.demoFunctions.isTrue(0));
     },
     {
          //This is a full test fixture instead of a stand-alone test function.  
          //Therefore, it allows over-riding of the timeout period for a deferred test.  
          //You can also define setup and teardown function
          //for complex tests, but they are unnecessary here.
          name: "test_asyncEcho",
          timeout: 5000, // 5 seconds.
          runTest: function() {
               //     summary:
               //          A simple async test of the asyncEcho function.
               //     description:
               //          A simple async test of the asyncEcho function.
               var deferred = new doh.Deferred();
               var message  = "Success";
               function callback(string){
                    try {
                         doh.assertEqual(message, string);
                         deferred.callback(true);
                    } catch (e) {
                         deferred.errback(e);
                    }
               }
               demo.doh.demoFunctions.asyncEcho(callback, message);
               return deferred;      //Return the deferred.  DOH will 
                                     //wait on this object for one of the callbacks to 
                                     //be called, or for the timeout to expire.
          }
     }
]);


上面的测试代码已经包含了DOH框架,我们先运行起来看看结果。同样,为避免烦琐的运行环境设置,我们仍然使用firebug来完成全部工作。在跟着教程学习时常遇到的最大问题就是环境问题…如果全部工作都能在firebug中完成的话,那么显然是最简单的了–不过仍然还是有一点点环境设置的:

首先,通常我们可以使用Google的CDN发行的dojo,但是遗憾的是,这个发行中并不包含DOH框架,所以,我们需要去dojotoolkit.org下载它的完整发行包,并使用Apache/Nginx等server来host它。这个过程省去不写,假设最后dojo安装完成后可以通过http://example.com/dojolib/dojo/dojo.js来访问。检查一下这两个链接是否可以访问:

http://example.com/dojolib/util/doh/runner.js

http://example.com/dojolib/util/doh/_browserRunner.js

其次,你需要参照如何向网页动态注入dojo这篇文章了解如何向网页动态注入dojo。

假设你已经完成了上面的准备。现在,使用Firefox打开任意一个网页,并启动Firebug。点击bookmarklet向该网页注入dojo。然后在firebug控制台中输入以下命令,以注入DOH:

loadModule(“http://example.com/dojolib/util/doh/_browserRunner.js“);

loadModule(“http://example.com/dojolib/util/doh/runner.js“);

略等一会儿,在firebug中输入ls(doh),如果出现:

image

OK,DOH已经被注入到该网页当中了。这里有两个地方要注意:

loadModule和ls通过如何向网页动态注入dojo一文中提到的方法,向当前窗口注入的两个函数。其中loadModule的作用是将一个URL所指定的脚本文件注入到当前网页。而ls===console.dir()函数。

下面,将上文中的被测试代码和测试代码输入到firebug控制台窗口并运行。此时不会看到任何反馈。再运行下面的命令,完成单元测试:

doh.run();

doh.run()是DOH框架测试的主要入口,也是我们后面自己写测试页面需要调用的函数。

 

可是,什么结果也没有啊?教程里象下面这样的华丽界面呢?

image

显然,当我们通过firebug运行DOH时,不能期望上面的界面,只能看到命令行输出。但是,为什么命令行输出也没有呢?

doh._report()函数用来报告测试结果,但在正常的测试环境下(比如通过util/doh/runner.html运行),它被替换成跟环境相关的函数,而在我们这个测试环境中,仍然使用它原来定义的行为来输出测试结果。这个函数本身是这样定义的:

doh._report = function(){
	// summary:
	//		a private method to be implemented/replaced by the 'locally
	//		appropriate' test runner

	// this.debug('ERROR:');
	// this.debug('\tNO REPORTING OUTPUT AVAILABLE.');
	// this.debug('\tIMPLEMENT doh._report() IN YOUR TEST RUNNER');

	this.debug(this._line);
	this.debug('| TEST SUMMARY:');
	this.debug(this._line);
	this.debug('\t', this._testCount, 'tests in', this._groupCount, 'groups');
	this.debug('\t', this._errorCount, 'errors');
	this.debug('\t', this._failureCount, 'failures');
}
如果你看看debug()函数的定义,你会发现它什么也不做。因此,我们需要将其替换为console.log:

doh.debug = console.log

现在,再次运行doh.run(),现在你会得到:

image

注意本例的输出结果应该是4 tests to run in 1 groups,而非截屏中的8 tests。看起来这个例子并不太好,因为我们想看一下出现错误的情况。把被测试代码中任意一个函数的实现改成错误的实现,比如,让alwaysTrue返回false。再次重复上面的步骤,这次我们得到:

image

啊哈!没有繁琐的编写HTML,部署和设置,略微做了一点hack,我们就有了一个可能是史上部署最快的DOH测试。

最后,完整的代码附在附件中。你可以将文件打开,将代码拷贝到firefox命令窗口中运行。注意在加载DOH后(文件的前两行),要等一会儿才可以继续运行余下的代码。

注:有时候测试会因为 runner.js(1.61版)第1299行的if(this._paused){ return; }导致测试中止且没有结果输出。可以将这一行注释掉。在附件中该行已注释。


CSDN不支持js的附件,请访问http://www.lotus-scent.com/blog以获取附件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值