前言

  项目中需要用到前端自动化测试,自己被当作一个探针研究了下目前用的比较多的web自动化测试工具。一开始研究的是的selenium,但由于项目使用了大量的dijit控件,写起testCase来很费劲;最主要的是selenium有严重的浏览器兼容性问题,于是彻底放弃,改投doh门下,毕竟是dojo他爸爸开发的跟dojo继承起来非常方便。这几篇主要介绍doh、doh/Robot以及将doh与selenium结合进而与CI工具集成起来。

  一、DOH 是什么

  DOH 是 Dojo Objective Harness 的简称,是 Dojo 在 0.9 版本之后新增的单元测试工具。随着 Javascript 代码的数量和复杂度的增加,Web 前端开发者也需要一个 Javascript 代码的单元测试框架来保证自己写出来的 Javascript 代码是健壮的。所以,DOH 是 Web 前端开发者对 JUnit 的回应。DOH有如下特点:

  1. 提供用户界面:JUnit中的红条测试失败、绿条测试通过,大家都已经很熟悉了,DOH也有类似的用户界面,用户在测试时更加一目了然;
  2. 平台无关:DOH并不依赖某种浏览器平台,甚至不依赖于浏览器;用户可以根据自己的需要在命令行进行Javascript的自动化单元测试;
  3. 支持Ajax:Ajax编程在Web前端开发中是必不可少的一环,DOH最有价值的一个特性就是支持Ajax的测试;
  4. 不只适合与于Dojo,可用于任何JavaScript程序的单元测试。

  下载dojo源码包,解压后可以看到以下目录:

  

  二、DOH第一次亲密接触

  部署到服务器后,我们访问runner.html

    

  与JUnit类似,DOH也为我们提供了一个类似的界面,左侧表示运行的测试案例,右侧是测试日志,最上方的进度条表示的是本次运行中的已执行案例,同样绿色表示成功,红色表示失败。默认情况下会加载“dojo/tests/module.js”文件,该文件的作用就是像runner.html中加载dojo所有核心模块的测试案例。

  

  如果想要单独加载某一模块的测试案例,需要用到test参数指向该模块:

http://<server>/util/doh/runner.html?test=dojo/tests/fx

  

  我们可以吧测试案例放到自己的项目目录下,通过test参数指向自定义测试模块,这时需要用到paths参数:

 util/doh/runner.html?paths=org/myorg,../../../mycode/org/myorg&test=org/myorg/mymodule/tests/alltests

  paths参数中逗号前后的值相当于dojoConfig定义packages对象时的name和location    

  

  同样在path中我们可以定义多个模块, 模块之间用“;”分隔开来

util/doh/runner.html?paths=org/myorg,../../../mycode/org/myorg;com/mycom,../../../x/com/mycom&test=com/mycom/tests

  doh中测试模块要么是一个用来请求多个测试文件的文件,要么是一个使用doh.register方法注册时测试案例,或者两者皆有。

define([
"my/test/widget/Foo0",
"my/test/widget/Foo1",
"my/test/widget/Foo2"
]);

  或者

define(["doh/runner"], function(doh){

    doh.register("MyTests", [
function assertTrueTest(){
doh.assertTrue(true);
doh.assertTrue(1);
doh.assertTrue(!false);
},
{
name: "thingerTest",
setUp: function(){
this.thingerToTest = new Thinger();
this.thingerToTest.doStuffToInit();
},
runTest: function(){
doh.assertEqual("blah", this.thingerToTest.blahProp);
doh.assertFalse(this.thingerToTest.falseProp);
// ...
},
tearDown: function(){
}
},
// ...
]); });

  三、测试用例

  doh为我们提供了以下断言函数:

doh.assertTrue(boolean)
Note: This function is aliased to doh.t(); doh.assertFalse(boolean)
Note: This function is aliased to doh.f(); doh.assertEqual(obj1, obj2)
Note: This function is aliased to doh.is(); doh.assertNotEqual(obj1, obj2)
Note: This function is aliased to doh.isNot();

  Junit中,编写一个测试用例我们需要继承Junit类,同样在doh中也有自己的规则来将一段代码,包装成doh可识别的测试案例。

  doh中主要提供了以下方法(最常用的就是doh.register):

doh.register(...)
An almost 'magical' function. The doh.register() method accepts the function signatures of any of the other registration functions and determines the correct underlying function (listed below) to dispatch registration to. It's the function you'll most commonly use for registering Unit Tests.
doh.registerTest(group, testFuncOrObj)
This function registers a test as a member of the group 'group', and the test can either be a simple function definition or a 'Test Fixture', which is an object that defines the run requirements of the test.
doh.registerTests(group, testFuncOrObjArr)
This function registers an array of tests as a member of the group 'group'. The contents of the array of tests can be an array of simple test functions or an array of 'test fixtures', or a mix of them.
doh.registerTestNs(group, obj)
This function registers an object comprised of functions as a member of the group 'group'. Note that this function will only add in non-private (functions without an _ at the beginning of the name), as a test function. If you'd like to use fixtures (setUp(), tearDown(), and runTest()), please use doh.register(), doh.registerTest() or doh.registerTests().
doh.registerTestUrl(url)
This function registers a URL as a location to load tests from. The URL is used to populate the contents of an iframe, and usually refers to an HTML page that boot-loads D.O.H. internally for running tests in a segmented iframe. A good example showing this is the dojo/tests/fx.html. It loads dojo, doh, and then on dojo load completion calls doh.registerTests(). The D.O.H. instance in the iframe will proxy back the results of the test run to the primary D.O.H. instance.

  上面提到的dojo/test/fx模块中我们可以看到该文件中主要定义了两个TestSuite:

