自動エンドツーエンドテスト-Protrator Tutorial

14367 ワード

Basic


Protractor is an end-to-end test framework for AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.
Test Like a User
Protractor is built on top of WebDriverJS, which uses native events and browser-specific drivers to interact with your application as a user would.
For AngularJS Apps
Protractor supports Angular-specific locator strategies, which allows you to test Angular-specific elements without any setup effort on your part.
Automatic Waiting
You no longer need to add waits and sleeps to your test. Protractor can automatically execute the next step in your test the moment the webpage finishes pending tasks, so you don’t have to worry about waiting for your test and webpage to sync.

Setup


Use npm to install Protractor globally with:
npm install -g protractor

This will install two command line tools,  protractor  and  webdriver-manager . Try running  protractor --version  to make sure it's working.
The  webdriver-manager  is a helper tool to easily get an instance of a Selenium Server running. Use it to download the necessary binaries with:
webdriver-manager update

Now start up a server with:
webdriver-manager start

This will start up a Selenium Server and will output a bunch of info logs. Your Protractor test will send requests to this server to control a local browser. You can see information about the status of the server at http://localhost:4444/wd/hub.

Write a test


Open a new command line or terminal window and create a clean folder for testing.
Protractor needs two files to run, a spec file and a configuration file.
Let's start with a simple test that navigates to the todo list example in the AngularJS website and adds a new todo item to the list.
Copy the following into  todo-spec.js :
describe('angularjs homepage todo list', function() {
  it('should add a todo', function() {
    browser.get('https://angularjs.org');

    element(by.model('todoList.todoText')).sendKeys('write first protractor test');
    element(by.css('[value="add"]')).click();

    var todoList = element.all(by.repeater('todo in todoList.todos'));
    expect(todoList.count()).toEqual(3);
    expect(todoList.get(2).getText()).toEqual('write first protractor test');

    // You wrote your first test, cross it off the list
    todoList.get(2).element(by.css('input')).click();
    var completedAmount = element.all(by.css('.done-true'));
    expect(completedAmount.count()).toEqual(2);
  });});

The  describe  and  it  syntax is from the Jasmine framework.  browser  is a global created by Protractor, which is used for browser-level commands such as navigation with  browser.get .

Configuration


Now create the configuration file. Copy the following into  conf.js :
exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['todo-spec.js']};

This configuration tells Protractor where your test files ( specs ) are, and where to talk to your Selenium Server ( seleniumAddress ). It will use the defaults for all other configuration. Chrome is the default browser.

Run the test


Now run the test with:
protractor conf.js

You should see a Chrome browser window open up and navigate to the todo list in the AngularJS page, then close itself (this should be very fast!). The test output should be  1 test, 3 assertions, 0 failures . Congratulations, you've run your first Protractor test!

Tutorial


This is a simple tutorial that shows you how to set up Protractor and start running tests.

Prerequisites

Protractor is a Node.js program. To run, you will need to have Node.js installed. You will download Protractor package using npm, which comes with Node.js. Check the version of Node.js you have by running  node --version . It should be greater than v0.10.0.

By default, Protractor uses the Jasmine test framework for its testing interface. This tutorial assumes some familiarity with Jasmine, and we will use version 2.3.

This tutorial will set up a test using a local standalone Selenium Server to control browsers. You will need to have the Java Development Kit (JDK)installed to run the standalone Selenium Server. Check this by running  java -version  from the command line.

