《编写可测试的JavaScript代码》——第1章 可测试的JavaScript 1.1 现有技术

简介: 无论如何,TDD不是一件坏事;事实上,它可以是一件非常好的事情。TDD是一个伟大的开始,不管是整个应用程序还是一个单一模块—所有人都喜欢编写新代码,如果编写新代码之前的“成本”仅仅是先编写测试的话,那就随它去吧。因为开始时没有代码,所以编写测试的“成本”是最小的。

本节书摘来自异步社区《编写可测试的JavaScript代码》一书中的第1章,第1.1节,作者:【美】Mark Ethan Trostler著,更多章节内容可以访问云栖社区“异步社区”公众号查看

第1章 可测试的JavaScript

每个人的想法都是独一无二的,但代码不是。几乎每个行业都完成了机器革命,然而奇怪的是,计算机科学行业并没有。程序员基本上是在做已经做了40年的同样的事情。手工编写代码,接着这些代码被编译或解释,然后执行。看看输出结果,再确定是否需要再改代码。计算机科学的黎明到来之前,这种开发周期就一直这样保持不变。我们的机器在几何级变快,内存和二级存储大小是无限制的,且这样发展下去软件越来越复杂。但我们仍然一个字母一个键地手工编写着代码。我们依然滥用着“print”语句输出运行时发生的内容。我们的开发工具确实越来越强大,但每个热门的新语言出现时,又会出现新的工具。归根结底,在一个令人难以置信的自动化世界(并且大部分的自动化都是软件编程的成果),软件编程却依然是一个几乎完全手工的过程。一次敲一个字符的软件编程做法仍停滞不前。

虽然我们编写的大部分代码之前都已经编写过,可能是目前正在使用的语言,或者之前用过的语言,但每个应用程序都是独一无二的,即使我们和竞争对手都在做同样的事情。不管是否独特,成功的应用程序是必须能够使用的。它不需要漂亮,也不需要绝对得快,或者也不需要最丰富的功能,但它必须得能用才行。

应用程序的核心,只是拥有输入输出的消息传递系统。而在此之上构建的复杂性越来越大。由于JavaScript的出现,我们不仅要吸取其他语言的经验教训,还要从JavaScript自身吸取教训以便编写可测试的代码。在客户端和服务器端,JavaScript的应用程序都越来越大,我们必须非常谨慎地应用前辈们提供的最佳实践和经验教训,加以调整以很好地适应JavaScript代码。

图1-1显示了过去三十年每个晶体管周期的微处理器成本[1]。这幅怪诞的图表示了每个CPU的周期成本,此图遵循摩尔定律,有不可避免的下降趋势。硬件刷新率确实远远超出任何软件层面。

screenshot

通过编程机已经将对象变得更快更小以获得巨大的利益。为了达到不可思议的全球规模,大批的机器通过实施标准化组装于工厂中。然而软件工程师却仍然要在他们的个人电脑面前坐着,在键盘上不停地敲打着每个字符。

1.1 现有技术

编写软件虽然是一个手动过程,但已经有很多人尝试编纂和规范开发人员应该如何做事,以便为构建“良好”代码创建一个可重复的过程。当然这些过程,希望引导固执的开发人员编写“整洁”和“零Bug”的代码。然而在大多数情况下,本书下面几节中采用的过程或方法,其结果直接取决于开发人员在系统里引入的意愿。本书内容不关注技术的选择或使用,而是关注编程实战中应该考虑做什么。让我们通过如下一些内容思考一下。

1.1.1 敏捷开发
敏捷开发是大量实践中一个比较大的方法。敏捷方法主要是应对软件应用程序开发的“瀑布”模型,瀑布模型开发使用离散性的序列化过程。例如,瀑布模型首先是需求规范编写,接着程序员编码、测试人员测试、应用程序部署,然后回头重新更新新的需求。该过程的每一步都是连续且独立的。因此,编写需求规范时,程序员和测试人员都要等待,程序员编码时,测试人员再等待,而测试人员在测试的时候,所有人都在等待,等等。

敏捷开发尝试以更加灵活的方式让每个阶段都并行发生。软件能用是首要任务,与其花大量的时间等着上一步的完善交接,不如每个团队进行短周期的迭代,以便时刻都有事做。大量的工作被分解成可以预估的小块。敏捷开发尝试打破开发周期内每个小组的壁垒,这样他们可以一起工作,从而减少相互之间交接的时间。与客户沟通有助于确定最终的交付成果。

注意,使用敏捷开发方法,并不一定意味着应用程序完成得更快且质量更高。敏捷开发的最大优势是它处理需求变更的方式。在瀑布模型中,任何改变都需要贯穿整个过程。敏捷开发的短周期允许变更,以便将这些变更整合到最终的产品中。如果你听说过fail fast、release often、backlog、standup或者和continuous相关的词语,你可能已经在使用敏捷开发了。某种程度上,大多数现代开发都使用敏捷开发。图1-2显示了敏捷开发过程的典范图。

