量角器测试与CucumberJS不规则地通过

时间:2015-04-14 12:51:48

标签: angularjs cucumber protractor bdd cucumberjs

使用AngularJS尝试一些BDD,这样我就可以使用Protractor和CucumberJS自动化场景了。奇怪的是,魔鬼的工作是试图让步骤定义明智地失败。

Features.feature

Feature: Calculator
  As a user
  I want to perform arithmetic operations
  So that I don't have to think too hard

  Scenario: Addition 
    Given I have opened the calculator application
    When I add 2 and 2
    Then the result 4 should be displayed 

Steps.js

module.exports = function() {

  this.Given(/^I have opened the calculator application$/, function (callback) {
    //load protractor config baseurl
    browser.get('').then(
    callback());
  });

  this.When(/^I add (\d+) and (\d+)$/, function (arg1, arg2, callback) {
    //enter numbers to be added
    element(by.model('firstNumber')).sendKeys(arg1);
    element(by.model('secondNumber')).sendKeys(arg2);
    //select mathematical operator from dropdown list
    element(by.css('select')).click();
    element(by.css('select option[value="0"]')).click();
    //hit the calculate button
    element(by.buttonText('=')).click();
    callback();
  });

  this.Then(/^the result (\d+) should be displayed$/, function (arg1, callback) {

   element(by.binding('result')).getText()
    .then(function(result){
       result === arg1 ? callback() : callback.fail();
    });
  });
};

的index.html

    <!doctype html>
<html class="no-js">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body ng-app="calculator" ng-controller="MainCtrl">
    <input ng-model="firstNumber">
    <select ng-model="selectedOperation" ng-options="op as op.value for op in operations"></select>
    <input ng-model="secondNumber">
    <button ng-click="Calculate()">=</button>
    <span ng-bind="result"></span> 

    <script src="bower_components/angular/angular.js"></script>
    <script src="scripts/app.js"></script>
  </body>
</html>

App.js

    angular
  .module('calculator', [])
  .controller('MainCtrl', function ($scope) {
    $scope.operations = [
        { label: 'Add', value: '+' },
        { label: 'Subtract', value: '-' }
    ];
    $scope.selectedOperation = $scope.operations[0];
    $scope.Calculate = function(){
        switch($scope.selectedOperation.label) {
            case 'Add':
                var result = Number($scope.firstNumber) + Number($scope.secondNumber);
                break;
            case 'Subtract':
                var result = Number($scope.firstNumber) - Number($scope.secondNumber);
                break;
        };
        $scope.result = result !== NaN || result === 0 ? result : 'Boo! bad input!';
    };
  });

量角器输出:

1个场景(1个通过) 3个步骤(3个通过)

上面的设置工作正常。量角器提供正确的输出,我可以通过在Then()步骤中评估不正确的结果来使方案失败。看起来很好。

我看到的第一个问题是当我尝试使When步骤失败时。例如,使用上面相同的设置,但尝试找到不存在的元素。

  this.When(/^I add (\d+) and (\d+)$/, function (arg1, arg2, callback) {
    //enter numbers to be added. Sabotage edition!
    element(by.model('AintNoGood')).sendKeys(arg1);
    element(by.model('secondNumber')).sendKeys(arg2);
    //select mathematical operator from dropdown list
    element(by.css('select')).click();
    element(by.css('select option[value="0"]')).click();
    //hit the calculate button
    element(by.buttonText('=')).click();
    callback();
  });

量角器输出: NoSuchElementError:找不到使用locator找到的元素:by.model(&#34; AintNoGood&#34;) ... 1个场景(1个失败) 3个步骤(1个失败,2个过去)

第二步失败了。我的印象是,当步骤失败时,所有后续步骤都会被跳过,但量角器继续进行到第3步,无论如何都要通过。

陌生人仍然......我清空了HTML。 BDD测试优先和所有。

Inmdex.html

<!doctype html>
<html class="no-js">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body ng-app="calculator" ng-controller="MainCtrl">

    <!--Ghost town here-->

    <script src="bower_components/angular/angular.js"></script>
    <script src="scripts/app.js"></script>
  </body>
</html>

假设我一次一步地完成这个场景,我会在第二步写下定义,假设它会失败。

module.exports = function() {

  this.Given(/^I have opened the calculator application$/, function (callback) {
    //load protractor config baseurl
    browser.get('').then(
    callback());
  });

  this.When(/^I add (\d+) and (\d+)$/, function (arg1, arg2, callback) {
    //enter numbers to be added
    element(by.model('firstNumber')).sendKeys(arg1);
    element(by.model('secondNumber')).sendKeys(arg2);
    //select mathematical operator from dropdown list
    element(by.css('select')).click();
    element(by.css('select option[value="0"]')).click();
    //hit the calculate button
    element(by.buttonText('=')).click();
    callback();
  });

  this.Then(/^the result (\d+) should be displayed$/, function (arg1, callback) {
    callback.pending();
  });
};

量角器输出: 1个场景(1个待定) 3个步骤(1个待定,2个通过)

所以第二步过去了。显然它不应该没有它应该在html中定位的元素。

问题:

知道这里发生了什么吗?

如果没有,在我花更多时间去理解它之前,我想知道是否有人在使用Protractor和CucumberJS时取得了成功?

1 个答案:

答案 0 :(得分:2)

此:

browser.get('').then(
    callback());
});

应该是:

browser.get('').then(callback);

实际上,您立即调用callback并将其返回的任何内容作为参数传递给then

在您的第一个this.When结尾处:

 callback();

但它前面的element()调用链不会阻塞。他们只是安排在WebDriver控制流程上完成操作,所以我怀疑这个&#34; callback()&#34;将立即被调用。您可以通过执行以下操作来解决此问题:

element(by.buttonText('=')).click().then(callback);

获取在控制流中安排的回调。

WebDriver控制流程违反直觉并且常常是钝的,因此您需要阅读https://github.com/angular/protractor/blob/master/docs/control-flow.mdhttps://github.com/SeleniumHQ/selenium/wiki/WebDriverJs#control-flows