使用TDD原则在JavaScript中开发UI

时间:2008-09-18 19:33:10

标签: javascript user-interface tdd

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

最好是将视觉与功能区分开来吗?您是先开发可视元素,然后编写测试然后编写功能代码吗?

7 个答案:

答案 0 :(得分:22)

我以前用Javascript完成了一些TDD,而我要做的就是区分单元测试和集成测试。 Selenium将测试你的整个站点,包括服务器的输出,它的post backs,ajax调用,所有这些。但对于单元测试,这些都不重要。

您想要的只是您要与之交互的UI以及您的脚本。您将使用的工具基本上是JsUnit,它采用HTML文档,页面上有一些Javascript函数,并在页面上下文中执行它们。所以你要做的就是在你的功能页面上包含Stubbed out 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的系统。

答案 1 :(得分:4)

我从未成功使用TDDed UI代码。我们最接近的确是尽可能地将UI代码与应用程序逻辑分开。这就是为什么模型 - 视图 - 控制器模式很有用的一个原因 - 模型和控制器可以TDDed而不会有太多麻烦而且不会太复杂。

根据我的经验,视图始终留给我们的用户验收测试(我们编写了Web应用程序,我们的UAT使用了Java的HttpUnit)。但是,在这个级别上它实际上是一个集成测试,没有我们想要的TDD隔离测试属性。由于这种设置,我们必须首先编写控制器/模型测试/代码,然后编写UI和相应的UAT。但是,在我最近写过的Swing GUI代码中,在添加到控制器/模型/ API之前,我一直在编写带有存根的GUI代码来探索我的前端设计。 YMMV虽然在这里。

所以重申一下,我能给出的唯一建议是你似乎已经怀疑 - 尽可能将你的UI代码与你的逻辑分开并将它们TDD。

答案 2 :(得分:2)

答案 3 :(得分:1)

我发现MVP架构非常适合编写可测试的UI。您的演示者模型类可以简单地进行100%单元测试。你只需要担心视图(它应该只是一个愚蠢的薄层,只能向Presenter发送事件)进行UI测试(使用Selenium等)。

请注意,我在谈论完全在UI上下文中使用MVP,而不必跨越到服务器端。您的UI可以拥有自己的Presenter和Model,它完全位于客户端。 Presenter在模型保存状态信息的同时驱动UI交互/验证等逻辑,并为后端提供门户(您可以在其中拥有单独的模型)。

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

答案 4 :(得分:0)

这是我切换到Google Web Toolkit的主要原因......我使用Java开发和测试,并且合理地期望已编译的JavaScript可以在各种浏览器上正常运行。由于TDD主要是一个单元测试功能,因此大部分项目都可以在编译和部署之前进行开发和测试。

集成和功能测试套件验证生成的代码在部署到测试服务器后是否按预期运行。

答案 5 :(得分:0)

我正准备开始在我正在开发的新项目上使用Javascript TDD。我目前的计划是使用qunit进行单元测试。在开发测试时,只需在浏览器中刷新测试页即可运行。

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

我还将使用JSCoverage来获取测试的代码覆盖率分析。这也将通过Selenium实现自动化。

我目前正在设置它。一旦我完成设置,我会用更详细的细节更新这个答案。


测试工具:

答案 6 :(得分:0)

我所做的就是戳Dom,看看我是否得到了我的期望。这样做的一个很好的副作用是,在快速进行测试时,您也可以快速完成应用程序。

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

它提供了单个命令来运行:dev web server,jasmine单浏览器测试运行器,jasmine js-test-driver多浏览器测试运行器,以及JavaScript和CSS的连接/缩小。它还会输出一个未经编辑的应用程序版本,用于生产调试,预编译车把模板,并支持国际化。

无需设置。它只是有效。

http://github.com/davidjnelson/agilejs