screenshot

图1-2中有很多内容,但基本思想是:快速迭代和持续交互可以加快高质量软件的交付。

敏捷开发本身没有提到如何编写软件,相反,它建议了一些适合敏捷哲学的方法。例如,“用户故事(user story)”是由“用户(user)”描述一个应用程序该有的特性的句子。这些故事是用户想在应用程序中体现的产品特性。使用你的应用程序或API的用户,可以是普通的用户,也可以是能够帮你定义最终产品的另外一组开发人员。结对编程是一种经常与敏捷开发一起使用的开发方法。结对编程最纯粹的形式就是两个程序员坐在同一张桌子旁,看同一个屏幕、键盘以及鼠标,一起进行编写软件。其中一个开发人员敲代码,而另一个开发人员则积极调试和思考代码。两个大脑通常比一个更聪明,与两个人单独进行编码相比,结对编程能够更快地发现并解决问题。

1.1.2 测试驱动开发
测试驱动开发(TDD)是敏捷软件开发的推荐做法。TDD希望在编写代码之前先编写测试。这些测试提供了必须遵循预期功能的代码。编写测试失败后(刚开始还没编写代码肯定会失败),接着开始编写代码,以便确保测试能够通过。保持测试领先于开发,永远不会有未被测试的代码,至少这是TDD的理论。在现实中,往往开始时,开发人员会沿着这条路走,并开始编写测试,但很快功能代码就会超过测试代码。呵呵,至少你得到了一些测试!

在新建项目或模块时,使用TDD的效果显然是最好的。如果只是需要单元测试,那它也是最成功的。在编写代码之前,编写完整的集成测试是令人望而生畏的!TDD也为重写现有遗留代码提供了一个很好的理由或借口。如果开发人员在为“已存在的代码编写一大堆测试”和“在编写自己新代码的同时进行测试”中做选择,大多数开发人员可能会选择后者。当然,开发人员不一定只有一个选择,如果对现有已存在代码编写测试是下一步的话,那就不要指望他们能有开心的笑容以及很高的效率。

无论如何,TDD不是一件坏事;事实上,它可以是一件非常好的事情。TDD是一个伟大的开始,不管是整个应用程序还是一个单一模块—所有人都喜欢编写新代码,如果编写新代码之前的“成本”仅仅是先编写测试的话,那就随它去吧。因为开始时没有代码,所以编写测试的“成本”是最小的。

在2005年针对加拿大的大学生开展的一项有趣的研究发现,TDD使程序员更有效率,因为他们写了更多的测试。虽然这很有争议,但更有趣的是,研究人员也观察到,随着编写测试数量的增加,软件质量很少呈线性提高,这与采用的开发战略无关。最好是要知道,测试的数量和更高的代码质量是成正比的。从中能得出的结论是,任何能让开发人员在编码前、编码中、编码后进行编写测试的方法都是非常好的方法。

1.1.3 行为驱动开发
行为驱动开发(BDD)是在TDD的基础上发展而来的,它为开发人员和非开发人员提供了一种通用语言,用于描述正确的应用程序行为和模块行为,该通用语言是日常语言。例如,提供用于定义被测试模块的行为的描述,比如“如果购物车是空的就不能进行结账”,而不是写一个名为testEmptyCart的测试。使用通用语言定义的测试或预期,可以让任何人都能更容易地了解被测试的内容,并且有助于定义测试和期望应该是什么样的[2]。

相对于代码,BDD是利用敏捷用户故事来定义测试。用户故事可以直接转化为测试。用户故事通常必须遵循特定的模板形式:作为一个[人/角色],我需要[某些功能或权利],以便能[得到相应利益或达到相应的结果]。

正确填写每个空白项,如作为一位Yahoo!Mail用户,我想将照片附加到电子邮件中,以便我的收件人都可以看到它。这个用户故事可以转化为Yahoo!Mail产品的一组功能需求和测试。

BDD对于获得非项目团队成员(技术人员或非技术人员)的正式反馈很有用,从而帮助你理解系统应该如何操作。用户故事通常可以直接转化成测试—或者任何可以促进集中测试(更多测试)的内容,这是一件非常好的事情!

