对于单元测试,我们使用grunt/karma-runner/jasmine/phantom.js.因为我们试图涵盖任何新功能,所以许多单元测试会迅速增长.而且,不幸的是,测试时间也在增加.现在它并不重要,1000次测试需要10秒,但它会变得越来越糟.
问题:
我知道,有些测试写的很糟糕(耗费大量时间),但我应该优化哪一个?是否存在一些karma/jasmine剖析器来测量每次测试的时间执行?
我可以启动更多的karma-runner线程/进程,因为CPU仅使用5%-10%?单元测试真的是独立的.
每当我保存文件时,karma:watch启动所有测试,可能存在karma-runner的一些选项,它只重新启动当前文件夹的测试(我们使用规则:单元测试file.spec.js存储在同一个文件夹中作为源文件.js)?
谢谢,
update1:有人建议我使用iit/ddescribe作为jasmine(与mocha的.only相同),它是开发/调试的绝佳选择,但可能存在其他方式吗?
我在这里将问题发布到karma-user论坛.
寻找缓慢的测试
reportSlowerThan
(点或进度报告器将报告所有比ms给定数字慢的测试),
您可以跳转到浏览器并以与使用应用程序相同的方式配置测试(例如,Chrome中的火焰图很棒).
使测试更快
并行化:
我们正在研究这个问题.您将能够跨多个浏览器并行化测试.当然,这些浏览器不必在同一台机器上运行,因此您也可以使用多台机器.
我不认为运行Karma本身的多个实例会有多大帮助,因为它是以非"非阻塞"的方式编写的,我并没有将其视为瓶颈.但是我们应该优化CPU /内存使用量.这个领域的许多改进将在v0.12中出现.
只运行一部分测试:
你应该完全使用iit
/ ddescribe
(Jasmine).这不适合你的任何理由?顺便说一句.摩卡的实施it.only()
和describe.only()
问题,所以我推荐Jasmine(或修复摩卡).
还有一个Google Closure 插件的原型,它只加载你真正需要的文件(比如iit
一个测试,它只会加载/解析/评估你真正需要的文件iit
).这大大改善了大型项目的开始时间 - 我们应该为其他模块加载器(RequireJS,CommonJS)做类似的技巧.
写更快的代码:
你可能已经知道了这一点...... ;-)
DOM很慢.逻辑/ DOM的良好分离将允许您在不实际触及DOM的情况下测试更多内容.如果您使用Angular,您可以查看测试指令示例.
使用依赖注入模式有很大帮助,因为您基本上可以最大限度地减少每个测试准备(以及拆除)所需的环境.这是一个例子.
通常,较低的较低测试更快.我认为用尽可能低的测试来涵盖每个功能/问题是件好事.
消除内存泄漏:
如果您的测试泄漏内存,浏览器将变得越来越慢,因此即使编写得很好,测试编号1000也会非常慢.确保每个测试释放所有参考.您可以使用http://localhost:9876/debug.html
和配置内存.在执行之前检查内存(在Jasmine执行所有describe()
块并收集测试之后)然后在执行测试之后 - 它应该是相同的.
发现一些内存泄漏比其他内存更难,但它可以显着提高速度 - 我已经看到了从大约5分钟到不到一分钟的东西只是通过消除内存泄漏.
1a)关于分析:你可以使用业力记者,添加到你的karma-config这个字符串:
reporters: [ 'progress', 'junit', ], junitReporter: { outputFile: basePath + 'test_out/unit.xml', suite: 'unit' },
它将生成这样的好xml:
<testcase name="BuilderController should have a tileSelectorId" time="0.015" classname="unit Chrome 31.0.1650 (Windows 7).tileBuilder testing"/> <testcase name="BuilderController by default should sort by title" time="0" classname="unit Chrome 31.0.1650 (Windows 7).tileBuilder testing"/>
您可以排序并选择应优化哪个最慢的测试
1b)你也可以使用来自karma config的reportSlowerThan
reportSlowerThan: 100,
Karma将通知您关于慢于100毫秒的测试
2)我不知道如何开始更多的业力 - 跑步者进程/线程.
3)因为grunt:watch为你提供了更改的filename.js,你可以启动相应的filename.spec.js,所以你必须编写特殊的grunt-task
并使用ddescribe和iit仅启动指定的describe/it.