Setup Use npm to install Protractor globally with: npm install -g protractor This will install two command line tools,  protractor  and  webdriver-manager . Try running  protractor --version  to make sure it's working. The  webdriver-manager  is a helper tool to easily get an instance of a Selenium Server running. Use it to download the necessary binaries with: webdriver-manager update Now start up a server with: webdriver-manager start This will start up a Selenium Server and will output a bunch of info logs. Your Protractor test will send requests to this server to control a local browser. Leave this server running throughout the tutorial. You can see information about the status of the server at  http://localhost:4444/wd/hub . Step 0 - write a test Open a new command line or terminal window and create a clean folder for testing. Protractor needs two files to run, a spec file and a configuration file.  Let's start with a simple test that navigates to an example AngularJS application and checks its title. We’ll use the Super Calculator application at http://juliemr.github.io/protractor-demo/. Copy the following into spec.js: // spec.jsdescribe('Protractor Demo App', function() {   it('should have a title', function() {     browser.get('http://juliemr.github.io/protractor-demo/');     expect(browser.getTitle()).toEqual('Super Calculator');   });}); The  describe  and  it  syntax is from the Jasmine framework.  browser  is a global created by Protractor, which is used for browser-level commands such as navigation with  browser.get . Now create the configuration file. Copy the following into conf.js: // conf.jsexports.config = {   framework: 'jasmine',   seleniumAddress: 'http://localhost:4444/wd/hub',   specs: ['spec.js']} This configuration tells Protractor where your test files ( specs ) are, and where to talk to your Selenium Server ( seleniumAddress ). It specifies that we will be using Jasmine for the test framework. It will use the defaults for all other configuration. Chrome is the default browser. Now run the test with protractor conf.js You should see a Chrome browser window open up and navigate to the Calculator, then close itself (this should be very fast!). The test output should be  1 tests, 1 assertion, 0 failures . Congratulations, you've run your first Protractor test! Step 1 - interacting with elements Now let's modify the test to interact with elements on the page. Change spec.js to the following: // spec.jsdescribe('Protractor Demo App', function() {   it('should add one and two', function() {     browser.get('http://juliemr.github.io/protractor-demo/');     element(by.model('first')).sendKeys(1);     element(by.model('second')).sendKeys(2);     element(by.id('gobutton')).click();     expect(element(by.binding('latest')).getText()).         toEqual('5'); // This is wrong!   });}); This uses the globals  element  and  by , which are also created by Protractor. The  element  function is used for finding HTML elements on your webpage. It returns an ElementFinder object, which can be used to interact with the element or get information from it. In this test, we use  sendKeys  to type into  <input> s,  click  to click a button, and  getText  to return the content of an element. element  takes one parameter, a Locator, which describes how to find the element. The  by  object creates Locators. Here, we're using three types of Locators: by.model('first')  to find the element with  ng-model="first" . If you inspect the Calculator page source, you will see this is  <input type=text ng-model="first"> . by.id('gobutton')  to find the element with the given id. This finds  <button id="gobutton"> . by.binding('latest')  to find the element bound to the variable  latest . This finds the span containing  {{latest}} Learn more about locators and ElementFinders. Run the tests with protractor conf.js You should see the page enter two numbers and wait for the result to be displayed. Because the result is 3, not 5, our test fails. Fix the test and try running it again. Step 2 - writing multiple scenarios Let's put these two tests together and clean them up a bit. Change spec.js to the following: // spec.jsdescribe('Protractor Demo App', function() {   var firstNumber = element(by.model('first'));   var secondNumber = element(by.model('second'));   var goButton = element(by.id('gobutton'));   var latestResult = element(by.binding('latest'));   beforeEach(function() {     browser.get('http://juliemr.github.io/protractor-demo/');   });   it('should have a title', function() {     expect(browser.getTitle()).toEqual('Super Calculator');   });   it('should add one and two', function() {     firstNumber.sendKeys(1);     secondNumber.sendKeys(2);     goButton.click();     expect(latestResult.getText()).toEqual('3');   });   it('should add four and six', function() {     // Fill this in.     expect(latestResult.getText()).toEqual('10');   });}); Here, we've pulled the navigation out into a  beforeEach  function which is run before every  it  block. We've also stored the ElementFinders for the first and second input in nice variables that can be reused. Fill out the second test using those variables, and run the tests again to ensure they pass. Step 3 - changing the configuration Now that we've written some basic tests, let's take a look at the configuration file. The configuration file lets you change things like which browsers are used and how to connect to the Selenium Server. Let's change the browser. Change conf.js to the following: // conf.jsexports.config = {   framework: 'jasmine',   seleniumAddress: 'http://localhost:4444/wd/hub',   specs: ['spec.js'],   capabilities: {     browserName: 'firefox'   }} Try running the tests again. You should see the tests running on Firefox instead of Chrome. The  capabilities  object describes the browser to be tested against. For a full list of options, see the reference config file. You can also run tests on more than one browser at once. Change conf.js to: // conf.jsexports.config = {   framework: 'jasmine',   seleniumAddress: 'http://localhost:4444/wd/hub',   specs: ['spec.js'],   multiCapabilities: [{     browserName: 'firefox'   }, {     browserName: 'chrome'   }]} Try running once again. You should see the tests running on Chrome and Firefox simultaneously, and the results reported separately on the command line. Step 4 - lists of elements Let's go back to the test files. Feel free to change the configuration back to using only one browser. Sometimes, you will want to deal with a list of multiple elements. You can do this with  element.all , which returns an ElementArrayFinder. In our calculator application, every operation is logged in the history, which is implemented on the site as a table with  ng-repeat . Let's do a couple of operations, then test that they're in the history. Change spec.js to: // spec.jsdescribe('Protractor Demo App', function() {   var firstNumber = element(by.model('first'));   var secondNumber = element(by.model('second'));   var goButton = element(by.id('gobutton'));   var latestResult = element(by.binding('latest'));   var history = element.all(by.repeater('result in memory'));   function add(a, b) {     firstNumber.sendKeys(a);     secondNumber.sendKeys(b);     goButton.click();   }   beforeEach(function() {     browser.get('http://juliemr.github.io/protractor-demo/');   });   it('should have a history', function() {     add(1, 2);     add(3, 4);     expect(history.count()).toEqual(2);     add(5, 6);     expect(history.count()).toEqual(0); // This is wrong!   });}); We've done a couple things here - first, we created a helper function,  add . We've added the variable  history . We use  element.all  with the  by.repeater  Locator to get an ElementArrayFinder. In our spec, we assert that the history has the expected length using the  count  method. Fix the test so that the second expectation passes. ElementArrayFinder  has many methods in addition to  count . Let's use  last  to get an ElementFinder that matches the last element found by the Locator. Change the test to:   it('should have a history', function() {     add(1, 2);     add(3, 4);     expect(history.last().getText()).toContain('1 + 2');     expect(history.first().getText()).toContain('foo'); // This is wrong!   }); Since the Calculator reports the oldest result at the bottom, the oldest addition (1 + 2) be the last history entry. We're using the  toContain  Jasmine matcher to assert that the element text contains "1 + 2". The full element text will also contain the timestamp and the result.  Fix the test so that it correctly expects the first history entry to contain the text "3 + 4". ElementArrayFinder also has methods  each ,  map ,  filter , and  reduce  which are analogous to JavaScript Array methods. Read the API for more details.