【问题标题】:How to set jasmine for karma e2e for testing angular app?如何为 karma e2e 设置 jasmine 以测试 Angular 应用程序?
【发布时间】:2013-06-03 08:28:19
【问题描述】:

我尝试使用 karma 创建 e2e 测试,使用 yeoman 创建 jasmine。在我的karma-e2e.conf.js 中添加茉莉花:

files = [
   JASMINE,
   JASMINE_ADAPTER,
   ANGULAR_SCENARIO,
   ANGULAR_SCENARIO_ADAPTER,
   'test/e2e/**/*.js'
];

需要异步测试,所以我需要使用runswaitswaitsFor (https://github.com/pivotal/jasmine/wiki/Asynchronous-specs)

但如果我尝试使用它:

it('test', function () {
    runs(function () {
        ...
    });
});

场景测试运行器返回:

TypeError: Cannot call method 'runs' of null
    at runs (http://localhost:8080/adapter/lib/jasmine.js:562:32)
    at Object.<anonymous> (http://localhost:8080/base/test/e2e/eduUser.js:42:3)
    at Object.angular.scenario.SpecRunner.run   (http://localhost:8080/adapter/lib/angular-scenario.js:27057:15)
    at Object.run (http://localhost:8080/adapter/lib/angular-scenario.js:10169:18)

我不知道问题出在哪里。你能帮帮我吗?

【问题讨论】:

    标签: testing angularjs jasmine yeoman karma-runner


    【解决方案1】:

    使用 Karma 的 Angular e2e 测试不能也不能使用 JASMINE 适配器。取而代之的是ANGULAR_SCENARIO_ADAPTER,它与编写 Jasmine 测试的感觉相似。

    适配器的API 中的所有命令无论如何都是异步的。例如element('#nav-items').count() 不返回一个数字,它返回一个Future 对象。 Future 对象被放置在一个队列中,并随着运行器的进行而异步执行。引用API docs

    期望(未来)。{matcher}:

    [...] 所有 API 语句都返回一个 future 对象,该对象在执行后会获得一个赋值。

    如果您需要运行自己的异步测试代码,您可以扩展适配器的 DSL,这比听起来容易。这个想法是你返回你自己的Future,它可以由一个匹配器来评估,比如toBe()。在the e2e-tests.js Gist from Vojta 中有一些关于如何执行此操作的示例。只要记住在测试代码成功时调用done(null, myRetrunValue);myRetrunValue 是匹配器评估的值)。或者 done('Your own error message'); 如果您希望测试失败。

    更新:针对以下问题。要模拟登录,首先将名为 login 的函数添加到 dsl

    angular.scenario.dsl('login', function() {
      return function(selector) {
        
        // @param {DOMWindow} appWindow The window object of the iframe (the application)
        // @param {jQuery} $document jQuery wrapped document of the application
        // @param {function(error, value)} done Callback that should be called when done
        //                                      (will basically call the next item in the queuue)
        return this.addFutureAction('Logging in', function(appWindow, $document, done) {
    
          // You can do normal jQuery/jqLite stuff here on $document, just call done() when your asynchronous tasks have completed
          
          // Create some kind of listener to handle when your login is complete
          $document.one('loginComplete', function(e){
            done(null, true);
          }).one('loginError', function(e){
            done('Login error', false);
          });
          
          // Simulate the button click
          var loginButton = $document.find(selector || 'button.login');
          loginButton.click();
        })
      };
    });
    

    然后调用:

    beforeEach( function()
    {
        expect( login('button.login') ).toBeTruthy();
    });
    

    【讨论】:

    • 感谢这看起来不错。我需要登录的测试应用程序。所以我想在 beforeEach 中添加登录名并在 afterEach 中注销。登录 click() 后,我必须等待完成登录过程。您认为这种好方法是什么?
    • @MarekL,我已经用代码示例更新了答案。希望对您有所帮助。
    • 这个答案对我有帮助,但我仍在苦苦挣扎。我创建新的下一个问题stackoverflow.com/questions/16983116/…
    猜你喜欢
    • 2016-08-23
    • 1970-01-01
    • 2015-12-07
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    相关资源
    最近更新 更多