我无法回答有关travis-ci的问题,但我可以就使用jasmine对ember.js代码进行单元测试提供一些想法。
在开始使用ember.js之前,我使用jasmine和一个简单的node.js模块jasmine-node进行单元测试。这使我能够快速从命令行运行一套jasmine单元测试,而无需打开浏览器或使用“js-test runner”等工具。
当我拥有jasmine、jquery和简单的javascript模块时,这种方法非常有效,因为它可以让我的javascript代码易于阅读。但是,当我需要使用ember/handlebars等内容时,jasmine-node模块就失效了,因为它希望你将所有内容都可用于全局和window对象。但由于ember只是一个浏览器库,并不是所有内容都在“global”对象上。
我开始研究PhantomJS,与您一样,我也无法想象增加复杂性。因此,我决定花费一个周末写下缺失的jasmine测试运行器。我想要与jasmine-node相同的功能(这意味着在我的CI box上,我只需要一个最新版本的node.js和一个简单的npm模块即可运行测试)。
我写了一个npm模块叫
jasmine-phantom-node,它的核心是使用node.js运行phantomJS,然后启动一个常规的jasmine html runner,并使用一个非常基本的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', '');
});
});
这是我正在进行单元测试的生产Ember视图。
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', '');
}
}
});