使用TDD原则在JavaScript中开发UI

我在尝试提出在JavaScript中开发UI时正确遵循TDD原则的最佳方法遇到了很多麻烦。 最好的办法是什么呢?

将视觉与function分开是最好的吗? 你是否首先开发视觉元素,然后编写testing,然后编写function代码?

过去我使用Javascript做了一些TDD,而我所要做的就是区分unit testing和集成testing。 selenium将testing您的整个网站,从服务器的输出,其后发布,阿贾克斯调用,所有这一切。 但是对于unit testing来说,没有一个是重要的。

你想要的只是你要与之交互的UI,以及你的脚本。 你将使用的工具基本上是JsUnit ,它接受一个HTML文档,在页面上有一些Javascript函数,并在页面的上下文中执行它们。 所以你要做的是在你的函数页面中包含Stubbed HTML。 从那里,你可以testing你的脚本与模拟HTML,你的脚本和testing的隔离单元中的UI组件的交互。

这可能有点混乱,所以让我们看看我们是否可以做一些testing。 可以让一些TDD假设在一个组件被加载之后,根据LI的内容对元素列表进行着色。

tests.html

<html> <head> <script src="jsunit.js"></script> <script src="mootools.js"></script> <script src="yourcontrol.js"></script> </head> <body> <ul id="mockList"> <li>red</li> <li>green</li> </ul> </body> <script> function testListColor() { assertNotEqual( $$("#mockList li")[0].getStyle("background-color", "red") ); var colorInst = new ColorCtrl( "mockList" ); assertEqual( $$("#mockList li")[0].getStyle("background-color", "red") ); } </script> </html> 

显然TDD是一个多步骤的过程,所以对于我们的控制,我们需要多个例子。

yourcontrol.js(step1)

 function ColorCtrl( id ) { /* Fail! */ } 

yourcontrol.js(第二步)

 function ColorCtrl( id ) { $$("#mockList li").forEach(function(item, index) { item.setStyle("backgrond-color", item.getText()); }); /* Success! */ } 

你可能会在这里看到痛苦点,你必须保持你的模拟HTML在页面上,与服务器控件的结构同步。 但它确实为您带来了一个用JavaScript进行TDD的很好的系统。

我从来没有成功TDDed UI代码。 我们到的最接近的确是尽可能地将UI代码从应用程序逻辑中分离出来。 这是模型 – 视图 – 控制器模式有用的原因之一 – 模型和控制器可以TDDed没有太多的麻烦,没有太复杂。

根据我的经验,这个视图总是留给我们的用户验收testing(我们编写的Web应用程序和我们的UAT使用Java的HttpUnit)。 然而,在这个层面上,这是一个真正的集成testing,没有我们对TDD所期望的隔离testing属性。 由于这个设置,我们必须首先编写我们的控制器/模型testing/代码,然后是UI和相应的UAT。 然而,在最近我写的Swing GUI代码中,我一直在用GUI编写GUI代码,以便在添加到控制器/模型/ API之前探索我的前端devise。 YMMV在这里虽然。

所以要重申一下,我可以给出的唯一build议就是您已经怀疑的 – 尽可能将您的UI代码从逻辑中分离出来,然后对它们进行TDD。

另请参阅: 用于TDD的JavaScriptunit testing工具

我发现MVP架构非常适合编写可testing的用户界面。 演示者模型类可以简单地进行100%的unit testing。 用户界面testing(使用Selenium等),您只需要担心View (应该是一个愚蠢的,仅用于将事件触发到Presenter的层)

请注意,在我正在谈论完全在UI上下文中使用MVP,而不必交叉到服务器端。 您的用户界面可以拥有自己的Presenter和Model,完全在客户端。 Presenter驱动UI交互/validation等逻辑,而Model则保存状态信息,并为后端(可以有独立的模型)提供一个入口。

您还应该看看Presenter First TDD技术。

这是我切换到Google Web Toolkit的主要原因…我使用Java进行开发和testing,并有合理的期望,编译后的JavaScript将在各种浏览器上正常运行。 由于TDD主要是一个unit testingfunction,所以在编译和部署之前,大部分项目都可以开发和testing。

集成和functiontesting套件在将代码部署到testing服务器后,validation结果代码是否按预期运行。

我正要开始在我正在开发的一个新项目上开发Javascript TDD。 我目前的计划是用qunit来做unit testing。 开发testing可以通过在浏览器中刷新testing页面来运行。

为了持续集成(并确保testing在所有浏览器中运行),我将使用Selenium在每个浏览器中自动加载testing工具并读取结果。 这些testing将在每次签入到源控制时运行。

我也将使用JSCoverage来获得testing的代码覆盖分析。 Selenium也会自动执行此操作。

我目前正在设置这个中间。 一旦我完成设置,我会更新这个答案。


testing工具:

  • qunit
  • JSCoverage
  • selenium

我所做的是捅Dom,看看我是否得到了我所期望的。 这样做的一个好的副作用就是在快速testing时,你也可以快速地创build你的应用程序。

我刚刚发布了一个开源工具包,它将极大地帮助JavaScript tdd。 它是许多开源工具的组成部分,它为您提供了一个开箱即用的requirejs骨干应用程序。

它提供了单个命令来运行:dev web服务器,jasmine单一浏览器testing运行器,jasmine js-test-driver多浏览器testing运行器以及JavaScript和CSS的连接/缩小。 它还输出一个用于生产debugging的应用程序的非最小版本,预编译您的手柄模板,并支持国际化。

不需要安装。 它只是工作。

http://github.com/davidjnelson/agilejs