使用EmberJS进行持续集成

7
我目前正在研究如何将基于ember.js的应用程序测试套件集成到travis-ci中。首先,我们不在开源服务上,我们将其用于私有存储库等。
我查看了几个开源项目如何运行其ember.js测试套件,看起来他们设置了一个服务器与其项目一起使用,该服务器可能会在某人推送到存储库时得到更新。然后使用PhantomJS在该服务器上运行测试(实际上并非在travis-ci本身上运行)。
我对这种方法的问题是它增加了另一个步骤(最终增加了复杂性):我必须更新和维护具有最新代码的服务器,以便我可以使用PhantomJS运行测试套件。
另一个缺点是我不知道它如何使我们能够测试PR(pull-requests)。服务器必须使用来自PR的代码进行更新。在合并之前测试PR是travis-ci的伟大之处之一。
我找不到关于仅通过CLI运行ember.js测试的信息/内容 - 我希望有人在我之前解决了这个问题。
1个回答

5

我无法回答有关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', '');
    }
  }
});

谢谢分享 - 我没有深入研究代码,但它到底从哪里爬取数据?当涉及到phantomjs时,人们似乎使用了一个外部主机,他们也必须更新。我想避免这种情况。我们上周设置了一个完整的测试环境,包括jstestrunner等。我一直想在博客上写一篇文章并在这里发布。但是请告诉我你做了什么。 - Till
不需要外部主机:每次套件运行时,我都会创建一个node.js express web应用程序,它托管了使用npm模块所需的单个html文件。此文件使用jasmine和jasmine-html来运行您的测试,就像您在OSX / Ubuntu上手动运行一样。如果您在javascript本身中注释掉“process.exit(code = 0);”行,甚至可以在浏览器中查看它们(如果我需要查看完整的堆栈跟踪,我会为本地测试执行此操作,因为PhantomJS尚未带回足够的html以便使用我的npm模块进行爬取)。 - Toran Billups
一旦Express Web应用程序启动并显示Jasmine-HTML页面上的测试结果,我使用PhantomJS从HTML中抓取结果(通过phantomjs-node),并查看测试是否通过或失败。今天它还可以在快速失败的混合模式下工作,因为它仍然运行所有测试,但只显示第一个失败(再次强调 - 这是我的个人意见,但它有助于我专注于第一个失败的测试)。 - Toran Billups

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接