使用TDD原理在JavaScript中开发UI
在用JavaScript开发UI时,想出最好的方法来正确遵循TDD原则时遇到了很多麻烦。最好的方法是什么?
最好将视觉与功能区分开吗?我们是否先开发视觉元素,然后编写测试,然后编写功能代码?
解决方案
这是我改用Google Web Toolkit的主要原因。我用Java开发和测试,并且有合理的期望,认为编译后的JavaScript将在各种浏览器上正常运行。由于TDD主要是单元测试功能,因此大多数项目都可以在编译和部署之前进行开发和测试。
集成和功能测试套件可验证生成的代码在部署到测试服务器后是否按预期运行。
我从未成功开发过TDD用户界面代码。实际上,我们最接近的是尽可能将UI代码与应用程序逻辑分开。这就是为什么模型视图控制器模式有用的原因之一,该模型和控制器可以在没有太大麻烦且不会变得太复杂的情况下进行TDD。
以我的经验,该视图始终留给我们的用户接受度测试(我们编写了Web应用程序,而UAT使用Java的HttpUnit)。但是,在这个级别上,它实际上是一个集成测试,没有我们需要TDD进行的隔离测试属性。由于此设置,我们必须先编写控制器/模型测试/代码,然后编写UI和相应的UAT。但是,在我最近编写的Swing GUI代码中,在添加到controller / model / API之前,我一直先使用存根编写GUI代码来探索前端设计。 YMMV在这里。
因此,重申一下,我唯一能给出的建议就是我们似乎已经怀疑要尽可能将UI代码与逻辑分离并对其进行TDD。
我即将开始在我正在从事的新项目中执行Javascript TDD。我当前的计划是使用qunit进行单元测试。在开发测试时,只需在浏览器中刷新测试页面即可运行测试。
为了进行持续集成(并确保测试在所有浏览器中运行),我将使用Selenium在每个浏览器中自动加载测试工具,并读取结果。这些测试将在每次签到源代码控制时运行。
我还将使用JSCoverage获得测试的代码覆盖率分析。 Selenium也将自动执行此操作。
我目前正在进行此设置。一旦设置完成,我将使用更准确的详细信息更新此答案。
测试工具:
- 单位
- JSCoverage
- 硒
我过去用Javascript做过TDD,而我要做的就是区分单元测试和集成测试。 Selenium将使用服务器的输出,其回发,ajax调用以及所有这些测试整个站点。但是对于单元测试,这都不重要。
我们想要的只是我们将要与之交互的UI,以及脚本。用于此目的的工具基本上是JsUnit,它获取HTML文档,并在页面上具有一些Javascript函数,并在页面上下文中执行它们。因此,我们要做的就是在页面上添加带有功能的Stubked HTML。从那里,我们可以在模拟HTML的隔离单元,脚本和测试中测试脚本与UI组件的交互。
这可能有点令人困惑,所以让我们看看是否可以做一些测试。让某些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(第1步)
function ColorCtrl( id ) { /* Fail! */ }
yourcontrol.js(第2步)
function ColorCtrl( id ) { $$("#mockList li").forEach(function(item, index) { item.setStyle("backgrond-color", item.getText()); }); /* Success! */ }
我们可能在这里看到了痛点,我们必须在页面上的模拟HTML与服务器控件的结构保持同步。但这确实为我们提供了一个使用JavaScript进行TDD'ing的不错的系统。
另请参阅:用于TDD的JavaScript单元测试工具
我发现MVP体系结构非常适合编写可测试的UI。Presenter和Model类可以简单地进行100%单元测试。我们只需要担心用于UI测试(使用Selenium等)的View(应该是愚蠢的薄层,仅将事件触发到Presenter)。
请注意,在本文中,我所说的是完全在UI上下文中使用MVP,而不必跨入服务器端。UI可以有自己的Presenter和Model,它们完全位于客户端。 Presenter驱动UI交互/验证等逻辑,而Model保留状态信息并提供到后端的门户(我们可以在其中拥有单独的Model)。
我们还应该看看Presenter First TDD技术。