2013-07-05 54 views
3

我已经使用Yeoman发电机组建立了骨干项目。yeoman发电机自动运行测试

在Gruntfile中有一个称为服务器的任务,它运行一堆东西,但也有livereload。还有另外一个叫做测试的任务,运行几乎相同的东西,但运行测试一次,没有livereload。

我对工作流有点困惑。我无法在一个终端窗口中运行服务器,而另一个终端窗口中的测试由于他们使用相同的端口而不能运行。

它看起来像你必须停止服务器每次运行测试。

如何设置它以便每次文件更改并重新加载应用程序时自动运行测试?

这里是gruntfile(默认从发生器):

'use strict'; 
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet; 
var mountFolder = function (connect, dir) { 
    return connect.static(require('path').resolve(dir)); 
}; 

// # Globbing 
// for performance reasons we're only matching one level down: 
// 'test/spec/{,*/}*.js' 
// use this if you want to match all subfolders: 
// 'test/spec/**/*.js' 
// templateFramework: 'handlebars' 

module.exports = function (grunt) { 
    // load all grunt tasks 
    require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); 

    // configurable paths 
    var yeomanConfig = { 
     app: 'app', 
     dist: 'dist' 
    }; 

    grunt.initConfig({ 
     yeoman: yeomanConfig, 
     watch: { 
      coffee: { 
       files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'], 
       tasks: ['coffee:dist'] 
      }, 
      coffeeTest: { 
       files: ['test/spec/{,*/}*.coffee'], 
       tasks: ['coffee:test'] 
      }, 
      compass: { 
       files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'], 
       tasks: ['compass'] 
      }, 
      express: { 
       files:[ 
        '<%= yeoman.app %>/*.html', 
        '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css', 
        '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js', 
        '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}' 
       ], 
       tasks: [ 'express:dev', 'livereload' ] 
      }, 
      livereload: { 
       files: [ 
        '<%= yeoman.app %>/*.html', 
        '{.tmp,<%= yeoman.app %>}/styles/{,*/}*.css', 
        '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js', 
        '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}' 
       ], 
       tasks: ['livereload'] 
      }, 
      handlebars: { 
       files: [ 
        '<%= yeoman.app %>/scripts/templates/*.hbs' 
       ], 
       tasks: ['handlebars'] 
      } 
     }, 
     connect: { 
      options: { 
       port: 9000, 
       // change this to '0.0.0.0' to access the server from outside 
       hostname: 'localhost' 
      }, 
      livereload: { 
       options: { 
        middleware: function (connect) { 
         return [ 
          lrSnippet, 
          mountFolder(connect, '.tmp'), 
          mountFolder(connect, 'app') 
         ]; 
        } 
       } 
      }, 
      test: { 
       options: { 
        middleware: function (connect) { 
         return [ 
          mountFolder(connect, '.tmp'), 
          mountFolder(connect, 'test') 
         ]; 
        } 
       } 
      }, 
      dist: { 
       options: { 
        middleware: function (connect) { 
         return [ 
          mountFolder(connect, 'dist') 
         ]; 
        } 
       } 
      } 
     }, 
     express: { 
      options: { 
       // Override defaults here 
       port: '<%= connect.options.port %>' 
      }, 
      dev: { 
       options: { 
        script: 'server/app.js' 
       } 
      }, 
      prod: { 
       options: { 
        script: 'server/app.js' 
       } 
      }, 
      test: { 
       options: { 
        script: 'server/app.js' 
       } 
      } 
     }, 
     open: { 
      server: { 
       path: 'http://localhost:<%= connect.options.port %>' 
      } 
     }, 
     clean: { 
      dist: ['.tmp', '<%= yeoman.dist %>/*'], 
      server: '.tmp' 
     }, 
     jshint: { 
      options: { 
       jshintrc: '.jshintrc' 
      }, 
      all: [ 
       'Gruntfile.js', 
       '<%= yeoman.app %>/scripts/{,*/}*.js', 
       '!<%= yeoman.app %>/scripts/vendor/*', 
       'test/spec/{,*/}*.js' 
      ] 
     }, 
     mocha: { 
      all: { 
       options: { 
        run: true, 
        urls: ['http://localhost:<%= connect.options.port %>/index.html'] 
       } 
      } 
     }, 
     coffee: { 
      dist: { 
       files: [{ 
        // rather than compiling multiple files here you should 
        // require them into your main .coffee file 
        expand: true, 
        cwd: '<%= yeoman.app %>/scripts', 
        src: '*.coffee', 
        dest: '.tmp/scripts', 
        ext: '.js' 
       }] 
      }, 
      test: { 
       files: [{ 
        expand: true, 
        cwd: '.tmp/spec', 
        src: '*.coffee', 
        dest: 'test/spec' 
       }] 
      } 
     }, 
     compass: { 
      options: { 
       sassDir: '<%= yeoman.app %>/styles', 
       cssDir: '.tmp/styles', 
       imagesDir: '<%= yeoman.app %>/images', 
       javascriptsDir: '<%= yeoman.app %>/scripts', 
       fontsDir: '<%= yeoman.app %>/styles/fonts', 
       importPath: 'app/bower_components', 
       relativeAssets: true 
      }, 
      dist: {}, 
      server: { 
       options: { 
        debugInfo: true 
       } 
      } 
     }, 
     requirejs: { 
      dist: { 
       // Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js 
       options: { 
        // `name` and `out` is set by grunt-usemin 
        baseUrl: 'app/scripts', 
        optimize: 'none', 
        paths: { 
         'templates': '../../.tmp/scripts/templates' 
        }, 
        // TODO: Figure out how to make sourcemaps work with grunt-usemin 
        // https://github.com/yeoman/grunt-usemin/issues/30 
        //generateSourceMaps: true, 
        // required to support SourceMaps 
        // http://requirejs.org/docs/errors.html#sourcemapcomments 
        preserveLicenseComments: false, 
        useStrict: true, 
        wrap: true, 
        //uglify2: {} // https://github.com/mishoo/UglifyJS2 
       } 
      } 
     }, 
     useminPrepare: { 
      html: '<%= yeoman.app %>/index.html', 
      options: { 
       dest: '<%= yeoman.dist %>' 
      } 
     }, 
     usemin: { 
      html: ['<%= yeoman.dist %>/{,*/}*.html'], 
      css: ['<%= yeoman.dist %>/styles/{,*/}*.css'], 
      options: { 
       dirs: ['<%= yeoman.dist %>'] 
      } 
     }, 
     imagemin: { 
      dist: { 
       files: [{ 
        expand: true, 
        cwd: '<%= yeoman.app %>/images', 
        src: '{,*/}*.{png,jpg,jpeg}', 
        dest: '<%= yeoman.dist %>/images' 
       }] 
      } 
     }, 
     cssmin: { 
      dist: { 
       files: { 
        '<%= yeoman.dist %>/styles/main.css': [ 
         '.tmp/styles/{,*/}*.css', 
         '<%= yeoman.app %>/styles/{,*/}*.css' 
        ] 
       } 
      } 
     }, 
     htmlmin: { 
      dist: { 
       options: { 
        /*removeCommentsFromCDATA: true, 
        // https://github.com/yeoman/grunt-usemin/issues/44 
        //collapseWhitespace: true, 
        collapseBooleanAttributes: true, 
        removeAttributeQuotes: true, 
        removeRedundantAttributes: true, 
        useShortDoctype: true, 
        removeEmptyAttributes: true, 
        removeOptionalTags: true*/ 
       }, 
       files: [{ 
        expand: true, 
        cwd: '<%= yeoman.app %>', 
        src: '*.html', 
        dest: '<%= yeoman.dist %>' 
       }] 
      } 
     }, 
     copy: { 
      dist: { 
       files: [{ 
        expand: true, 
        dot: true, 
        cwd: '<%= yeoman.app %>', 
        dest: '<%= yeoman.dist %>', 
        src: [ 
         '*.{ico,txt}', 
         '.htaccess', 
         'images/{,*/}*.{webp,gif}' 
        ] 
       }] 
      } 
     }, 
     bower: { 
      all: { 
       rjsConfig: '<%= yeoman.app %>/scripts/main.js' 
      } 
     }, 
     handlebars: { 
      compile: { 
       options: { 
        namespace: 'JST', 
        amd: true 
       }, 
       files: { 
        '.tmp/scripts/templates.js': ['<%= yeoman.app %>/scripts/templates/*.hbs'] 
       } 
      } 
     } 
    }); 

    grunt.renameTask('regarde', 'watch'); 

    grunt.registerTask('createDefaultTemplate', function() { 
     grunt.file.write('.tmp/scripts/templates.js', 'this.JST = this.JST || {};'); 
    }); 

    grunt.registerTask('server', function (target) { 
     if (target === 'dist') { 
      return grunt.task.run(['build', 'open', 'connect:dist:keepalive']); 
     } 

     grunt.task.run([ 
      'clean:server', 
      'coffee:dist', 
      'createDefaultTemplate', 
      'handlebars', 
      'compass:server', 
      'livereload-start', 
      'connect:livereload', 
      'open', 
      'watch' 
     ]); 
    }); 

    grunt.registerTask('expressserver', function (target) { 
     if (target === 'dist') { 
      return grunt.task.run(['build', 'open', 'connect:dist:keepalive']); 
     } 

     grunt.task.run([ 
      'clean:server', 
      'coffee:dist', 
      'createDefaultTemplate', 
      'handlebars', 
      'compass:server', 
      'express:dev', 
      'livereload-start', 
      'open', 
      'watch' 
     ]); 
    }); 

    grunt.registerTask('test', [ 
     'clean:server', 
     'coffee', 
     'createDefaultTemplate', 
     'handlebars', 
     'compass', 
     'connect:test', 
     'mocha' 
    ]); 

    grunt.registerTask('build', [ 
     'clean:dist', 
     'coffee', 
     'createDefaultTemplate', 
     'handlebars', 
     'compass:dist', 
     'useminPrepare', 
     'requirejs', 
     'imagemin', 
     'htmlmin', 
     'concat', 
     'cssmin', 
     'uglify', 
     'copy', 
     'usemin' 
    ]); 

    grunt.registerTask('default', [ 
     'jshint', 
     'test', 
     'build' 
    ]); 
}; 

回答

0

如果您正在使用backbone-generator,我们没有这种能力现在。 但肯定是我们未来将添加到它的一个功能。

在此之前,你可以对Gruntfile和like this做一些调整。 对于那些调整工作,你需要如果你运行grunt server:test它会在浏览器打开test.html文件重命名test目录中的index.html来的test.html

现在。

关于端口问题同时使用服务器和测试,现在我不确定任何解决方案。但会尝试找到一个并在这里更新。