All Projects → CareMessagePlatform → jasmine-styleguide

CareMessagePlatform / jasmine-styleguide

Licence: other
Suggested best practices when writing Jasmine unit tests.

Projects that are alternatives of or similar to jasmine-styleguide

wdio-jasmine-framework
A WebdriverIO v4 plugin. Adapter for Jasmine testing framework.
Stars: ✭ 22 (-66.15%)
Mutual labels:  jasmine, jasmine-tests
angular-material-boilerplate
A straightforward and well structured boilerplate based on Google's Angular Material project.
Stars: ✭ 28 (-56.92%)
Mutual labels:  unit-testing, jasmine
SITreg
SAP Event Registration app backend
Stars: ✭ 26 (-60%)
Mutual labels:  jasmine, jasmine-tests
aurelia-typescript-boilerplate
A starter kit for building a standard navigation-style app with Aurelia, typescript and webpack by @w3tecch
Stars: ✭ 18 (-72.31%)
Mutual labels:  jasmine, jasmine-tests
Enzyme Matchers
Jasmine/Jest assertions for enzyme
Stars: ✭ 881 (+1255.38%)
Mutual labels:  unit-testing, jasmine
Teaspoon
Teaspoon: Javascript test runner for Rails. Use Selenium, BrowserStack, or PhantomJS.
Stars: ✭ 1,443 (+2120%)
Mutual labels:  jasmine, javascript-tests
jasmine-marbles
Marble testing helpers for RxJS and Jasmine
Stars: ✭ 102 (+56.92%)
Mutual labels:  unit-testing, jasmine
angular-unit-testing-examples
Showroom for different Angular unit testing concepts
Stars: ✭ 19 (-70.77%)
Mutual labels:  unit-testing, jasmine
Jasmine Matchers
Write Beautiful Specs with Custom Matchers for Jest and Jasmine
Stars: ✭ 552 (+749.23%)
Mutual labels:  unit-testing, jasmine
Sazerac
Data-driven unit testing for Jasmine, Mocha, and Jest
Stars: ✭ 322 (+395.38%)
Mutual labels:  unit-testing, jasmine
Jasmine Marbles
Marble testing helpers for RxJS and Jasmine
Stars: ✭ 85 (+30.77%)
Mutual labels:  unit-testing, jasmine
Semaphore Ng2 Webpack
Stars: ✭ 81 (+24.62%)
Mutual labels:  unit-testing, jasmine
Spectrum
A BDD-style test runner for Java 8. Inspired by Jasmine, RSpec, and Cucumber.
Stars: ✭ 142 (+118.46%)
Mutual labels:  unit-testing, jasmine
Sinon Jest Cheatsheet
Some examples on how to achieve the same goal with either of both libraries: sinon and jest. Also some of those goals achievable only by one of these tools.
Stars: ✭ 226 (+247.69%)
Mutual labels:  unit-testing
ttdo
Extend tinytest with diffobj
Stars: ✭ 21 (-67.69%)
Mutual labels:  unit-testing
Transport Eta
Twitch streamed 🎥playground repo, README speaks to you.
Stars: ✭ 223 (+243.08%)
Mutual labels:  unit-testing
Simple Headless Chrome
Simple abstraction to use Chrome as a Headless Browser with Node JS
Stars: ✭ 216 (+232.31%)
Mutual labels:  unit-testing
bUnit
bUnit is a testing library for Blazor components that make tests look, feel, and runs like regular unit tests. bUnit makes it easy to render and control a component under test’s life-cycle, pass parameter and inject services into it, trigger event handlers, and verify the rendered markup from the component using a built-in semantic HTML comparer.
Stars: ✭ 857 (+1218.46%)
Mutual labels:  unit-testing
Alcotest
A lightweight and colourful test framework
Stars: ✭ 248 (+281.54%)
Mutual labels:  unit-testing
Vue Unit
Component testing utilities for Vue.js
Stars: ✭ 215 (+230.77%)
Mutual labels:  unit-testing