define(["doh/main", "require"], function(doh, require){
if(doh.isBrowser){
doh.register("tests.fx", require.toUrl("./fx.html"), 30000);
doh.register("tests.NodeList-fx", require.toUrl("./NodeList-fx.html"), 30000);
}
});

  对应于runner.html中

  

  打开该目录下的fx.html文件,我们可以看到该文件中定义了一系列TestCase

  

  doh中有两种测试结构:

  1、Simple Tests  将一个单独的函数放到doh.register参数testCase数组里

  同步形式:

function mySimpleTest(doh){
doh.assertTrue(true);
}

  异步形式:

function mySimpleAsyncTest(doh){
var deferred = new doh.Deferred();
setTimeout(deferred.getTestCallback(function(){
doh.assertTrue(true);
}), 100);
return deferred;
}

2、Test Fixture

  同步形式:

{
name: "thingerTest",
setUp: function(){
// Setup to do before runTest.//类似于JUnit中的@beforeTest
this.thingerToTest = new Thinger();
this.thingerToTest.doStuffToInit();
},
runTest: function(){
// Our test function to run.//类似于JUnit中的@Test
doh.assertEqual("blah", this.thingerToTest.blahProp);
doh.assertFalse(this.thingerToTest.falseProp);
// ...
},
tearDown: function(){
// cleanup to do after runTest.//类似于JUnit中的@afterTest
},
timeout: 3000 // 3 second timeout.//测试运行时间,超过改时间会报错
}

  异步形式:

{
name: "thingerTest",
setUp: function(){
// Setup to do before runTest.
this.thingerToTest = new Thinger();
this.thingerToTest.doStuffToInit();
},
runTest: function(){
// Our test function to run.
var deferred = new doh.Deferred();
setTimeout(deferred.getTestCallback(function(){
doh.assertEqual("blah", this.thingerToTest.blahProp);
doh.assertFalse(this.thingerToTest.falseProp);
}), 100);
return deferred;
},
tearDown: function(){
// cleanup to do after runTest.
},
timeout: 3000 // 3 second timeout.
}

参考资料:

http://www.infoq.com/cn/articles/dojo-unit-test-DOH/

http://tech.ddvip.com/2010-04/1271148731150772_2.html

随机推荐

  1. 【CentOS】安装RPM包或者源码包

    一.rpm  (是Redheat Package Manager的简称) 如果光驱中还有系统安装盘的话, 1.先挂载光驱, mount /dev/cdrom /mnt/ 2.cd /mnt/ 3.cd ...

  2. RSA密钥生成与使用

    RSA密钥生成与使用 openssl生成工具链接:http://pan.baidu.com/s/1c0v3UxE 密码:uv48 1. 打开openssl密钥生成软件打开 openssl 文件夹下的  ...

  3. Python爬虫基础知识入门一

    一.什么是爬虫,爬虫能做什么 爬虫,即网络爬虫,大家可以理解为在网络上爬行的一直蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛咯,如果它遇到资源,那么它就会抓取下来.比如它在抓取一个网 ...

  4. HPCC 登录总结

    最近开始做NGS的分析,数据明显更大,在自己的机子上面做有些不现实了,需要登录高性能计算机. 1. 目录结构: home directory: /auto/rcf-40/USERNAME -- onl ...

  5. 【开发记录】iOS中使用 Reachability 检测网络

    如果你想在iOS程序中提供一仅在wifi网络下使用(Reeder),或者在没有网络状态下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测. 写本文的目的 了解Re ...

  6. 234. Palindrome Linked List

    题目: Given a singly linked list, determine if it is a palindrome. Follow up:Could you do it in O(n) t ...

  7. 【转】ant命令总结

    http://feiyeguohai.iteye.com/blog/1295922 ant命令总结 1 Ant是什么?  Apache Ant 是一个基于 Java的生成工具. 生成工具在软件开发中用 ...

  8. QLGame 2D Engine编写环境搭建

    QLGame 2D Engine编写 (win7环境搭建) 广州麒麟网络工作室,计划制作一款2d game engine,基于opengl(es)平台,暂时支持android,以后考虑支持linux, ...

  9. python——BS解析器

  10. struts2日常

    更新struuts2 的action后不能马上反应,要重启服务器才可以,加上 <constant name="struts.devMode" value="true ...