Software systems to innovate and grow

End to End Testing Angular 2, A Complete Guide (Part 2)

By Engineering Team May 29, 2017 10 mins read

Alright, time to take end to end testing to the next level.

If you’re new to end to end testing, our previous article is a good place to start. It will help you understand why you need e2e testing and how you can get started.

This article takes things to the next level. We’ll talk about –

  • Different end to end testing frameworks and which one you should choose.
  • Reducing test rigidity and flakiness using the Page Object model design pattern.
  • Protractor’s element explorer for playing around and debugging.

We also have a simple demo application for you to play with.

Moving forward we’re assuming you’re already familiar with Protractor’s syntax. If not, have a look at Protractor’s API.

Angular End to End Testing – Quick Recap

So much has changed since we wrote the last article. Donald Trump became the president and Angular went from v2 to v4.

What hasn’t changed is that we still need to test our applications. End to end tests are still a great way to test our application as a whole.

End to end testing is black box testing. That means that the tests don’t know anything about how we’ve written code. They are independent.
They simulate a real user going through your application.

Note: End to End Tests vs Unit Tests

The good part about end to end tests is that we can test the application as a whole. We can ensure that all the components are working together as expected.

The bad part is we can’t pinpoint the source of a failed test. End to end tests aren’t good at pinpointing the problem.

That’s why e2e tests aren’t a substitute for unit tests. If you had to pick one of two, pick unit tests.

Demo Application

We’ve put together a demo application for you. We built it with Angular CLI using Angular v4.

If you’ve followed along, you should see the coffee shop.

end to end testing angular

This simple app allows you to order a coffee. When you click on any one of the options (Espresso, Cappuccino, etc.), the app displays a status message. You can also choose to cancel you order if it isn’t ready.

end to end testing angular

After 2 seconds, your coffee is ready. You can click on the collect order button to collect your coffee and then order another one.

The buttons to order another coffee are disabled when your order is ready. Once you collect your order, you can order another coffee.

end to end testing angular 2

Note: Our barista can only make one coffee at a time. And he doesn’t like starting the next order till you collect the one that’s ready. So you need to be a bit patient if you’re going there with friends ;).

You can find the end to end tests for this application in the e2e folder. We’ll talk more about the test later.

Angular End to End Testing Challenges

Most people don’t write end to end tests. Heck, most developers don’t write tests at all. Many times it’s because writing tests is hard. You need to set up the testing tools and go through lines and lines of clunky and ugly code.

Oh, and you need discipline – lots of it!

But those aren’t the only struggles. If you’ve ever written end to end tests, you might have faced problems in one of these areas –

  • Running the WebDriver – dealing with the binaries and browser instances can be a challenge.
  • Difficulty writing tests – as the size of your application and team increases, you release more code. A larger codebase means there are more moving parts. Writing and maintaining tests that are useful can be a challenge.
  • Slowness and flakiness – end to end tests are the slowest tests you can run (compared to unit and integration tests). They are also very fragile. If anything (and I mean anything) changes, these tests are usually the first to break.

Our goal is to make your job writing tests a whole lot easier.

Picking an End to End Testing Framework

There is no limit to the number of frameworks/tools/libraries out there. As a developer, it can be harder to pick a testing framework than to write the tests themselves. Let’s make your choice easier.

1. Nightwatch

Nightwatch is the new kid on the block.

It’s a custom implementation of the W3C webdriver. The W3C webdriver allows programs to instruct the behavior of a web browser. That’s how end to end testing frameworks work in general.

Nightwatch has great documentation and is easy to set up. It has frequent version releases and a decent community around it. It’s definitely a good tool to use for end to end testing.

Nightwatch is not Angular-specific. You can use it with any stack.

2. Protractor

Protractor is the de facto end to end testing framework for Angular. Its built for Angular. That means you’ll have an easier time with setup and testing.

Protractor is a wrapper around WebdriverJS (an implementation of the Selenium webdriver). That means that protractor extends all WebdriverJS features.

One of the most Angular-specific things about protractor is automatic waiting. This means that protractor will wait for pending tasks before running your tests.

3. Webdriver.io

Webdriver.io does pretty much what the other two frameworks do. It makes end to end testing easier.

