JavaScript Testing

Who Am I

  • My name is Jedediah Smith
  • I love JavaScript, working with data, and organizing chaos.
  • I enjoy teaching, training, mentoring, and otherwise helping others with their code.
  • I work for CurbNTurf where we connect land owners and RVers
     
  • A Book I Am Writing: JedJS.com
  • Twitter: @jedsmith13
  • LinkedIn: https://www.linkedin.com/in/jedediahsmith

What are Tests

According to Wikipedia

A test is an assessment intended to measure a test-taker's knowledge, skill, aptitude, physical fitness, or classification in many other topics. A test may be administered verbally, on paper, on a computer, or in a predetermined area that requires a test taker to demonstrate or perform a set of skills.

https://en.wikipedia.org/wiki/Test_(assessment)

What are Tests

How about the Dictionary (or Google's equivalent)

 

1. a procedure intended to establish the quality, performance, or reliability of something, especially before it is taken into widespread use.

https://www.google.com/search?q=what+are+tests

What are Tests

The reason(s) I would write a test

 

  • Confidence
  • Confidence
  • Confidence

https://www.google.com/search?q=what+are+tests

Types of Tests

No Open-book Tests here

Types of Tests

  • In Production
  • In Beta
  • Manual
  • End To End (e2e)
  • Integration
  • Unit
  • Static
  • Regression, functional, system, sanity, smoke
    interface, etc...
  • Security, usability, load, etc...

Types of Tests

  • In Production (possibly your business or job)
  • In Beta
  • Manual
  • End To End (e2e)
  • Integration
  • Unit
  • Static

Sorted By Cost Per Test

High

Low

Advantages/Disadvantages

Advantages

  • No developer time
  • Maximum flexibility for developer and project
  • Tested by exact customer base

In Production

Disadvantages

  • Angry former customers
  • Late nights and weekends spent fixing bugs

Advantages/Disadvantages

In Beta

Advantages

  • No developer time
  • Fairly good sample of customer base
  • More sympathetic users

Disadvantages

  • Slow to deploy
  • Often requires paying customers (either in free usage or other)

Advantages/Disadvantages

Manual

Advantages

  • Can have very high confidence
  • Less developer training

Disadvantages

  • Slow
  • Boring
  • Easy to skip steps after repeated attempts
  • "It worked last time I tried it"

Advantages/Disadvantages

e2e

Advantages

  • High confidence
  • Tested similarly to how a user will use the site
  • Don't need holes in reality

Disadvantages

  • Slow
  • Can be complex to create
  • Can break on UI rework without code changes
  • Can be expensive if paying for 3rd-party APIs

Advantages/Disadvantages

Integration

Advantages

  • Simpler to write
  • Good confidence in the application
  • Faster then e2e

Disadvantages

  • Slower then Unit tests
  • Can be more complex then Unit tests
  • Can be expensive if paying for 3rd-party APIs
  • May need some mocking

Advantages/Disadvantages

Unit

Advantages

  • Quick
  • Can be simple to write
  • High confidence in functions/units

Disadvantages

  • Mocks add complexity
  • Doesn't test interactions between units

Advantages/Disadvantages

Static Tests

Advantages

  • Lightning fast
  • Basically free to write

Disadvantages

  • Only tests static code and structure

No Tests

Every Test

Where should we be?

Unfortunately, the answer is, that it depends.

Points to Consider

  • User base
  • Speed to delivery
  • Life expectancy
  • Rate features will be added after release
  • # of developer
  • Skill of developers
  • Complexity of app
  • Deployment processes (CI vs waterfall)
  • # of 3rd party integrations
  • Stability of code and APIs

No Tests

Every Test

Widely Used Library

Libraries that are depended on should be thoroughly tested. 

If you use an open source library that isn't tested as well as you would like, consider adding some to a PR for everyone's benefit.

No Tests

Every Test

Autonomous Car

Anything involving the safety of lives should be tested extensively from many different approaches.

No Tests

Every Test

Banking App

Anything involving finances should be thoroughly tested and not just for security vulnerabilities. People tend to get upset when their money disappears.

No Tests

Every Test

Large Enterprise Level App

The larger and the more complex the app the more you benefit from automated tests.

No Tests

Every Test

I am Learning React

If you are just creating a site to learn a new tech don't worry about tests, unless that is part of learning the new tech.

No Tests

Every Test

My App

If your app wasn't listed then it is probably in the middle somewhere.

?

No Tests

Every Test

CurbNTurf

We started with very few tests (read only what was pre-built in the scaffolding) until we had a somewhat stable API and we are now increasing our code coverage as we add or refactor features.

Where We Started

  • Testing API endpoints
  • A few e2e paths
  • Unit test helper functions
  • New features
  • More tests (as I learn how to write them)

Testing API Endpoints

Tool: Cypress

Setup: Using a Docker instance of the database with pre-populated fields and a separate instance of the server. Writing the tests was pretty simple with Cypress. The setup did take a bit of work to get the data database and to keep it up to date. It is also kind of slow already.

import * as usersJson from '../../fixtures/users.json';

const API_URL = Cypress.env('API_URL');
const users = usersJson as any;

describe('User API: Fetch', () => {
  it('if same user returns JSON, has hasCC field', () => {
    (cy as any)
      .loginByRequest(users.generic.email, users.generic.password)
      .then((authToken: string) => {
        cy.request({
          url: `${API_URL}/user/${users.generic.id}`,
          method: 'GET',
          headers: { Authorization: authToken },
        }).then(response => {
          expect(response.body).to.be.an('object');
          expect(response.body.email).to.not.be.undefined;
        });
      });
  });

  it('if not logged in returns JSON, does not have email', () => {
    cy.request({
      url: `${API_URL}/user/${users.generic.id}`,
      method: 'GET',
    }).then(response => {
      expect(response.headers['content-type']).to.include('application/json');
      expect(response.body).to.be.an('object');
      expect(response.body.email).to.be.undefined;
    });
  });
});

Example:

Tool: Cypress

Setup: Using a Docker instance of the database with pre-populated fields and a separate instance of the server. Writing the tests was much simpler then expected with Cypress. Used the same database setup as used for the integration tests.

A few e2e paths

  context('Handle Profile', () => {
    beforeEach(() => {
      (cy as any).loginByForm(users.generic.email, users.generic.password);
      cy.get('#profile-heading').click();
    });

    it('can update the user profile information', () => {
      cy.get('input[formcontrolname=firstName]').type(users.generic.firstName);
      cy.get('input[formcontrolname=lastName]').type(users.generic.lastName);
      cy.get('#user-profile-save-button')
        .click()
        .then(() => {
          // we should have visible response now
          cy.get('.toast-title')
            .should('be.visible')
            .and('contain', 'User Updated');
        });
    });
  });

Example:

Other Advantages of Tests

  • Can be used to identify difficult code
  • Can be used to guide the development
  • Can encourage better coding practices

Many of the developers I read, listened to, or watched mentioned these as primary reasons why everyone has to write tests. I see these as secondary benefits that can be had other ways.

Some False Statements about Tests

  • Written tests lead to bug-free code
  • 100% code coverage leads to bug-free code
  • If we write tests we don't have to do manual testing

Your tests only cover bugs you already identified.

Some Other Items

  • e2e and integration are better for refactoring
  • Unit test are quick to run so they are better for sections of code needing thorough testing
  • Cypress allows running smaller groups of tests easily

Your tests only cover potential bugs you already identified.

JavaScript Testing

By Jedediah Smith

JavaScript Testing

The problem of deciding how much of which test to use.

  • 582