Testing AngularJS Apps with Protractor

   Angular
Test your Angular apps with Protractor

Do the words “automated” and “tests” make you cringe a little?

Creating automated tests for an application isn’t the most glamorous of tasks. Sure, it can be tedious and requires a lot of work initially, but establishing a good workflow for development and testing is important and putting test creation on the back burner is easy. If you happen to not have a dedicated tester, it doesn’t take much to fall behind on testing. However, once a good workflow is established, automated tests can save time in your overall testing effort and help ensure the stability of your app.

And, thankfully, testing frameworks that make the process a little easier are plentiful. Let’s take a look at testing the functionality of your Angular app specifically with Protractor. If you have used Selenium and Selenium-Webdriver for creating automated tests then you will be familiar with how Protractor works. Protractor tests can run on both regular and headless browsers like PhantomJS1 and emulates user actions on the application. This particular testing framework is built with AngularJS apps in mind and can test elements that are specific to the development structure. It is also smart enough to automatically wait for pending tasks to finish.

If you are a fan of behavior driven development, Protractor supports Jasmine, Mocha, Cucumber, and adapters for custom frameworks. Jasmine and Mocha both have an active development community and great support. Documentation for Cucumber is currently a little more limited, but its development community is actively updating the codebase with bug fixes and new features – worth checking out.

Protractor comes with Jasmine as the default framework, so we will use that in our examples. Before installing Protractor, make sure you have Node.js and the Java Development Kit installed.

Getting Started

To install protractor run the following in your terminal:

npm install -g protractor

In another terminal window or tab, update and start the Selenium Server. This is needed to run tests locally in a browser.

webdriver-manager update  
webdriver-manager start

Create a Config File

Now that the Selenium Server is up and running, you can create your tests. You will first need to create a tests.conf.js file. This stores each option needed to run tests like timeouts, test directory sources, and suites.

exports.config = {  
    seleniumAddress: 'http://localhost:4444/wd/hub',  
    getPageTimeout: 60000,  
    allScriptsTimeout: 500000,  
      
    specs: ['*.spec.js'],  
  
    suites: {  
        suite1: 'spec/suite1/*.spec.js',  
        suite2: 'spec/suite2/*.spec.js'  
    },  
  
    baseURL: 'http://localhost:8080/',  
    framework: 'jasmine',  
};

You can change the folder structure of your specs, but this gives you an example of how the configuration file can look. What do each of these options mean?

seleniumAddress: Where to talk to the Selenium Server instance that is running on your machine. This can be verified by checking the logs in the terminal window that is running the server.

getPageTimeout: Time to wait for the page to load

allScriptsTimeout: Time to wait for page to synchronize. More information on timeouts can be found in Protractor’s wiki.

specs: Location of specs to run

suites: Organized directories for suites – run with –suite=suite1,suite2

baseURL: Main URL to hit for testing. This is helpful if there is only one, root URL.

framework: Where you specify the type of framework to use with Protractor

Create a Spec File

The next step is creating a spec, where the test is defined. Below is an example:

//test.spec.js

describe('Protractor Test', function() {  
  var addField = element(by.css('[placeholder="add new todo here"]'));  
  var checkedBox = element(by.model('todo.done'));  
  var addButton = element(by.css('[value="add"]'));  
  
  it('should navigate to the AngularJS homepage', function() {  
    browser.get('https://angularjs.org/'); //overrides baseURL  
  });  
    
  it('should show a search field', function() {  
    browser.sleep(5000); //used just to give you enough time to scroll to todo section  
    addField.isDisplayed();  
  });  
    
  it('should let you add a new task ', function() {  
    addField.sendKeys('New Task');  
    addButton.click();  
    browser.sleep(5000); //used just to see the task list update  
  });  
});

This spec first defines each element it needs to interact with. Then it navigates to the AngularJS homepage, checks for the existence of a search field, and adds a new task. This is a basic example, but Protractor provides a robust set of locators for interacting with your application. You can view the full list in Protractor’s API doc.

Run Your Test

Now that you have a configuration and spec written, it’s time to run the test. In your terminal, navigate to the directory where the configuration file is located and run the following command.

protractor tests.conf.js

You will see a browser window pop up and the test will execute – Firefox by default. You can watch the output of steps in your terminal window and, after the test is done running it will show as “passed” in terminal.

Wrapping Up

Protractor makes creating E2E tests simple and it’s easy to get a suite up and running for your application. For more information on Protractor, you can head to the official docs. A few helpful docs are included below to help you get started with your automation project:

Final notes: Protractor supports both Jasmine 1.3 and 2.0, but uses 1.3 by default. And there are reports of PhantomJS crashing with Protractor tests.

* * *

Featured “Angular JS Protractor” image at beginning of article provided by John Fischer under cc license


Like What You See?

Got any questions?