The difference is that Webdriver.io is more flexible and easily extendable. It’s used under the hood of other frameworks including Spectron, Chimp, and CodeceptJS.

Verdict

After weighing the pros and cons of these frameworks, we recommend Protractor. Protractor’s Angular-specific support, large community, and active contributions make it a great choice.

Consider Webdriver.io if you want more control over the testing framework itself. Keep in mind, in most cases, it will be overkill.

Pick one and go with it!

Regardless of the framework you use, your application will be better of with end to end tests.
For a more detailed comparison of these frameworks, you can have a look at this comparison chart. It compares these frameworks across several variables.

Best Practices for Writing End to End Tests

Let’s address some of those challenges we mentioned above.

Luckily, the framework takes away the setup challenge. All three frameworks keep you far away from the browser binaries and other setup drama.

What’s left is to make testing easier and reduce flakiness. We can achieve that by using the page object model and organizing our code better.

1. Page Object Model

Before we explain what this design pattern is, let’s look at an example without it.

Not very readable is it?

There’s no way to tell that element(by.css('.well h4')) refers to a status heading. Sure, we could add an id and have element(by.css('#status-heading'')).

But, what would we do if the new designer changed the id to status-header?

We would have to go in and update all the tests!

Now, let’s use the page object model pattern for the same tests. Here’s what the test file looks like.

And here’s what the page object file looks like.

Doesn’t that look so much better?

The page object model design pattern makes the tests more readable. It also extracts code related to element selection and actions. We can reuse the extracted methods in many test cases.

To update a selector or action, we only need update the associated method. Without this design pattern, we’d have to update the selector method in each test case.

This flexibility makes our code a lot more maintainable.

2. Folder Structure

The point of a good folder structure is to make it easy to locate files. We don’t want to spend five minutes looking for the test file when we’re writing our tests.

All our test are in the e2e folder. We’ve grouped each spec file with it’s corresponding page object model into a folder.

The folder name corresponds to the page name. Eg. tests for the home page will be in the home folder. The file names also correspond to the name of the page we’re testing.

We add the .e2e-spec.ts suffix to our spec files. Eg. the spec file for the home page is home.e2e-spec.ts. We use the .po.ts suffix for the page object model files. Eg. the page object model for the home page tests is home.po.ts.

Our folder structure should end up looking something like this.

3. Readable Methods

Did you notice how readable the tests were in the example above?

One glance at the code and we know what the test does.

It’s important to keep your tests this way. Extract all the selector logic into the page object model and keep the spec file as readable as possible.

If a test requires too many steps, then extract them into one method.

A good folder structure and readable code make end to end testing a whole lot easier. The page object model design pattern itself takes care of a lot of the pain.

There’s a lot more you can do to make your end to end tests cleaner. Have a look at this styleguide if you’re looking for something more in-depth.

Protractor’s Element Explorer

Protractor’s Element Explorer allows us to play around with the DOM using a CLI. It allows us to run Protractor’s methods on a browser instance. Then, we observe the browser’s behavior and output.

Let’s set up the CLI.

Now we need to start up our demo application (link to repo above).

Finally, we need to start the CLI for Protractor in a new Terminal window.

Now, we can play with the browser using Protractor’s API. Let’s start with something simple.

If you’ve followed along so far, you should have an output that looks like this.

Protractor Element Explorer Output

end to end testing angular

To quit the CLI, you can type in .exit and Protractor will close the controller browser instance and exit the CLI.

Have a look at Protractor’s API. It has a lot more selectors and methods for you!

Conclusion

We’ve got a solid understanding of end to end tests and their importance. Once again, end to end tests are NOT a replacement for unit tests.

After comparing end to end frameworks we selected Protractor. Its Angular-specific features makes testing our Angular application easier.

Finally, we covered the page object model design pattern. It makes our tests much cleaner and more maintainable.

You are now ready to write some end to end tests in your application. You can start off in the demo application. Check if the buttons are disabled once the user orders a coffee.

P.S. Saucelabs

If you’ve got CI/CD in your architecture, kudos to you! You can make end to end tests a part of your build process.

Services like Saucelabs and Browserstack allow you to run end to end (and even unit tests) on the cloud. You can run your tests on a wide array of devices, operating systems, and browsers. You can also record videos, take screenshots and see what users would see.