{"id":13990381,"url":"https://github.com/CareMessagePlatform/jasmine-styleguide","last_synced_at":"2025-07-22T12:32:22.926Z","repository":{"id":96800223,"uuid":"81346767","full_name":"CareMessagePlatform/jasmine-styleguide","owner":"CareMessagePlatform","description":"Suggested best practices when writing Jasmine unit tests.","archived":false,"fork":false,"pushed_at":"2017-02-22T17:23:38.000Z","size":0,"stargazers_count":69,"open_issues_count":3,"forks_count":17,"subscribers_count":29,"default_branch":"master","last_synced_at":"2024-11-25T19:04:13.417Z","etag":null,"topics":["angular-testing","jasmine","jasmine-tests","javascript","javascript-tests","unit-testing"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CareMessagePlatform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-02-08T15:54:31.000Z","updated_at":"2023-11-13T20:46:59.000Z","dependencies_parsed_at":"2023-04-05T10:01:09.308Z","dependency_job_id":null,"html_url":"https://github.com/CareMessagePlatform/jasmine-styleguide","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CareMessagePlatform%2Fjasmine-styleguide","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CareMessagePlatform%2Fjasmine-styleguide/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CareMessagePlatform%2Fjasmine-styleguide/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CareMessagePlatform%2Fjasmine-styleguide/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CareMessagePlatform","download_url":"https://codeload.github.com/CareMessagePlatform/jasmine-styleguide/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227098770,"owners_count":17730630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular-testing","jasmine","jasmine-tests","javascript","javascript-tests","unit-testing"],"created_at":"2024-08-09T13:02:39.286Z","updated_at":"2024-11-29T10:30:25.137Z","avatar_url":"https://github.com/CareMessagePlatform.png","language":null,"funding_links":[],"categories":["Others"],"sub_categories":[],"readme":"# Jasmine Style Guide\n\n## Purpose\n\nThe purpose of this style guide is to offer suggested best practices when writing Jasmine unit tests.\n\n## Contributing\n\nThis 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.\n\n## Rules\n\n1. [Speak Human](#speak-human)\n1. [Write _Unit_ Tests](#write-unit-tests)\n1. [Arrange-Act-Assert](#arrange-act-assert)\n1. [Don't Repeat Yourself](#dont-repeat-yourself)\n1. [`this` Is How We Do It](#this-is-how-we-do-it)\n1. [Avoid the `All`s](#avoid-the-alls)\n1. [Be `describe`tive](#be-describetive)\n1. [Write Minimum Passable Tests](#write-minimum-passable-tests)\n\n### Speak Human\n\nLabel 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.\"\n\n#### Why?\n\n* Test suite becomes documentation for your codebase (helpful for new team members and non-technical stakeholders)\n* Failure messages accurately depict what is broken\n* Forces good naming conventions in tested code\n\n#### Bad:\n\n```javascript\n// Output: \"Array adds to the end\"\ndescribe('Array', function() {\n  it('adds to the end', function() {\n    var initialArray = [1];\n    initialArray.push(2);\n    expect(initialArray).toEqual([1, 2]);\n  });\n});\n```\n\n#### Better:\n\n```javascript\n// Output: \"Array.prototype .push(x) appends x to the end of the Array\"\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    it('appends x to the end of the Array', function() {\n      var initialArray = [1];\n      initialArray.push(2);\n      expect(initialArray).toEqual([1, 2]);\n    });\n  });\n});\n```\n\n### Write _Unit_ Tests\n\nA unit test should test **one** thing. Confine your `it` blocks to a single assertion.\n\n#### Why?\n\n* Single responsibility principle\n* A test can fail for only one reason\n\n#### Bad:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    it('appends x to the end of the Array and returns it', function() {\n      var initialArray = [1];\n      expect(initialArray.push(2)).toBe(2);\n      expect(initialArray).toEqual([1, 2]);\n    });\n  });\n});\n```\n\n#### Better:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    it('appends x to the end of the Array', function() {\n      var initialArray = [1];\n      initialArray.push(2);\n      expect(initialArray).toEqual([1, 2]);\n    });\n\n    it('returns x', function() {\n      var initialArray = [1];\n      expect(initialArray.push(2)).toBe(2);\n    });\n  });\n});\n```\n\n### Arrange-Act-Assert\n\nOrganize 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.\n\n#### Why?\n\n* The AAA unit test pattern is well known and recommended\n* Improves unit test modularity and creates opportunities to DRY things up\n\n#### Bad:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    it('appends x to the end of the Array', function() {\n      var initialArray = [1];\n      initialArray.push(2);\n      expect(initialArray).toEqual([1, 2]);\n    });\n  });\n});\n```\n\n#### Better:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    var initialArray;\n\n    beforeEach(function() {\n      initialArray = [1]; // Arrange\n\n      initialArray.push(2); // Act\n    });\n\n    it('appends x to the end of the Array', function() {\n      expect(initialArray).toEqual([1, 2]); // Assert\n    });\n  });\n});\n```\n\n### Don't Repeat Yourself\n\nUse `before`/`after` blocks to DRY up repeated setup, teardown, and action code.\n\n#### Why?\n\n* Keeps test suite more concise and readable\n* Changes only need to be made in one place\n* Unit tests are not exempt from coding best practices\n\n#### Bad:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    it('appends x to the end of the Array', function() {\n      var initialArray = [1];\n      initialArray.push(2);\n      expect(initialArray).toEqual([1, 2]);\n    });\n\n    it('returns x', function() {\n      var initialArray = [1];\n      expect(initialArray.push(2)).toBe(2);\n    });\n  });\n});\n```\n\n#### Better:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    var initialArray,\n        pushResult;\n\n    beforeEach(function() {\n      initialArray = [1];\n\n      pushResult = initialArray.push(2);\n    });\n\n    it('appends x to the end of the Array', function() {\n      expect(initialArray).toEqual([1, 2]);\n    });\n\n    it('returns x', function() {\n      expect(pushResult).toBe(2);\n    });\n  });\n});\n```\n\n### `this` Is How We Do It\n\nUse `this` to share variables between `it` and `before`/`after` blocks.\n\n#### Why?\n\n* Declare and initialize variables on one line\n* Jasmine automatically cleans the `this` object between specs to avoid state leak\n\n#### Bad:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    var initialArray,\n        pushResult;\n\n    beforeEach(function() {\n      initialArray = [1];\n\n      pushResult = initialArray.push(2);\n    });\n\n    it('appends x to the end of the Array', function() {\n      expect(initialArray).toEqual([1, 2]);\n    });\n\n    it('returns x', function() {\n      expect(pushResult).toBe(2);\n    });\n  });\n});\n```\n\n#### Better:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    beforeEach(function() {\n      this.initialArray = [1];\n\n      this.pushResult = this.initialArray.push(2);\n    });\n\n    it('appends x to the end of the Array', function() {\n      expect(this.initialArray).toEqual([1, 2]);\n    });\n\n    it('returns x', function() {\n      expect(this.pushResult).toBe(2);\n    });\n  });\n});\n```\n\n### Avoid the `All`s\n\nPrefer `beforeEach/afterEach` blocks over `beforeAll/afterAll` ones. The latter are not reset between tests.\n\n#### Why?\n\n* Avoids accidental state leak\n* Enforces test independence\n* Order of `All` block execution relative to `Each` ones is not always obvious\n\n#### Bad:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    beforeAll(function() {\n      this.initialArray = [1];\n    });\n\n    beforeEach(function() {\n      this.pushResult = this.initialArray.push(2);\n    });\n\n    it('appends x to the end of the Array', function() {\n      expect(this.initialArray).toEqual([1, 2]);\n    });\n\n    it('returns x', function() {\n      expect(this.pushResult).toBe(2);\n    });\n  });\n});\n```\n\n#### Better:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    beforeEach(function() {\n      this.initialArray = [1];\n\n      this.pushResult = this.initialArray.push(2);\n    });\n\n    it('appends x to the end of the Array', function() {\n      expect(this.initialArray).toEqual([1, 2]);\n    });\n\n    it('returns x', function() {\n      expect(this.pushResult).toBe(2);\n    });\n  });\n});\n```\n\n### Be `describe`tive\n\nNest `describe` blocks liberally to create functional subsets.\n\n#### Why?\n\n* Allows tests to build on each other from least to most specific\n* Creates tests that are easy to extend and/or refactor\n* Makes branch testing easier and less repetitive\n* Encapsulates tests based on their common denominator\n\n#### Bad:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x) on an empty Array', function() {\n    beforeEach(function() {\n      this.initialArray = [];\n\n      this.initialArray.push(1);\n    });\n\n    it('appends x to the Array', function() {\n      expect(this.initialArray).toEqual([1]);\n    });\n  });\n\n  describe('.push(x) on a non-empty Array', function() {\n    beforeEach(function() {\n      this.initialArray = [1];\n\n      this.initialArray.push(2);\n    });\n\n    it('appends x to the end of the Array', function() {\n      expect(this.initialArray).toEqual([1, 2]);\n    });\n  });\n});\n```\n\n#### Better:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    describe('on an empty Array', function() {\n      beforeEach(function() {\n        this.initialArray = [];\n\n        this.initialArray.push(1);\n      });\n\n      it('appends x to the Array', function() {\n        expect(this.initialArray).toEqual([1]);\n      });\n    });\n\n    describe('on a non-empty Array', function() {\n      beforeEach(function() {\n        this.initialArray = [1];\n\n        this.initialArray.push(2);\n      });\n\n      it('appends x to the end of the Array', function() {\n        expect(this.initialArray).toEqual([1, 2]);\n      });\n    });\n  });\n});\n```\n\n### Write Minimum Passable Tests\n\nIf 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.\n\n#### Why?\n\n* Tests become more resilient to future changes in the codebase\n* Closer to testing behavior over implementation\n\n#### Bad:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    beforeEach(function() {\n      this.initialArray = [];\n\n      this.initialArray.push(1);\n    });\n\n    it('appends x to the Array', function() {\n      expect(this.initialArray).toEqual([1]);\n    });\n  });\n});\n```\n\n#### Better:\n\n```javascript\ndescribe('Array.prototype', function() {\n  describe('.push(x)', function() {\n    beforeEach(function() {\n      this.initialArray = [];\n\n      this.initialArray.push(1);\n    });\n\n    it('appends x to the Array', function() {\n      expect(this.initialArray).toContain(1);\n    });\n  });\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCareMessagePlatform%2Fjasmine-styleguide","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCareMessagePlatform%2Fjasmine-styleguide","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCareMessagePlatform%2Fjasmine-styleguide/lists"}