锁定老帖子 主题:Ajax,你补过钙了吗?
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-08-03
这一段让我印象非常深刻。如果说测试驱动和持续集成相当于为我们的代码集体补了钙的话,那么既然 Ajax 现在已经被当作了一种主流严肃的软件开发方式(已经有相关的专著出版发行。然而多年以来,JavaScript 开发并不被认为是严肃的软件开发),那么 Ajax 当然也要补补钙。 对于 JavaScript/ECMAScript 代码的自动测试已经有了一些框架,我在这里介绍两个: 1、比较老一些,功能非常完善,也更加成熟的 JsUnit: http://www.edwardh.com/jsunit/ 这个测试框架可以运行在所有主流的浏览器中。并且可以与 Ant 结合起来做完全自动的单元测试。以命令行的方式进行完全自动的单元测试对于建造一个持续集成的环境是非常重要的。 2、一个比较新的测试框架 ECMAUnit: http://kupu.oscom.org/download/ 这个框架使用起来更加简单(核心只有一个 JS 文件),也可以运行在所有主流的浏览器中。还可以使用 JavaScript 解析器 SpiderMonkey (http://www.mozilla.org/js/spidermonkey/)在命令行上运行测试。 但是这个框架刚刚起步,没有与 Ant 进行集成,因此对于持续集成的支持也比较弱。当然你也可以使用 Ant 来调用 SpiderMonkey 实现自动测试,这也是非常容易做到的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2005-08-03
jsunit不错的,另外,完全可以单独做HTML来测试,效果不错,只是没有集成的环境,稍稍有点麻烦
|
|
返回顶楼 | |
发表时间:2005-08-03
为了显示我确实会写茴香豆的茴字的四种写法,再加一些资料。
实际上另外还有一个同样叫做 JsUnit 的框架: http://jsunit.berlios.de 不过这个框架只能运行于浏览器之中,不支持使用 Ant 直接在命令行上运行,因此也就不能和持续集成工具结合在一起。这个项目已经是一个死的项目,已经有将近 3 年没有发布过新的版本。 与 commons-log 一样,有人写了一个 wrapper 封装这两个 JsUnit 的差异(虽然我觉得并无必要,但是不能不赞叹老外不厌其烦地把这些事情做彻底的精神)。 http://burstproject.org/build/tooldoc/JsTestManager/jsunit__wrap_8js.html 实际上为一种语言写一个 xUnit 框架是一件很简单的事情,在 Kent Beck 的《测试驱动开发》一书中,Kent Beck 手把手讲解他如何为 Python 开发这样一个框架的全过程。如果不是为了写书,他开发出这样一个框架最多只需要一下午的时间。 第一个 JsUnit 框架使用的很多,现在使用 ECMAUnit 的项目包括: Sarissa:一个封装不同浏览器差异的库 http://sarissa.sourceforge.net Zope:Zope 也决定拥抱 Ajax 了,这里是 Zope 如何支持 Ajax 的文档。我们看到 Zope 所提供的 JS 代码是经过 ECMAUnit 测试的。 http://www.z3lab.org/sections/front-page/white-papers/draft-ajax/downloadFile/file/ajax_in_zope.pdf |
|
返回顶楼 | |
发表时间:2005-08-03
呵呵,我说的那个jsunit是你指的第一个jsunit,
我不知道你指的ANT集成测试是怎么回事, 我也忘了最初自己是怎么了解的这个JSUNIT的乐, 有一部分可能不错的功能是需要开服务器的, 至少初初看到的部分jsunit.jar的代码是这样的, 我一般都是拿来直接做JS代码的单元测试, 因此跑服务器来运行测试太奢侈, 在EDITPLUS里面配置一下命令行(修改乐下JSUNIT内部运行的脚本文件,使它可以接受命令脚本),在使用EDITPLUS编辑代码的同时来方便跑测试,效率上还算可以接受,后来也没有使用它做其它方面的单元测试,因此就一直这么使用乐。 总体上说,这个jsunit是不错的乐,不过一早就不维护乐,但是功能齐乐就OK乐, 在JS的单元测试上,要自己做个也可以,不过我估计还是蛮少人能做到它这样的,最初我也是自己做,后来找到它就放弃乐。 另外,还有个IEUNIT(连接懒得找乐,应该很容易搜索到),似乎也不错,不过没有深入去研究。 |
|
返回顶楼 | |
发表时间:2005-08-03
swing 写道 我不知道你指的ANT集成测试是怎么回事,
你还没有看他们的文档吗?文档中写得很清楚啊。 http://www.edwardh.com/jsunit/documentation/index.html 我来讲讲它是如何与 Ant 相结合的。 这个 JsUnit 提供了一个 JUnit 的 TestCase: net.jsunit.StandaloneTest 这个 TestCase 可以在 JUnit 的 TestSuite 或者 Ant 的 junit 任务中调用。在测试过程中,它会自动打开某种浏览器(IE、FireFox、etc.),运行所有的测试用例,然后关闭浏览器,将返回结果输出到命令行并且保存到与 JUnit 格式完全相同的 xml 报表文件中。 JsUnit 有两种工作方式,本地 standalone_test 方式和远程 distributed_test 方式,上面讲的是 standalone_test 方式。对于 distributed_test 方式情况要复杂一些。使用的是另外一个 JUnit 的 TestCase: net.jsunit.DistributedTest JsUnit 提供了几个 Servlet,需要部署到远程的 Web Server 上,叫做 JsUnit Server。JsUnit Client(就是 DistributedTest 对象)将测试请求发送到远程 JsUnit Sever,远程的 JsUnit Sever 自动打开该机器上的浏览器,运行所有的测试用例,然后关闭浏览器,将返回结果送回给 JsUnit Client,JsUnit Client将返回结果输出到命令行并且保存到与 JUnit 格式完全相同的 xml 报表文件中。 通过以上的两种方式,JsUnit 可以测试任何操作系统+浏览器的组合,并且可以以命令行方式执行所有的测试用例。然后我们就可以更进一步将对于 JS 代码的自动测试集成到持续集成工具(CC、AntHill、etc.)之中了。 |
|
返回顶楼 | |
发表时间:2005-08-03
o,
那我是多虑乐。 我想我们使用它的区别在于,你在将它集成起来, 而我只是希望以最简单容易的方式来展开TDD, 所以我不会开JAVA来运行测试。 我原来以为,你在开发过程中,会同时开ANT做TDD过程中的运行测试效果,没有试过那样做。 主要是这样,我使用EDITPLUS(比如)编辑一个js test case文件开展TDD,一旦有一小步,就会运行这个test case,这样似乎用ANT有些麻烦。 |
|
返回顶楼 | |
发表时间:2005-08-03
swing 写道 我原来以为,你在开发过程中,会同时开ANT做TDD过程中的运行测试效果,没有试过那样做。
我是要把对 Java 代码的自动测试和对于 JS 代码的自动测试放在同一个 Ant 创建之中,这样就可以通过持续集成的方式来保证所有代码的质量了(我只写 Java 代码和 JS 代码)。不用 Ant,你是怎么用命令行方式执行自动测试的?我很感兴趣。 swing 写道 主要是这样,我使用EDITPLUS(比如)编辑一个js test case文件开展TDD,一旦有一小步,就会运行这个test case,这样似乎用ANT有些麻烦
呵呵,其实 Ant 应该也可以采用上面的方式配置为 EditPlus 的一个外部程序的,这样启动 Ant 就不会很麻烦了。 |
|
返回顶楼 | |
发表时间:2005-08-04
dlee 写道 swing 写道 我原来以为,你在开发过程中,会同时开ANT做TDD过程中的运行测试效果,没有试过那样做。
我是要把对 Java 代码的自动测试和对于 JS 代码的自动测试放在同一个 Ant 创建之中,这样就可以通过持续集成的方式来保证所有代码的质量了(我只写 Java 代码和 JS 代码)。不用 Ant,你是怎么用命令行方式执行自动测试的?我很感兴趣。 swing 写道 主要是这样,我使用EDITPLUS(比如)编辑一个js test case文件开展TDD,一旦有一小步,就会运行这个test case,这样似乎用ANT有些麻烦
呵呵,其实 Ant 应该也可以采用上面的方式配置为 EditPlus 的一个外部程序的,这样启动 Ant 就不会很麻烦了。 一开始我就是找JS的测试工具,所以最终用起来的时候,完全没有开java的东西的想法,仅此而已。 因为希望像java编辑器那样,总是集成JUNIT的,要跑测试非常方便,所以认为和EDITPLUS集成起来是最佳效果乐,原来还想做成将测试结果输出到editplus的控制台显示,后来最终失败或者懒,就算乐,就任凭它弹出个窗口看结果乐。 至于集成JS和JAVA的所有测试,我没有那样做过,因为JS和JAVA的代码关联是没有的, 所以我也没有想把它们按到一起,而是每次都是在需要的时候单独运行它们。 当然,对于持续集成做到的话是需要这样,只是我没有那样的需要罢乐(因为整个团队只有我写并运行这些test case)。 这样我会在项目中配置一个全局的类似TEST SUITE的HTML,可以直接运行它来查看测试结果,而不关心到底代码在哪里,谁是不是安装乐必要的ANT(这样仅仅是我根据环境来做的,你们可能ANT和JAVA编辑器一样必备,就不会考虑这个)。 而JAVA,仅就TDD产生的TEST CASE而言,在JAVA编辑器里面直接运行总的TEST SUITE,代价很小,很快就能执行完,所以也没有想拿ANT跑它。 也许是总的代码量不多的缘故,运行代价很高的(特别是费时的)代码,一般让它足够简单而不写测试。 所以,只是在需要的时候在相应编辑器环境里面运行它们就好乐,几秒钟完成是遵循的原则。 引用 不用 Ant,你是怎么用命令行方式执行自动测试的?我很感兴趣。
集成JS和JAVA的,我想还是ANT合适,我想这样做主要是为了出整个系统所有测试的报表吧。 单独的JSUNIT的运行,是修改乐下JSUNIT包里面的一个脚本运行文件来实现的,默认的JSUNIT的HTML执行界面需要一个JS TEST CASE的文件作为参数,需要手工选择,加脚本将当前EDITPLUS正在编辑的文件作为其HTML执行界面的JS TEST CASE文件而已。 ======================== 实际上,JS的UNIT TEST,最麻烦的还是HTML中由浏览器控制生成的对象,比如window、document等,这些东西的初始化以及运行中的一些情况蛮麻烦的,特别是牵涉一些响应事件时;目前我的策略是使用mock,而不是真实的对象,但是MOCK也有致命的弱点,就是有些动作不见得你能准确MOCK,需要一些测试来帮助; 不知你在这方面是怎么处理的。 |
|
返回顶楼 | |
发表时间:2005-08-05
swing 写道 集成JS和JAVA的,我想还是ANT合适,我想这样做主要是为了出整个系统所有测试的报表吧。
确实,这是使用 Ant 来运行 JsUnit 测试的主要好处之一。 一些更加深入的问题,我们以后在这个主题下继续讨论。 JsUnit 在 IE5.0 里面运行有问题,昨天查出其实只是因为一个小问题。IE5.0 有一个 bug,一个 Frame 中的代码修改另外一个 Frame 中 Form 的 Select 对象时不能直接使用 new Option() 的方法来赋值。IE5.5 以上已经没有这个 bug。对于 IE5.0 需要做一点特殊处理。 在 jsUnitTestManager.js 第 387 行,原来为: var newOption = new Option(serializedTestCaseString); this.testCaseResultsField[this.testCaseResultsField.length]=newOption; 修改为: var newOption = new Option(serializedTestCaseString); //IE5.0 has a bug to modify select object in another frame. if (navigator.userAgent.indexOf("MSIE 5.0")!=-1) { this.testCaseResultsField.length += 1; this.testCaseResultsField.options[this.testCaseResultsField.length-1].text = newOption.text; this.testCaseResultsField.options[this.testCaseResultsField.length-1].value = newOption.value; } else { this.testCaseResultsField[this.testCaseResultsField.length]=newOption; } 这样 JsUnit 就可以在 IE5.0 中正常运行了。虽然我很不喜欢 IE,但是使用 IE 来运行单元测试的速度确实比使用 FireFox 要快得多。 |
|
返回顶楼 | |
发表时间:2005-08-29
其实还可以用junit写js测试:D
方法是使用rhino import junit.framework.TestCase; import org.mozilla.javascript.*; public class JsTest extends TestCase { public void testUseJunit();{ Context cx = Context.enter();; try{ Scriptable scope = cx.initStandardObjects();; ScriptableObject.putProperty(scope,"assert",new TestCase();{});; cx.evaluateReader(scope, new java.io.FileReader("xmlc/Test1.js");, "<cmd>", 1, null);; }catch(Exception e);{ e.printStackTrace();; fail();; } finally { Context.exit();; } } |
|
返回顶楼 | |