Home » JavaScript » Angular.js » Quick Start: End-to-End Testing With Protractor

About Todd Horn

Todd Horn
Todd Horn is a Keyhole Software developer based in St. Louis, MO with experience in .Net, JavaScript, Java, and PHP. Todd has been involved with software projects in the telecom, manufacturing, insurance, and non-profit industries, including background in HR, Payroll, Benefits, and Insurance systems. When not at work, he enjoys spending time with his wife and kids, helping with boy scouts, hiking, and volunteering for the Ozark Trail Association.

Quick Start: End-to-End Testing With Protractor

As AngularJS applications become more complex, manual testing becomes unreliable and repetitive. Unit Testing is a great start for testing the code, but eventually End-to-End testing is needed for better coverage.

A great tool to use for this is Protractor, which is an end-to-end test framework for AngularJS applications. In this blog, we’ll introduce the benefits of Protractor and give you the steps needed to get started.

Introduction to Protractor

Protractor runs tests against your application using a browser, as a user would, and interacts with the UI, similar to how you would test workflows in QA. It allows for better testing interaction between components than unit testing can provide, making sure everything gets tested the same way each time, and eliminating the repetitiveness that large applications require for testing.

Based on the Node.js program, Protractor uses WebDriverJs and Selenium to control the browser and simulate user interaction. Jasmine is the default testing framework, but you could also use Mocha or a custom framework of your choice.

A test file, or spec, includes a describe block, and has it blocks that contain the requirements that you want to test. it blocks are made of commands and expectations.

Commands tell Protractor to do something, such as go to a page, get an element, or click on a button. Expectations tell Protractor to assert something about the application’s state, such as a value of a field, a count, or the current URL. If any Expectation within an it block fails, the runner marks the it block as Failed and continues on to the next block.

Setup for Protractor

Run npm on the command line to install Protractor globally:

protractor1

This will install the protractor command line tool, the webdriver-manager command line tool, and the Protractor API library. You can check the version with:

protractor2

To download the necessary binaries for webdriver-manager and make sure they are up to date, run:

protractor3

To start up an instance of a Selenium Server, run:

protractor4

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

Project File and Folder Structure

You should set up your end-to-end tests in a way that best fits the structure of your project. Some prefer a separate testing project, while others keep it with the code in a test\e2e\ folder that matches your code structure, separate from your unit tests. This will make finding your tests and locating what you are testing easier.

Here is an example of how you could set up your project structure:

protractor5

In this example I have a test\e2e\ folder that contains my Protractor tests. The protractor.config.js file is in the test folder. All the specs (test files) are in the e2e folder, broken up and organized in folders where it makes sense. The pages folder will have my page objects.

Writing A Basic Test

To write a test, you will need a spec file and a configuration file.

Here is an example of a spec for Keyhole’s MockOla application:

protractor6

This spec can be used to test the MockOla home page, to make sure it loads, and that the 5 default mocks are shown. The describe and it syntax are from Jasmine. The beforeEach function will cause whatever code is included in it to run before each it block. browser is a global created by Protractor and browser.get will navigate to the given page. element.all is used to find HTML elements on the page.

The by object creates Locators, which tells Protractor how to find DOM elements. The most common are by.css, by.id, by.model, and by.binding. by.repeater is used above.

More about Locators

Here is an example of a config file:

protractor7

This config file tells Protractor to use Jasmine (framework), the url for selenium (seleniumAddress), where the test files are located (specs), and to use the Chrome browser (capabilities). It also has test suites defined, which allow you to group your tests together to run as needed. The last section, onPrepare, will run once Protractor is ready, but before the tests are executed.

In my example, it tells Protractor to use jasmine-spec-reporter, giving you a more detailed display of the test results.

Working with Spec and Config Files

Running Tests

To run the tests on the command line, use:

protractor8

You can also specify the test suite with the suite option:

protractor9

Here is what the results will look like using jasmine-spec-reporter:

protractor91

While the tests are running, you will see the browser open, run through all the tests, and then close.

The jasmine-spec-reporter is used above to give a more detailed output than the standard periods and failures seen below:

protractor92

Page Objects

Page Objects are a little more advanced technique that can help you write cleaner tests by encapsulating information about the elements on your application page.

In many cases if the UI changes, you just have to update the page object instead of the spec. It also helps reduce the number of places you will need to update when refactoring and makes the spec code much more sustainable and readable.

Here’s an example of a page object for an account registration:

protractor93

All the elements that are used in the test are assigned to properties, and some reusable set functions are created.

And here is the spec file that goes with the account registration page object:

protractor94

The RegistrationPage page object is brought in using require and a new registrationPage instance is created. Then you can use the properties (instead of element(by.()) ) and set functions defined from the registration page object.

This makes the JavaScript much more readable.

More on Page Objects

Let’s run our account registration tests and see that they pass:

protractor95

Success!

Final Thoughts

Thanks for following along with this blog, I hope you found it helpful in getting to know Protractor. Feel free to leave any questions or comments below. Also make sure to check out some more information available:

Do you want to know how to develop your skillset to become a Web Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. Building web apps with Node.js

2. HTML5 Programming Cookbook

3. CSS Programming Cookbook

4. AngularJS Programming Cookbook

5. jQuery Programming Cookbook

6. Bootstrap Programming Cookbook

 

and many more ....

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Want to take your WEB dev skills to the next level?

Grab our programming books for FREE!

Here are some of the eBooks you will get:

  • PHP Programming Cookbook
  • jQuery Programming Cookbook
  • Bootstrap Programming Cookbook
  • Building WEB Apps with Node.js
  • CSS Programming Cookbook
  • HTML5 Programming Cookbook
  • AngularJS Programming Cookbook