Jasmine Style Guide

Purpose

The purpose of this style guide is to offer suggested best practices when writing Jasmine unit tests.

Contributing

This style guide ultimately represents the opinions of its contributors. If you disagree with anything, or wish to add more, please create an issue or submit a pull request. Our goal is to continuously improve the guide and build consensus around it.

Rules

  1. Speak Human
  2. Write Unit Tests
  3. Arrange-Act-Assert
  4. Don't Repeat Yourself
  5. this Is How We Do It
  6. Avoid the Alls
  7. Be describetive
  8. Write Minimum Passable Tests

Speak Human

Label your test suites (describe blocks) and specs (it blocks) in a way that clearly conveys the intention of each unit test. Note that the name of each test is the title of its it preceded by all its parent describe names. Favor assertive verbs and avoid ones like "should."

Why?

  • Test suite becomes documentation for your codebase (helpful for new team members and non-technical stakeholders)
  • Failure messages accurately depict what is broken
  • Forces good naming conventions in tested code

Bad:

// Output: "Array adds to the end"
describe('Array', function() {
  it('adds to the end', function() {
    var initialArray = [1];
    initialArray.push(2);
    expect(initialArray).toEqual([1, 2]);
  });
});

Better:

// Output: "Array.prototype .push(x) appends x to the end of the Array"
describe('Array.prototype', function() {
  describe('.push(x)', function() {
    it('appends x to the end of the Array', function() {
      var initialArray = [1];
      initialArray.push(2);
      expect(initialArray).toEqual([1, 2]);
    });
  });
});

Write Unit Tests

A unit test should test one thing. Confine your it blocks to a single assertion.

Why?

  • Single responsibility principle
  • A test can fail for only one reason

Bad:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    it('appends x to the end of the Array and returns it', function() {
      var initialArray = [1];
      expect(initialArray.push(2)).toBe(2);
      expect(initialArray).toEqual([1, 2]);
    });
  });
});

Better:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    it('appends x to the end of the Array', function() {
      var initialArray = [1];
      initialArray.push(2);
      expect(initialArray).toEqual([1, 2]);
    });

    it('returns x', function() {
      var initialArray = [1];
      expect(initialArray.push(2)).toBe(2);
    });
  });
});

Arrange-Act-Assert

Organize your code in a way that clearly conveys the 3 A's of each unit test. One way to accomplish this is by Arranging and Acting in before blocks and Asserting in it ones.

Why?

  • The AAA unit test pattern is well known and recommended
  • Improves unit test modularity and creates opportunities to DRY things up

Bad:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    it('appends x to the end of the Array', function() {
      var initialArray = [1];
      initialArray.push(2);
      expect(initialArray).toEqual([1, 2]);
    });
  });
});

Better:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    var initialArray;

    beforeEach(function() {
      initialArray = [1]; // Arrange

      initialArray.push(2); // Act
    });

    it('appends x to the end of the Array', function() {
      expect(initialArray).toEqual([1, 2]); // Assert
    });
  });
});

Don't Repeat Yourself

Use before/after blocks to DRY up repeated setup, teardown, and action code.

Why?

  • Keeps test suite more concise and readable
  • Changes only need to be made in one place
  • Unit tests are not exempt from coding best practices

Bad:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    it('appends x to the end of the Array', function() {
      var initialArray = [1];
      initialArray.push(2);
      expect(initialArray).toEqual([1, 2]);
    });

    it('returns x', function() {
      var initialArray = [1];
      expect(initialArray.push(2)).toBe(2);
    });
  });
});

Better:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    var initialArray,
        pushResult;

    beforeEach(function() {
      initialArray = [1];

      pushResult = initialArray.push(2);
    });

    it('appends x to the end of the Array', function() {
      expect(initialArray).toEqual([1, 2]);
    });

    it('returns x', function() {
      expect(pushResult).toBe(2);
    });
  });
});

this Is How We Do It

Use this to share variables between it and before/after blocks.

