如何使用Grunt和Mocha以mtime顺序运行单元测试

时间:2017-10-12 20:50:40

标签: javascript unit-testing gruntjs mocha grunt-contrib-watch

所以当你做TDD时,你是否等待它运行所有测试,直到你正在进行的测试?这需要太多时间。当我急于求助时,我将测试文件重命名为aaaaaaaaaaaaaaaa_testsomething.test.js,以便它首先运行,我尽快看到错误。

我不喜欢这种方法,我确定有解决方案,但我无法找到它。那么使用Mocha以mtime顺序运行单元测试的最简单方法是什么?有'-sort选项,但它只按名称对文件进行排序。如何通过修改时间对它们进行排序?

我的Gruntfile.js:



module.exports = function(grunt) {

  grunt.initConfig({
    watch: {
      tests: {
        files: ['**/*.js', '!**/node_modules/**'],
        tasks: ['mochacli:local']
      }
    },
    mochacli: {
      options: {
        require: ['assert'],
        reporter: 'spec',
        bail: true,
        timeout: 6000,
        sort: true,
        files: ['tests/*.js']
      },
      local: {
        timeout: 25000
      }
    }
  });

  
  grunt.loadNpmTasks('grunt-mocha-cli');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('test', ['mochacli:local']);
  grunt.registerTask('livetests', [ 'watch:tests']);

};




注意:它不重复。每次保存源代码文件时,我都不想编辑我的测试或Gruntfile.js。我询问如何修改Grunt任务,以便它首先从上次修改的* .test.js文件运行测试。按照标题中的说明对mtime进行单元测试。

简单场景:我在编辑器中打开test1.test.js,更改它,按Ctrl + B,然后从test1.test.js运行单元测试,然后运行test4.test.js。我打开test4.test.js,按Ctrl + S,按Ctrl + B,它从test4.test.js运行测试然后test1.test.js

我正在思考一些Grunt插件首先对文件进行排序,因此我可以将其结果放在&#39; tests / * .js&#39;使用grunt.config.set('mochacli.options.files', 'tests/recent.js,tests/older.js', ....);,但我找不到任何可以作为中间件使用的内容,不想发明脚本,因为我确定已经实现了这一点。< / p>

2 个答案:

答案 0 :(得分:1)

如果您正在使用mocha,则可以在您感兴趣的测试中设置.on;

// automatically queue the job after the initial creation
if (!jenkins.model.Jenkins.instance.getItemByFullName(repo)) {
  queue(repo)
}

答案 1 :(得分:1)

  

不想发明自行车,因为我确信已经实现了这一点。

......有时你必须骑自行车;)

<强>解决方案

这可以通过在Gruntfile.js中注册中间custom-task来动态执行以下操作来实现:

  1. 使用具有相应grunt.file.expand模式的globbing获取所有单元测试文件(.js)的文件路径。
  2. 按文件mtime / modified-date。
  3. 对每个匹配的文件路径进行排序
  4. 使用grunt.config
  5. 使用按时间顺序排序的文件路径配置mochacli.options.file数组
  6. 使用Target
  7. 运行local任务中定义的mochacli grunt.task.run

    <强> Gruntfile.js

    按如下方式配置Gruntfile.js

    module.exports = function(grunt) {
    
      // Additional built-in node module.
      var statSync = require('fs').statSync;
    
      grunt.initConfig({
        watch: {
          tests: {
            files: ['**/*.js', '!**/node_modules/**', '!Gruntfile.js'],
            tasks: ['runMochaTests']
          }
        },
        mochacli: {
          options: {
            require: ['assert'],
            reporter: 'spec',
            bail: true,
            timeout: 6000,
            files: [] // <-- Intentionally empty, to be generated dynamically.
          },
          local: {
            timeout: 25000
          }
        }
      });
    
      grunt.loadNpmTasks('grunt-mocha-cli');
      grunt.loadNpmTasks('grunt-contrib-watch');
    
      /**
       * Custom task to dynamically configure the `mochacli.options.files` Array.
       * All filepaths that match the given globbing pattern(s), which is specified
       # via the `grunt.file.expand` method, will be sorted chronologically via each
       * file(s) latest modified date (i.e. mtime).
       */
      grunt.registerTask('runMochaTests', function configMochaTask() {
        var sortedPaths = grunt.file.expand({ filter: 'isFile' }, 'tests/**/*.js')
          .map(function(filePath) {
            return {
              fpath: filePath,
              modtime: statSync(filePath).mtime.getTime()
            }
          })
          .sort(function (a, b) {
            return a.modtime - b.modtime;
          })
          .map(function (info) {
            return info.fpath;
          })
          .reverse();
    
        grunt.config('mochacli.options.files', sortedPaths);
        grunt.task.run(['mochacli:local']);
      });
    
      grunt.registerTask('test', ['runMochaTests']);
      grunt.registerTask('livetests', [ 'watch:tests']);
    
    };
    

    附加说明

    使用上面的配置。通过CLI运行$ grunt livetests,然后保存修改后的测试文件将导致 Mocha 根据上次修改日期的文件按时间顺序运行每个测试文件(即最新修改的文​​件将先运行,最后一个修改过的文件最后运行)。运行$ grunt test时也适用同样的逻辑。

    但是,如果您希望 Mocha 首先运行最新修改的文​​件,然后按正常顺序运行其他文件(即按名称),则自定义runMochaTests任务上面的Gruntfile.js应该替换为以下逻辑:

    /**
     * Custom task to dynamically configure the `mochacli.options.files` Array.
     * The filepaths that match the given globbing pattern(s), which is specified
     # via the `grunt.file.expand` method, will be in normal sort order (by name).
     * However, the most recently modified file will be repositioned as the first
     * item in the `filePaths` Array (0-index position).
     */
    grunt.registerTask('runMochaTests', function configMochaTask() {
      var filePaths = grunt.file.expand({ filter: 'isFile' }, 'tests/**/*.js')
        .map(function(filePath) {
          return filePath
        });
    
      var latestModifiedFilePath = filePaths.map(function(filePath) {
          return {
            fpath: filePath,
            modtime: statSync(filePath).mtime.getTime()
          }
        })
        .sort(function (a, b) {
          return a.modtime - b.modtime;
        })
        .map(function (info) {
          return info.fpath;
        })
        .reverse()[0];
    
      filePaths.splice(filePaths.indexOf(latestModifiedFilePath), 1);
      filePaths.unshift(latestModifiedFilePath);
    
      grunt.config('mochacli.options.files', filePaths);
      grunt.task.run(['mochacli:local']);
    });