下面的 Gulp 任务几乎完成了我想要的。
const gulp = require('gulp');
const browserify = require('browserify');
const vinylStream = require('vinyl-source-stream');
const vinylBuffer = require('vinyl-buffer');
const watchify = require('watchify');
const glob = require('glob');
const jasmineBrowser = require('gulp-jasmine-browser');
gulp.task('test', function() {
let testBundler = browserify({
entries: glob.sync('src/**/*-test.js'),
cache: {},
packageCache: {},
}).plugin(watchify);
function updateSpecs() {
return testBundler.bundle()
.pipe(vinylStream(jsBundleName))
.pipe(vinylBuffer())
.pipe(jasmineBrowser.specRunner({console: true}))
.pipe(jasmineBrowser.headless({driver: 'phantomjs'}));
}
testBundler.on('update', updateSpecs);
updateSpecs();
});
它使用 Browserify 捆绑了我所有的 Jasmine 规范,并通过 gulp -jasmine-browser对其进行了测试。它还监视它们所依赖的所有规范和所有模块,并在这些模块中的任何一个发生更改时重新运行测试。
唯一丑陋的一点,我真的希望看到解决,每次updateSpecs运行时都会创建一个新的 PhantomJS 实例和一个新的 Jasmine 服务器。我希望通过如下代码来避免这种情况:
gulp.task('test', function() {
let testBundler = browserify({
entries: glob.sync('src/**/*-test.js'),
cache: {},
packageCache: {},
}).plugin(watchify);
// persist the Jasmine server and PhantomJS browser
let testServer = jasmineBrowser.headless({driver: 'phantomjs'});
function updateSpecs() {
return testBundler.bundle()
.pipe(vinylStream(jsBundleName))
.pipe(vinylBuffer())
.pipe(jasmineBrowser.specRunner({console: true}))
.pipe(testServer);
}
testBundler.on('update', updateSpecs);
updateSpecs();
});
唉,这行不通。启动任务后,所有测试都运行良好,但下一次updateSpecs调用时,我收到write after end错误并且任务以状态 1 退出。此错误源自readable-streamNode 模块。
据我了解,end第一次运行期间的事件updateSpecs处于testServer不接受任何新输入的状态。不幸的是,Node.js 流文档对于如何解决这个问题并不是很清楚。
我曾尝试在不同的地方打破管道链,但我得到了相同的结果,这似乎表明这是流的普遍行为。我还尝试end通过插入未重新发出该事件的直通流来阻止事件传播,但这完全阻止了测试的运行。最后,我尝试从任务return中获取流;testServer这停止了错误,但是尽管updateSpecs每次源更改时都会调用该函数,但测试仅在任务第一次启动时运行。这一次,testServer似乎根本就忽略了新的输入。
gulp-jasmine-browser 文档建议以下代码可以工作:
var watch = require('gulp-watch');
gulp.task('test', function() {
var filesForTest = ['src/**/*.js', 'spec/**/*-test.js'];
return gulp.src(filesForTest)
.pipe(watch(filesForTest))
.pipe(jasmineBrowser.specRunner())
.pipe(jasmineBrowser.server());
});
它继续建议您也可以使用 Browserify 进行这项工作,但这没有说明。显然,gulp-watch 做了一些事情,导致后续管道稍后接受更新的输入。如何用 watchify 模仿这种行为?