Why?

  • Declare and initialize variables on one line
  • Jasmine automatically cleans the this object between specs to avoid state leak

Bad:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    var initialArray,
        pushResult;

    beforeEach(function() {
      initialArray = [1];

      pushResult = initialArray.push(2);
    });

    it('appends x to the end of the Array', function() {
      expect(initialArray).toEqual([1, 2]);
    });

    it('returns x', function() {
      expect(pushResult).toBe(2);
    });
  });
});

Better:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    beforeEach(function() {
      this.initialArray = [1];

      this.pushResult = this.initialArray.push(2);
    });

    it('appends x to the end of the Array', function() {
      expect(this.initialArray).toEqual([1, 2]);
    });

    it('returns x', function() {
      expect(this.pushResult).toBe(2);
    });
  });
});

Avoid the Alls

Prefer beforeEach/afterEach blocks over beforeAll/afterAll ones. The latter are not reset between tests.

Why?

  • Avoids accidental state leak
  • Enforces test independence
  • Order of All block execution relative to Each ones is not always obvious

Bad:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    beforeAll(function() {
      this.initialArray = [1];
    });

    beforeEach(function() {
      this.pushResult = this.initialArray.push(2);
    });

    it('appends x to the end of the Array', function() {
      expect(this.initialArray).toEqual([1, 2]);
    });

    it('returns x', function() {
      expect(this.pushResult).toBe(2);
    });
  });
});

Better:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    beforeEach(function() {
      this.initialArray = [1];

      this.pushResult = this.initialArray.push(2);
    });

    it('appends x to the end of the Array', function() {
      expect(this.initialArray).toEqual([1, 2]);
    });

    it('returns x', function() {
      expect(this.pushResult).toBe(2);
    });
  });
});

Be describetive

Nest describe blocks liberally to create functional subsets.

Why?

  • Allows tests to build on each other from least to most specific
  • Creates tests that are easy to extend and/or refactor
  • Makes branch testing easier and less repetitive
  • Encapsulates tests based on their common denominator

Bad:

describe('Array.prototype', function() {
  describe('.push(x) on an empty Array', function() {
    beforeEach(function() {
      this.initialArray = [];

      this.initialArray.push(1);
    });

    it('appends x to the Array', function() {
      expect(this.initialArray).toEqual([1]);
    });
  });

  describe('.push(x) on a non-empty Array', function() {
    beforeEach(function() {
      this.initialArray = [1];

      this.initialArray.push(2);
    });

    it('appends x to the end of the Array', function() {
      expect(this.initialArray).toEqual([1, 2]);
    });
  });
});

Better:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    describe('on an empty Array', function() {
      beforeEach(function() {
        this.initialArray = [];

        this.initialArray.push(1);
      });

      it('appends x to the Array', function() {
        expect(this.initialArray).toEqual([1]);
      });
    });

    describe('on a non-empty Array', function() {
      beforeEach(function() {
        this.initialArray = [1];

        this.initialArray.push(2);
      });

      it('appends x to the end of the Array', function() {
        expect(this.initialArray).toEqual([1, 2]);
      });
    });
  });
});

Write Minimum Passable Tests

If appropriate, use Jasmine's built-in matchers (such as toContain, jasmine.any, jasmine.stringMatching, ...etc) to compare arguments and results. You can also create your own matcher via the asymmetricMatch function.

Why?

  • Tests become more resilient to future changes in the codebase
  • Closer to testing behavior over implementation

Bad:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    beforeEach(function() {
      this.initialArray = [];

      this.initialArray.push(1);
    });

    it('appends x to the Array', function() {
      expect(this.initialArray).toEqual([1]);
    });
  });
});

Better:

describe('Array.prototype', function() {
  describe('.push(x)', function() {
    beforeEach(function() {
      this.initialArray = [];

      this.initialArray.push(1);
    });

    it('appends x to the Array', function() {
      expect(this.initialArray).toContain(1);
    });
  });
});
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].