Intro to Testing

Projected Time

About 2 hours

Prerequisites

Motivation

Testing makes your code better, lets you work faster, and can actually be fun!

Which companies use automated testing?

Objectives

Apprentices will be able to:

Outline

Materials

Lesson

This slideshow follows along with this Testing/TDD lesson.

Why Test?

Everyone probably tests their code manually as they write it. But this lesson is about automated testing where you write some special code, the test code, that verifies the behavior of your “regular code” aka production code.

QA

Isn’t testing the QA’s job? Some organizations might have dedicated QA staff. However, who wants to wait until they test your code to find bugs? Wouldn’t it be great to find them yourself first?

And there are other advantages too…

Pros

Cons

Types of Tests

Naming can get tricky so here are some helpful starting point definitions.

Unit Tests

This term has reasonable consensus. These tests exercise the smallest pieces of your code, ideally in total isolation from the rest. In an object-oriented language, it might test a class. In a functional language it will likely test a function.

But what if your class uses another class? And what if your function calls another function? We won’t cover them today but mocking can help with these issues.

Integration Tests

This term does not have much consensus on its meaning, but it generally refers to tests that test two (or more) units working together. It could be two classes/objects or a function that calls another function. It can also having your API call another real API, which is quite different (and slower) than a unit test. But some of the ideas are the same.

As you might notice, these attributes aren’t that specific. That’s because they are highly dependent on what flavor of integration test you’re writing. Is it almost like a unit test against two or more units with mocking, etc? Or is it closer to UI Test below, such as an API calling another real API which can go down for lots of reasons.

However, this balance makes them a good place to start if you don’t know what kind of test to write.

UI Tests / User Acceptance Tests / Browser Tests / End-to-End Tests

Sadly, these go by even more names than listed but, in general, these are the highest level of all tests and test an entire page in a real browser or real mobile app. They can even imitate a user journey as a flow through several pages (e.g. login, create profile).

Load Testing

We won’t go into these much here, but load testing is essential testing that your code can handle an increased amount of input or activity. Lets say you have a website that works when you have one user, what happens when you have 10,000 users? If you have a database that is working with three rows, what happens when you have thousands? You want to make sure that you program still works reliably regardless of user volume.

How to choose?

There is no right answer. You should try them all and see which you like best.

The Testing Pyramid source

A lot of people think having more unit tests is cheaper, easier, and gives a better return on investment in the long run. See for yourself.

Methodologies

Automated testing is relatively new compared to many practices and, as such, habits vary widely across teams and organizations. People can be quite opinionated about the practices that they follow. Try not to get hung up on all the disagreements.

Just remember that some tests are infinitely better than no tests. The rest is details.

Test-Driven Development (TDD)

If tests are helpful and help make your code stronger, some developers like to start with the tests first, before any code exists. That way they know they have testable code from the start.

const sum = function (a, b) {};

// this test will fail since the function doesn't even do anything yet!
describe('sum()', function () {
  it('adds the input numbers together', function () {
    expect(sum(1, 2)).toBe(3);
  });
});

Red-Green-Refactor

Even if you’re adding tests to existing code, it’s a great idea to write a failing test first. This can avoid the pitfall above of false confidence. It’s sometimes easy to accidentally write a test that will never fail but without realizing it.

Red Green Refactor source

This practice is nicknamed Red-Green-Refactor

No Code Exists

This is easy since you don’t have any code yet.

// implement this function to make the test pass:
// const sum = ...;

describe('sum()', function () {
  it('should add two numbers together', function () {
    expect(sum(1, 2)).toBe(3);
  });
});
Code Already Exists

You can do this if the code already exists by, say, commenting out the line doing the work you’re testing.

const sum = function (a, b) {
  return a + b; // TODO: comment this to make the test fail
};

describe('sum()', function () {
  it('should add two numbers together', function () {
    expect(sum(1, 2)).toBe(3);
  });
});

Outside-In vs. Inside-Out

Q: Where do you start adding tests? At the highest level (requesting a whole page) or at a tiny level, e.g. a single function? A: Neither way is better. You should try both and see.

Common Mistakes / Misconceptions

Read about these common antipatterns so you can avoid them.

Guided Practice

Let’s Write a Test!

Add some additional tests for this function:

const countWords = function (sentence) {
  return sentence.split(' ').length;
};

describe('countWords', function () {
  it('should count a single word', function () {
    expect(countWords('a')).toBe(1);
  });

  it('???', function () {});
});
Challenge

Try to find some input where the function gives the wrong result.

Independent Practice

What if instead of requirements for your code to be in written form, someone gave you a test spec that defined its exact behavior?

Try some JavaScript examples at https://www.codewars.com/

Challenge

Ping Pong Pairing

Ping Pong Pairing is a common technique when using TDD where each developer switches roles between test writer and code implementer. The first developer writes a test, then the second developer writes just enough code to make the test pass. Then the first developer writes another test, and so on.

Hints

Acceptance Testing

Users may be on many different web browsers so we need to test webpages for browser compatibility.

Other tests PageSpeed Insights Free tool by Google to test the speed of your website 10 Free UI Testing Tools Numerous online tools that you can use to test your website.

Check for Understanding

Form small groups and discuss: