【问题标题】:unit-tests karma-runner/jasmine profiling单元测试业力跑步者/茉莉花分析
【发布时间】:2016-06-08 17:58:45
【问题描述】:

对于单元测试,我们使用 grunt/karma-runner/jasmine/phantom.js。因为我们试图涵盖任何新功能,所以许多单元测试迅速增长。而且,不幸的是,测试时间也在增加。 现在它并不重要,1000 次测试需要 10 秒,但它会越来越差。

还有问题:

  1. 我知道,有些测试写得不好(很费时间),但我应该优化哪一个?是否存在一些 karma/jasmine profiler 来测量每个测试的执行时间?

  2. 我可以启动更多的 karma-runner 线程/进程,因为 CPU 只使用了 5%-10%?单元测试真正独立。

  3. 每次我保存文件时,karma:watch 都会启动所有测试,可能存在 karma-runner 的某些选项,它仅重新启动当前文件夹的测试(我们使用规则: 单元测试 file.spec.js 存储在与源 file.js 相同的文件夹中)?

谢谢,

update1:​​有人建议我使用iit/ddescribe for jasmine(与.only for mocha 相同),它是开发/调试的绝佳选择,但可能以其他方式存在?

我将问题发布到业力用户论坛here

【问题讨论】:

  • 尝试切换到 Chrome 而不是 Phantom。切换后我们体验到了明显更好的结果(当然您的里程可能会有所不同)。

标签: javascript unit-testing jasmine karma-runner


【解决方案1】:

寻找慢速测试

  • reportSlowerThan(点或进度报告器将报告所有比给定数字慢的测试,以毫秒为单位),

  • 您可以跳到浏览器并分析您的测试,就像使用应用程序一样(例如,Chrome 中的flamecharts 很棒)。

加快测试速度

  • 并行化:

    我们正在努力解决这个问题。您将能够跨多个浏览器并行化测试。当然,这些浏览器不必在同一台机器上运行,因此您也可以使用多台机器。

    我认为运行多个 Karma 实例本身不会有太大帮助,因为它是以非常“非阻塞”的方式编写的,而且我还没有看到它是瓶颈。然而,我们应该优化 CPU/内存使用。 v0.12 将在这方面进行大量改进。

  • 只运行一部分测试:

    你应该完全使用iit/ddescribe (Jasmine)。为什么这对你不起作用?顺便提一句。 Mocha 对it.only()describe.only() 的实现有问题,所以我推荐 Jasmine(或修复 Mocha)。

    还有一个 Google Closure plugin 的原型,它只加载你真正需要的文件(比如你 iit 一个测试,它只会加载/解析/评估你真正需要的文件 iit) .这显着缩短了大型项目的启动时间——我们应该为其他模块加载器(RequireJS、CommonJS)做类似的技巧。

  • 编写更快的代码:

    你可能已经知道了... ;-)

    DOM 很慢。逻辑/DOM 的良好分离将允许您在不实际接触 DOM 的情况下测试更多内容。如果你使用 Angular,你可以查看testing directives example

    使用依赖注入模式有很大帮助,因为您基本上可以最大限度地减少为每个测试准备(以及拆除)所需的环境。这里是an example

    一般来说,较低的测试速度更快。我认为最好用尽可能少的测试来涵盖每个功能/问题。

  • 消除内存泄漏:

    如果您的测试泄漏内存,浏览器会变得越来越慢,因此测试编号 1000 会非常慢,即使它写得很好。确保每个测试都释放所有引用。您可以使用http://localhost:9876/debug.html 并分析内存。在执行之前检查内存(在 Jasmine 执行所有 describe() 块并收集测试之后)然后在执行测试之后 - 它应该是相同的。

    发现一些内存泄漏比其他的更难,但它可以显着提高速度 - 我已经看到仅通过消除内存泄漏从大约 5 分钟到不到 1 分钟。

【讨论】:

  • 您能否详细说明如何“在执行前检查内存(在 Jasmine 执行所有 describe() 块并收集测试之后)然后在执行测试之后”?
  • npmjs.com/package/grunt-contrib-jasmine-phantom 这个插件解决了这个问题,涵盖了你在回答中提到的内容。
【解决方案2】:

1a) 关于分析:您可以使用karma reporters,将这些字符串添加到您的 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) 我不知道如何启动更多的 karma-runner 进程/线程。

3) 因为 grunt:watch 为你提供了修改后的 filename.js,所以你可以启动对应的 filename.spec.js,所以你必须编写特殊的 grunt-task

并使用 ddescribeiit 仅启动指定的 describe/it。

【讨论】:

    【解决方案3】:

    如果您正在寻找一种方法来了解哪些规格很慢,我写了一篇关于它的博客文章 (http://jipiboily.com/how-to-know-jasmine-specs-are-slow/),但简短的版本是使用我制作的这个记者:

    // This works under Jasmine 2.3
    var slowSpecsReporter = {
      specStarted: function(result) {
        this.specStartTime = Date.now()
      },
      specDone: function(result) {
        var seconds = (Date.now() - this.specStartTime) / 1000
        if (seconds > 0.5) {
          console.log('WARNING - This spec took ' + seconds + ' seconds: "' + result.fullName + '"')
        }
      },
    }
    jasmine.getEnv().addReporter(slowSpecsReporter);
    

    【讨论】:

      猜你喜欢
      • 2014-12-12
      • 2016-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-12
      相关资源
      最近更新 更多