NightWatch开发向导(一):使用NightWatch

写测试

使用首选的CSS选择器模型在页面上定位元素,Nightwatch使编写自动端到端测试变得非常容易。
为项目中的测试创建一个单独的文件夹,例如:tests。其中的每个文件都将由Nightwatch测试运行器作为测试加载。基本测试将如下所示:

module.exports = {
  'Demo test Google' : function (browser) {
    browser
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .setValue('input[type=text]', 'nightwatch')
      .waitForElementVisible('button[name=btnG]', 1000)
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('#main', 'Night Watch')
      .end();
  }
};

注:代码中“name=btnG”的描述应该是旧的描述,新的应该是“name=btnK”,另外由于使用环境的环境不同,使用css选择器的属性也有所不同,请以实际情况为准

当您想要关闭测试时,请记住始终调用.end()方法,以便正确关闭Selenium会话。
如果需要,测试可以有多个步骤:

module.exports = {
  'step one' : function (browser) {
    browser
      .url('http://www.google.com')
      .waitForElementVisible('body', 1000)
      .setValue('input[type=text]', 'nightwatch')
      .waitForElementVisible('button[name=btnG]', 1000)
  },

  'step two' : function (browser) {
    browser
      .click('button[name=btnG]')
      .pause(1000)
      .assert.containsText('#main', 'Night Watch')
      .end();
  }
};

测试也可以这种格式编写:

this.demoTestGoogle = function (browser) {
  browser
    .url('http://www.google.com')
    .waitForElementVisible('body', 1000)
    .setValue('input[type=text]', 'nightwatch')
    .waitForElementVisible('button[name=btnG]', 1000)
    .click('button[name=btnG]')
    .pause(1000)
    .assert.containsText('#main', 'The Night Watch')
    .end();
};

使用XPath选择器
Nightwatch也支持xpath选择器。要切换到xpath而不是css选择器作为定位策略,在测试中调用方法useXpath(),如下例所示。要切换回CSS,请调用useCss()
要始终使用xpath,请在测试设置中将属性“use_xpath”设置为true。

this.demoTestGoogle = function (browser) {
  browser
    .useXpath() // every selector now must be xpath
    .click("//tr[@data-recordid]/span[text()='Search Text']")
    .useCss() // we're back to CSS now
    .setValue('input[type=text]', 'nightwatch')
};

BDD期待断言
Nightwatch从版本v0.7开始引入了一个新的BDD风格的断言库,它极大地提高了断言的灵活性和可读性。
expect断言使用来自Chai框架的Expect api的子集,此时仅可用于元素。这是一个例子:

module.exports = {
  'Demo test Google' : function (client) {
    client
      .url('http://google.no')
      .pause(1000);

    // expect element  to be present in 1000ms
    client.expect.element('body').to.be.present.before(1000);

    // expect element <#lst-ib> to have css property 'display'
    client.expect.element('#lst-ib').to.have.css('display');

    // expect element  to have attribute 'class' which contains text 'vasq'
    client.expect.element('body').to.have.attribute('class').which.contains('vasq');

    // expect element <#lst-ib> to be an input tag
    client.expect.element('#lst-ib').to.be.an('input');

    // expect element <#lst-ib> to be visible
    client.expect.element('#lst-ib').to.be.visible;

    client.end();
  }
};

expect接口为定义断言提供了更加灵活和流畅的语言,与现有的断言接口相比有了显着的改进。唯一的缺点是不再可能链接断言,此时尚不支持自定义消息。
有关可用期望断言的完整列表,请参阅API文档。
在[Every]之前和[Each]之后使用
Nightwatch提供在测试中使用的标准之前/之后以及之前/之后的每个挂钩。 之前和之后将分别在执行测试套件之前和之后运行,而beforeEach和afterEach分别在每个测试用例之前和之后运行(测试步骤)。
所有方法都将N​​ightwatch实例作为参数传递。

module.exports = {
  before : function(browser) {
    console.log('Setting up...');
  },

  after : function(browser) {
    console.log('Closing down...');
  },

  beforeEach : function(browser) {

  },

  afterEach : function() {

  },

  'step one' : function (browser) {
    browser
     // ...
  },

  'step two' : function (browser) {
    browser
    // ...
      .end();
  }
};

在上面的例子中,方法调用的顺序如下:before()beforeEach()“step one”afterEach()beforeEach()“step two”afterEach()after()
出于向后兼容性原因,afterEach挂钩只能以其异步形式接收浏览器对象 - afterEach(browser,done){..}
所有的before[Each]和after[Each]方法也可以执行异步操作,在这种情况下,它们需要将回调作为第二个参数传递。
必须在异步操作完成时调用done函数作为最后一步。不调用它将导致超时错误。

module.exports = {
  beforeEach: function(browser, done) {
    // performing an async operation
    setTimeout(function() {
      // finished async duties
      done();
    }, 100);
  },

  afterEach: function(browser, done) {
    // performing an async operation
    setTimeout(function() {
      // finished async duties
      done();
    }, 200);
  }
};

控制完成的调用超时
默认情况下,完成调用超时设置为10秒(单元测试为2秒)。在某些情况下,这可能不足以避免超时错误,您可以通过在外部全局文件中定义asyncHookTimeout属性(以毫秒为单位)来增加此超时(有关外部全局变量的详细信息,请参阅下文)。
有关示例,请参阅提供的globalsModule示例。
显然未通过测试
通过简单地使用Error参数调用done,可以在测试挂钩中故意进行测试失败:

module.exports = {
  afterEach: function(browser, done) {
    // performing an async operation
    performAsync(function(err) {
      if (err) {
        done(err);
      }
      // ...
    });
  }
};

External Globals
大多数情况下,在globals_path属性中指定的外部文件中定义全局变量更有用,而不是在nightwatch.json中定义它们。
您可以根据需要覆盖每个环境的全局变量。假设您在本地运行测试,并且还在远程登台服务器上运行。大多数情况下,您需要一些不同的设置。
Global Hooks
在测试范围之外,全局也可以使用与测试套件相同的一组钩子。有关详细信息,请参阅以下示例。在全局钩子的情况下,beforeEach和afterEach引用测试套件(即测试文件),并在测试套件之前和之后运行。
Global Settings
有许多全局变量保持测试设置并可以控制测试执行。这些在提供的globalsModule示例中有详细说明。

module.exports = {
  'default' : {
    isLocal : true,
  },

  'integration' : {
    isLocal : false
  },

  // External before hook is ran at the beginning of the tests run, before creating the Selenium session
  before: function(done) {
    // run this only for the local-env
    if (this.isLocal) {
      // start the local server
      App.startServer(function() {
        // server listening
        done();
      });
    } else {
      done();
    }
  },

  // External after hook is ran at the very end of the tests run, after closing the Selenium session
  after: function(done) {
    // run this only for the local-env
    if (this.isLocal) {
      // start the local server
      App.stopServer(function() {
        // shutting down
        done();
      });
    } else {
      done();
    }
  },

  // This will be run before each test suite is started
  beforeEach: function(browser, done) {
    // getting the session info
    browser.status(function(result) {
      console.log(result.value);
      done();
    });
  },

  // This will be run after each test suite is finished
  afterEach: function(browser, done) {
    console.log(browser.currentTest);
    done();
  }
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值