Introduction to Angular Testing - Here's how to get started

Daniel Kreider
Daniel Kreider
Published on July 17th at 7:00am
  • Angular Testing

Who else wants to learn how to properly test an Angular application - in half the time?

Say!

Why does testing Angular applications have to be so complicated?

Where do you start when you have to write tests for your Angular application?

What are the first steps?

What should you test?

Not sure how to mock a dependency? Or if you should just inject it directly?

And what Angular testing tools should you use?

What's Karma anyway?

And how do I use Jasmine?

Or is Mocha better?

Should you test everything? Are unit or integration tests better? What about smock or E2E tests?

Getting started with Angular testing can be overwhelming - it's hard to know where to focus your limited time to get the best ROI.

And that, my friend, is why I've written this article. I'm going to help point you in the right direction and get you started with Angular testing.

This will be a quick but thorough introduction to the basic theory and principles you need to get started with Angular testing. And I'll also answer some common questions that developers ask when they first start testing an Angular application.

So...

3...

2..

1.

LET'S GO!

Testing lingo you need to know before we get started

Jasmine is a testing framework that is included in every Angular project created with the CLI, unless you specifically opt out.

It's got all kinds of features like asynchronous testing, the ability to use 'spies' for implementing test doubles and more.

Assuming we have a simple helloWorld function we could test it with Jasmine like this.

describe('Hello world', function() {
  it('says hello', function() {
    expect(helloWorld()).toEqual('Hello world!');
  });
});

Karma is the default test runner.

It takes the Jasmine test files in your Angular project and runs them in the browser, checking and displaying the results of your various tests. You can learn more about how it works here.

  • Unit

A unit is the smallest piece of an application that can still be tested.

In most cases, this would be the functions inside your components, services, pipes, etc...

  • Unit Tests

A unit test is a test for the smallest, testable pieces of an Angular application.

  • Integration Tests

An integration test is where we combine an object and it's dependencies and test how they cooperate together, instead of mocking the dependencies like we would do in a unit test.

  • E2E Testing

End-to-end (E2E) testing is when we use Protactor to run a series of step tests via browser automation. This is to simulate a real-world user using and clicking around in our application.

Angular testing theory that will let you get started with a BANG! 💥 💥 💥

If you apply this section of the article when testing your Angular applications you'll become a testing whiz, I promise. 😉

When we create a unit of code, it's usually a function inside our component, service, or another common piece of our Angular application.

And then we open our browser, let it refresh and manually test to make sure things are working like expected.

But what if we could automate the testing process? While still being confident that our code is bug-free?

That's where unit tests help us and give us 3 significant advantages over manually testing.

First, after coding a unit, we can create unit tests that make sure our new unit of code is behaving properly without having to manually test.

The second advantage we get from testing is a bug-net for the future in case we ever come back to modify this unit. Most production bugs hide in old features that we coded awhile ago and don't test anymore. As we add new features we change or modify our Angular code a bit and test the new feature manually but never check an old feature to make sure that it wasn't broken with the changes to a dependency that your old code depends on. If we had written good tests, they would have caught these bugs before our code hit production.

The third advantage we get when writing unit tests is that it forces us to become a better developer and write better code.

And please, remember to be thorough in your testing. Good unit tests will check both the unsuccessful and successful scenarios.

If unit testing is hard then it means something is wrong with your code, not the test. For example, if you have to many tests for a single objects it indicates that your object is too large and helps you properly split your code into smaller modules.

Which leads us to...

Isolation

What is isolation?

Isolation is the act of replacing the dependencies of an object with fake objects like mocks, stubs and spies.

Good unit tests are self-reliant, independent and autonomous. They should not expect a specific order to run in. Or depend on a value from another test.

If your unit tests are tightly coupled then you're trying to build solid tests on sand.

Another advantage of isolation is that it keeps the tests much faster.

So, when you're writing unit tests for your Angular application make sure you mock first level dependencies. Second level dependencies should never be known about.

Clean unit tests are small.

Clean unit tests are understandable.

Clean unit tests know as little as possible about the object's dependencies.

Clean unit tests are reusable.

So, what should you test?

I also talk about this in another article on What should I test? Here's how to get the best ROI.

But for a quick intro, keep in mind there are 3 things that you can test.

  1. Initialization - Object creation.
  2. Methods - Generally, you should only test public methods or what's also known as the public API of our object.
  3. Events - How does our object respond to events like an observable, promises and DOM events.

Generally, testing your object's methods are the best place to start testing.

The best ROI you can get with minimum effort will be writing unit tests for your services and other shared pieces of the project.

But what should you NOT waste time testing?

This might turn controversial but I do not recommend testing the DOM.

Most DOM tests are as brittle as sun-baked mozzarella cheese.

Conclusion

Learning how to write good tests is like learning how to write good code.

It just takes practice and time.

It took me years to become a proficient coder and I don't expect to turn into a super-hero tester overnight.

But if you follow the basic testing theory and principles that I've given you in this article, you can expect great results.

Questions or comments? Don't hesitate to reach out.

signature

Angular Consultant

P.S. - If you're like me and like to skim read then here's what this article is about.

  • How to get the best ROI with minimum effort when testing your Angular app.
  • The 3 points of an application that can be unit tested.
  • Three reasons why you should be writing unit tests for your Angular application.
  • How to spot a clean unit test.