【问题标题】:Protractor tests with CucumberJS passing irregularlyCucumberJS 的量角器测试不规则通过
【发布时间】:2015-04-14 12:51:47
【问题描述】:

尝试使用 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();
    });
  });
};

索引.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 个通过)

上面的设置工作正常。 Protractor 给出了正确的输出,我可以通过在 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:使用定位器找不到元素:by.model(“AintNoGood”) ... 1 个场景(1 个失败) 3 个步骤(1 个失败,2 个通过)

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

更奇怪...我清空了 HTML。 BDD 测试优先。

索引.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?

【问题讨论】:

    标签: angularjs cucumber protractor bdd cucumberjs


    【解决方案1】:

    这个:

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

    应该是:

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

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

    在您的第一个 this.When 中,您以:

     callback();
    

    但它前面的element() 调用链不会阻塞。他们只是安排在 WebDriver 控制流上完成的操作,所以我怀疑这个“callback()”几乎会立即被调用。您可以通过以下方式解决此问题:

    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

    【讨论】:

    • "获取控制流中安排的回调",绝对正确。这正是我错过的。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多