花费数小时后,也许>天> ,为您的Web应用程序提供了令人敬畏的新功能的完成,您终于准备好看到它的行动。您将新代码添加到您的JavaScript基础,构建发布候选者,并启动您的浏览器,希望惊讶。然后……嗯……新功能可能运行良好,但是您的应用程序中的其他一些关键部分 - 在开发新版本时您没有 touch
的部分 - 变得非常糟糕。现在,您面临着在几天工作中进行回溯的挑战,以弄清楚如何打破现有代码。快乐的日子绝对不在这里。>>这种情况比我想承认的要多。而且,如果您已经编码了一段时间,那么您也可能已经看到了它。但是,请考虑一下使这种情况如此痛苦的原因。这并不是因为我们的新代码破坏了现有代码;这是不可避免的。真正的痛苦是,花了很长时间才能注意到破裂。由于我们知道我们的应用程序正在起作用,因此有如此多的发展,因此该错误可能隐藏了大量代码。而且,尽管它似乎有点像在草丛中寻找针头,但我们别无选择。 在本文中,我们将真正从JavaScript开发中消除这种情况。不再需要在数小时,数天或几周的代码中进行挖掘。我们将采用的原则是一个简单的原则:在我们创建它后立即找到任何错误
。这是正确的;我们将建立一个开发环境和流程,当我们编写引入错误的代码时立即告诉我们。此外,一旦最初的开发完成,我们将付出的额外努力就不会浪费。在集成环境中,捕获我们开发错误的相同测试代码将完全重复使用。我们可以轻松地将测试纳入我们的源代码管理系统中,在错误进入我们的代码库之前阻止错误。 在以下四个部分中,我们将首先研究JavaScript测试环境所需的工具。然后,我们将考虑一个琐碎的应用程序,该应用程序足够简单,可以理解,但具有实际生产Web应用程序中可能存在的所有功能。最后两个部分展示了我们如何使用环境在开发过程中测试示例应用程序,并且在整合过程中初始开发完成后。
>我们已经确定我们的测试工具必须支持Web浏览器和Node.js环境,我们可以缩小选择的范围,以选择核心测试框架。存在许多JavaScript测试框架,但大多数人倾向于浏览器测试。通常可以让他们与node.js一起工作,但通常需要不高的黑客攻击或调整。摩卡咖啡是一个不遭受此问题的框架,其合理地描述为:
Mocha最初是为Node.js开发的,它也很容易支持Web浏览器。通过使用Mocha作为我们的测试框架,我们可以编写支持开发和集成而无需修改的测试。
sustert>,>期望, and 应该。代码。在封面下,它们都是等效的。将测试从一种断言样式转换为另一种主张风格很容易。断言风格的主要区别在于它们的可读性。主张样式的选择主要取决于您(或您的团队)认为最可读性的样式,哪种风格会产生最可理解的测试。要查看差异,请考虑为以下代码开发琐碎的测试:>
>传统的断言测试可以写为:<span>var sum = 2 + 2;</span>
该测试可以完成工作,但是除非您已经习惯了老式的单元测试,否则阅读和解释可能有些挑战。替代断言风格的使用期望:
assert<span>.equal(sum, 4, "sum should equal 4");</span>
大多数开发人员发现,与断言风格的测试相比,预期的断言更容易阅读和理解。第三个替代方案应该使考试断言更像是自然语言:
<span>expect(sum).to.equal(4);</span>
> Chai库支持所有三种主张样式。在本文中,我们应该坚持。
sum<span>.should.equal(4);</span>
>
>大多数Web应用程序,包括我们将在本文中考虑的琐碎示例,依赖第三方库和服务。在许多情况下,测试我们的代码需要观察甚至控制这些库和服务。 Sinon.js库提供了许多用于测试这些交互的工具。这样的工具分为三个一般类:>我们测试工作台的最终工具是用于单元测试的开发环境。在我们的示例中,我们将使用Test’EM。 Test’em是一个方便的脚本集合,用于设置并运行连续的测试环境。如果我们选择,我们可以自己编写脚本并手动管理环境;但是,Toby Ho(Test’em的创建者)整理了一个很棒的软件包,可以节省我们的麻烦。
要查看我们的测试环境,请考虑一个简单的应用程序。尽管该应用程序包含了实际应用所需的所有功能,但该应用程序包含了其裸露的必需品。 (该应用程序的完整源代码可在GitHub上找到。)
>>用户可以看到他们的毒品列表,他们可以单击一个复选框以切换任何todo的状态。
todos数据库>我们在其中放了一些测试数据后,表可能会看起来。
<span>var sum = 2 + 2;</span>
id
title我们的Web应用程序需要访问此数据库,因此我们将提供标准的REST接口。 API遵循Ruby惯例,但是任何服务器技术都可以轻松实现。特别是:
get api/todos/nnn返回todo的json表示,ID等于nnn。
>
在开发过程中进行测试<span>var sum = 2 + 2;</span>
>安装工具
>我们需要的其他所有内容都可以作为节点软件包可用。 Node软件包管理器可以处理其安装以及任何依赖项。
assert<span>.equal(sum, 4, "sum should equal 4");</span>
此示例的源代码包括一个完整的项目结构,其中包含以下15个文件:
<span>expect(sum).to.equal(4);</span>
>最后,我们准备好编码了。在命令外壳中,导航到我们项目的根文件夹并执行命令testem。 Test’em脚本将运行,清除终端窗口,并在右上方给我们一个URL。将该URL复制并粘贴到我们选择的浏览器中,我们已经离开了。
>>
<span>var sum = 2 + 2;</span>
>本着真正的测试驱动开发的精神,我们将首先在测试/app-todos-test.js文件中编写第一个测试用例。像任何好的Web应用程序一样,我们希望最大程度地减少全球名称空间污染。为此,我们将依靠一个全局变量doApp来包含我们的所有代码。我们的第一个测试案例将确保存在全局名称空间变量。
><span>var sum = 2 + 2;</span>
>
在测试块中,我们通过测试的内容记录了每个测试用例。这就是IT()函数的目的。读取任何测试案例的方法是将描述()和()字符串组合到单个语句中。因此,我们的第一个测试案例是
应用程序为名称space测试代码本身在IT()块内部。我们的测试案例是创建一个全局变量
assert<span>.equal(sum, 4, "sum should equal 4");</span>
终端窗口也会自动更新。
要进行测试,我们必须创建全局名称空间变量。我们转移到srcapp-todos.js文件并添加必要的代码。
>我们保存文件后,请再次验证“ EM再次弹出”。我们立即为测试案例获得更新的结果。
<span>expect(sum).to.equal(4);</span>
>退后一会儿,考虑发生了什么!每当我们更改测试代码或应用程序时,Test`EM都会立即重新运行我们的整个测试套件。我们要做的就是将Test'Em的浏览器或终端窗口保持在屏幕的角落,并且在开发
>随着我们的开发环境现已完全建立,我们可以开始开发应用程序。由于我们的应用程序显示了招待员列表,因此最好为这些毒品创建一个模型。该模型将需要跟踪Todo的标题及其状态。让我们添加一个单元测试,该测试可以验证我们可以使用合理默认值创建一个todo。
><span>var sum = 2 + 2;</span>
这些测试值得注意的几个方面。
>使用第三方功能的存根
assert<span>.equal(sum, 4, "sum should equal 4");</span>
>在每个测试之前,我们还包括一些其他代码,并且在每个测试后都添加了一部分代码以执行。该额外的代码管理Sinon存根,该函数有效地将代码中的另一个函数取消。在我们的情况下,存根将this.todo的save()方法无效。有了存根,对该方法的呼叫实际上不会访问后库库。相反,Sinon拦截了这些电话,并立即返回。这种行为很重要。如果我们试图在单元测试环境中执行实际的骨干保存()方法,则该调用将失败,因为不会有数据库或服务器API。
>存根后,我们的测试用例可以使用它来验证模型的行为。在第一个测试案例中,我们立即将TODO的标题设置为新值。由于这更改了标题属性,因此我们希望我们的模型更新其备份商店。为了检查我们是否只验证了该存根是被调用的。为了使我们的模型通过这些测试,我们可以寻找变更事件并做出适当的响应。
<span>var sum = 2 + 2;</span>
>
assert<span>.equal(sum, 4, "sum should equal 4");</span>
接下来,我们可以开发该列表项目视图的详细内容。例如,我们希望完整的列表项目看起来像以下内容。
<span>expect(sum).to.equal(4);</span>
对于我们的测试案例,我们可以利用jQuery从视图的主要元素中提取单个元素。
sum<span>.should.equal(4);</span>
请注意,在上一个测试案例中,我们将模型的save()方法固定了。由于我们正在从其默认值中更改属性,因此我们的模型将尽职尽责地将其持续到其备用商店。但是,在单元测试环境中,我们将没有数据库或服务器API。该存根取代了缺失的组件,并允许测试无错误进行。为了通过这些测试通过,我们必须在我们的视图中添加一些其他代码。
CREATE TABLE `todos` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key for the table.', `title` varchar(256) NOT NULL DEFAULT '' COMMENT 'The text for the todo item.', `complete` bit(1) NOT NULL DEFAULT b'0' COMMENT 'Boolean indicating whether or not the item is complete.', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='To Do items.'
测试模型/视图交互
<span><span><!DOCTYPE html></span> </span><span><span><span><html</span> lang<span>="en"</span>></span> </span> <span><span><span><head</span>></span> </span> <span><span><span><meta</span> charset<span>="utf-8"</span>></span> </span> <span><span><span><title</span>></span><span><span></title</span>></span> </span> <span><span><span></head</span>></span> </span> <span><span><span><body</span>></span> </span> <span><span><span><h1</span>></span>List of Todos<span><span></h1</span>></span> </span> <span><span><span><script</span> src<span>="lib/jquery-1.9.0.min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="lib/underscore-min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="lib/backbone-min.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span> src<span>="src/app-todos.js"</span>></span><span><span></script</span>></span> </span> <span><span><span><script</span>></span><span> </span></span><span><span> <span>$(function () { </span></span></span><span><span> <span>var todos = new todoApp<span>.Todos</span>(); </span></span></span><span><span> todos<span>.fetch(); </span></span></span><span><span> <span>var list = new todoApp<span>.TodosList</span>({collection: todos}); </span></span></span><span><span> <span>$("body").append(list.el); </span></span></span><span><span> <span>}) </span></span></span><span><span> </span><span><span></script</span>></span> </span> <span><span><span></body</span>></span> </span><span><span><span></html</span>></span></span>
。这是单元测试代码。
请注意,我们再次将todo's save()方法固定。否则,当我们通过模拟单击更改todo状态时,骨干将尝试更新不存在的备份商店。bash-3.2$ node --version v0.8.18 bash-3.2$ npm --version 1.2.2 bash-3.2$
对于测试用例本身,我们首先创建具有固定件ID的
<span>var sum = 2 + 2;</span>
在视图中,我们想在元素上查看单击事件,并为模型调用此方法。
assert<span>.equal(sum, 4, "sum should equal 4");</span>
但是,我们可以验证我们对集合观点的实施是否合适。我们希望该视图呈现为无序列表(
<span>expect(sum).to.equal(4);</span>
视图实现也很简单。它跟踪集合中的任何添加并更新视图。对于初始渲染(),它一次只会一次添加一个集合中的所有模型。
>sum<span>.should.equal(4);</span>
奖励测试:验证API
CREATE TABLE `todos` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary key for the table.', `title` varchar(256) NOT NULL DEFAULT '' COMMENT 'The text for the todo item.', `complete` bit(1) NOT NULL DEFAULT b'0' COMMENT 'Boolean indicating whether or not the item is complete.', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='To Do items.'
>秘密知道骨干依赖于jQuery的$ .ajax()函数来实现REST API。我们可以通过固定该功能来拦截API相互作用。当我们启动功能时,我们将要替代自己的响应。 存根的屈服方法为我们提供了这个机会。它告诉辛农(Sinon)在称呼该存根时应采取什么其他动作。这是一个完整的测试案例,可以验证我们的收集使用REST API正确初始初始初始初始初始初始初始初始初始初始初始。
<span>var sum = 2 + 2;</span>
在集成期间进行测试
我们的代码需要这些修改,因为Node.js处理全局变量的处理方式与Web浏览器不同。在Web浏览器中,默认情况下,JavaScript变量在范围内是全局。另一方面,node.js默认情况下将变量限制在其本地模块中。在那个环境中,我们的代码将无法找到所需的第三方库(jQuery,下划线和骨干。 。
>我们还需要调整测试代码。测试脚本需要访问自己的库(jQuery,Chai,Sinon.js和Sinon-Chai)。此外,我们需要添加一些额外的内容来模拟Web浏览器的文档对象模型(DOM)。回想一下,我们的点击处理测试要求我们将“固定装置”
<span>var sum = 2 + 2;</span>
>包装这些语句测试的条件,以查看我们是否在Node.js环境中运行,而不是Web浏览器。在浏览器中,不需要额外的语句,因此我们可以安全地跳过它们。
>通过这些更改,我们可以从命令行执行完整的测试套件。只需导航到项目的根文件夹并执行命令摩卡咖啡即可。结果看起来很熟悉。>
结论
这是文章中使用的主要单元测试资源。
>命令行JavaScript执行环境:node.js
backbone.js与其他JavaScript框架一样,支持单元测试以确保应用程序的质量。但是,由于其灵活性和简单性,Backbone.js脱颖而出。它并不决定您的应用程序应如何构建,从而使开发人员可以自由设计自己的应用程序,因为他们认为合适。这种灵活性扩展到单元测试,使开发人员可以选择其首选的测试工具和方法。此外,与其他框架相比,Backbone.js具有较小的占地面积,使其用于单元测试更快,更有效。
>>我如何在backbone.js?
我可以在Backbone.js.js吗?自动化单元测试在backbone.js中。自动化涉及建立连续集成(CI)系统,该系统每当对代码进行更改时会自动运行测试。这样可以确保更改引入的任何错误都会立即捕获。有几种CI工具,例如Jenkins,Travis CI和CircleCi,它们支持JavaScript,可用于在Backbone.js中自动化单元测试。
> 我可以在单元测试backbone.js吗? >是的,您可以在单元测试骨干链中使用模拟和存根。模拟和存根是模拟真实对象行为的假对象。它们用于隔离系统的其余部分。这使得测试更加可靠,更容易编写。有几个可用的库,例如sinon.js,它们提供了创建和管理模拟和存根的功能。>我如何在backbone.js中调试失败的单位测试?报告确定失败的原因。大多数测试框架都提供详细的错误消息,可以帮助您查明问题。您还可以使用chrome devtools或node.js debugger等调试工具逐步浏览您的代码并检查变量和函数调用。
>如何改善backbone.js中的单元测试的性能? Backbone.js中单元测试的性能涉及优化您的测试和测试环境。这包括编写有效的测试,这些测试快速执行,并行运行测试以及使用快速的测试框架。您还可以使用分析工具在测试过程中识别慢速测试和瓶颈。
>
以上是单元测试骨干。JS应用程序的详细内容。更多信息请关注PHP中文网其他相关文章!