我无法回答你关于 travis-ci 的问题……但我可以提供一些关于使用 jasmine 对 ember.js 代码进行单元测试的想法。
在我开始使用 ember.js 之前,我正在使用 jasmine 和一个名为 jasmine-node 的简单 node.js 模块进行单元测试。这使我可以从命令行快速运行一套 jasmine 单元测试,而无需打开浏览器或使用“js-test runner”/等进行破解
当我使用 jasmine、jquery 和简单的 javascript 模块来保持我的 javascript 代码人类可读时,这非常有用。但是当我需要使用 ember/handlebars/etc 时,jasmine-node 模块就崩溃了,因为它希望你在全局和窗口上都有所有可用的东西。但是因为 ember 只是一个浏览器库,并不是所有东西都在“全局”上
我开始研究 PhantomJS 并且像您自己一样看不到自己增加了复杂性。因此,我决定花一个周末来写下 jasmine 测试运行器空间中缺少的东西,而不是围绕这个问题进行破解。我想要 jasmine-node 的相同功能(这意味着我的 CI 盒子上只需要一个最新版本的 node.js 和一个简单的 npm 模块来运行测试)
我编写了一个名为jasmine-phantom-node的 npm 模块,其核心是使用 node.js 来运行 phantomJS =>,这反过来会启动一个常规的 jasmine html 运行程序,并使用一个非常基本的 express web 应用程序抓取页面以获取测试结果。
我花时间在 github 项目中放置了 2 个不同的示例,以便其他人可以快速了解它是如何工作的。这是自以为是的,因此您需要在项目根目录中创建一个 html 文件,插件将使用该文件来执行您的测试。它还需要 jasmine 和 jasmine-html 以及最近的 jQuery。
它为我个人解决了这个问题,现在我可以使用简单的 jasmine 编写针对 ember 的测试,并在没有浏览器的情况下从 cmd 行运行它。
这是我最近在使用这个测试运行器时针对 ember 视图编写的示例 jasmine 单元测试。如果您想查看被测视图如何在应用程序中使用,这里是完整的 ember / django 项目的链接。
require('static/script/vendor/filtersortpage.js');
require('static/script/app/person.js');
describe ("PersonApp.PersonView Tests", function(){
var sut, router, controller;
beforeEach(function(){
sut = PersonApp.PersonView.create();
router = new Object({send:function(){}});
controller = PersonApp.PersonController.create({});
controller.set("target", router);
sut.set("controller", controller);
});
it ("does not invoke send on router when username does not exist", function(){
var event = {'context': {'username':'', 'set': function(){}}};
var sendSpy = spyOn(router, 'send');
sut.addPerson(event);
expect(sendSpy).not.toHaveBeenCalledWith('addPerson', jasmine.any(String));
});
it ("invokes send on router with username when exists", function(){
var event = {'context': {'username':'foo', 'set': function(){}}};
var sendSpy = spyOn(router, 'send');
sut.addPerson(event);
expect(sendSpy).toHaveBeenCalledWith('addPerson', 'foo');
});
it ("does not invoke set context when username does not exist", function(){
var event = {'context': {'username':'', 'set': function(){}}};
var setSpy = spyOn(event.context, 'set');
sut.addPerson(event);
expect(setSpy).not.toHaveBeenCalledWith('username', jasmine.any(String));
});
it ("invokes set context to empty string when username exists", function(){
var event = {'context': {'username':'foo', 'set': function(){}}};
var setSpy = spyOn(event.context, 'set');
sut.addPerson(event);
expect(setSpy).toHaveBeenCalledWith('username', '');
});
});
这是我在上面进行单元测试的生产余烬视图
PersonApp.PersonView = Ember.View.extend({
templateName: 'person',
addPerson: function(event) {
var username = event.context.username;
if (username) {
this.get('controller.target').send('addPerson', username);
event.context.set('username', '');
}
}
});