1.1.4 哪种方式最好
本书既不提倡也不解释任何一种开发方法,从这一点上讲,我认为它是成功的。瀑布(Waterfall)、螺旋(Spiral)、敏捷(Agile)以及其他方法都很好用,但都没有产生可测试的代码,更不用说可测试的JavaScript了。同样,TDD、BDD以及其他形式的开发方式也不一定确保有可测试的JavaScript。怎样才可以确保生成可测试的JavaScript?确保编写出整洁、松耦合并有足够注释,且确保别人能够接手维护的代码,才能够编写可测试的JavaScript。编写、阅读和维护可测试的JavaScript并不一定需要测试驱动、行为驱动或任何其他“驱动”型的开发方式。然而,遵循任何强调与编码一起测试的实践是一件有益的事情。要谨记的最重要的事情是我们编写的代码并不是凭空存在的。前面编写的任何专业代码,都将被我们自己或者别人查阅、编译、调试,并最终使用。最后,我们编写出代码,让别人来维护、研究和使用。

相关文章
|
12天前
|
JavaScript 前端开发 Serverless
Vue.js的介绍、原理、用法、经典案例代码以及注意事项
Vue.js的介绍、原理、用法、经典案例代码以及注意事项
28 2
|
5天前
|
JSON 前端开发 JavaScript
在JavaScript中,异步编程是一种处理非阻塞操作(如网络请求、文件读写等)的重要技术
【6月更文挑战第12天】JavaScript中的异步编程通过Promise和async/await处理非阻塞操作。Promise管理异步操作的三种状态,防止回调地狱,支持链式调用和并行处理。async/await是ES8引入的语法糖,使异步代码更像同步代码,提高可读性。两者结合使用能更高效地处理复杂异步场景。
16 3
|
5天前
|
JavaScript 前端开发 UED
深入理解JavaScript中的节流与防抖技术
理解并合理运用节流与防抖技术,可以帮助我们优化事件处理函数的执行频率,从而提升应用的性能和用户体验。这两种技术通过减少不必要的计算和DOM操作,使得Web应用程序能够更加流畅地运行。 通过掌握防抖和节流的实现原理及应用场景,开发者可以更加灵活地编写高效且性能优化的代码,对于面对高频事件处理时尤其重要。在开发中合理选择使用防抖或节流,将直接影响到应用的响应性和效率。
8 1
|
1天前
|
JavaScript 前端开发 开发者
如何跟踪最新的JavaScript游戏开发技术趋势
【6月更文挑战第16天】跟踪JavaScript游戏开发趋势:关注技术网站和博客,如Medium和GameDev.net;参加JSConf和GDC;订阅期刊;关注Phaser、Three.js等开源项目;利用Twitter和Stack Overflow交流;学习新技术如WebGL和WebAssembly。保持学习和参与,确保与时俱进。
12 6
|
1天前
|
JavaScript 前端开发 Android开发
kotlin安卓在Jetpack Compose 框架下使用webview , 网页中的JavaScript代码如何与native交互
在Jetpack Compose中使用Kotlin创建Webview组件,设置JavaScript交互:`@Composable`函数`ComposableWebView`加载网页并启用JavaScript。通过`addJavascriptInterface`添加`WebAppInterface`类,允许JavaScript调用Android方法如播放音频。当页面加载完成时,执行`onWebViewReady`回调。
|
1天前
|
机器学习/深度学习 人工智能 Devops
软件测试中的自动化技术发展趋势
随着信息技术的不断发展,软件测试领域也在不断创新与进步。本文将探讨软件测试中自动化技术的发展趋势,分析当前主流的自动化测试工具以及未来可能的发展方向,帮助读者更好地了解并应对软件测试领域的挑战。
12 0
|
2天前
|
SQL 存储 关系型数据库
MySQL存储过程——Baidu Comate智能代码助手添加20条DML语句——测试索引效果
MySQL存储过程——Baidu Comate智能代码助手添加20条DML语句——测试索引效果
4 0
|
4天前
|
机器学习/深度学习 敏捷开发 人工智能
探索软件测试中的AI辅助技术
【6月更文挑战第12天】在软件开发生命周期中,测试环节是确保产品质量的关键环节。随着人工智能技术的飞速发展,AI辅助的软件测试方法正在改变传统的测试流程。本文将探讨AI如何优化测试过程,提高缺陷检测的准确性和效率,并预测未来AI在软件测试领域的应用趋势。
12 1
|
4天前
|
JavaScript UED
ab77b6ea7f3fbf79.JS代码报错什么原因?
网站出现JS报错,表现为黄色小叹号,经排查发现是360自动收录JS引起。这不仅导致页面延迟增加,还影响用户体验。解决方案是删除360的自动推送JS代码。
10 1
|
4天前
|
机器学习/深度学习 人工智能 测试技术
技术创新与实践:我的自动化测试之路
自动化测试作为软件开发领域中的重要一环,对于项目质量和效率起着至关重要的作用。本文将分享我在自动化测试方面的实践经验和感悟,包括技术创新、挑战及解决方案,以及对未来发展的展望。
13 0