Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • Jasmine for writing unit/spec tests and Karma for running those tests
  • ProtractorCypress for writing integration / end-to-end (e2e) tests
  • GitHub Actions - This is our continuous integration (CI) system of choice. It automatically runs all code style checks & unit/integration tests for all Pull Requests. Our configuration for GitHub Actions can be found in [src]/.github/workflows/build.yml
    • Our GitHub Actions configuration also starts up a Docker-based REST API backend for running end-to-end (e2e) tests against.
  • Coveralls - GitHub Actions CI runs test code coverage checks which it passes to Coveralls.io for easier display/analysis. If Coveralls finds code coverage has decreased significantly (which means tests were not implemented for new code), it will place a warning on a Pull Request.

...

  • Unit tests (or specs) can be found throughout the codebase (under /src/app) alongside the code they test. Their filenames always end with ".spec.ts". For example, the login-page.component.ts has a corresponding login-page.component.spec.ts test file.
  • End to End (e2e) tests are all in the /cypress/e2eintegration  folder. At this this time we have very few of these.

Learning Resources

  • https://testing-angular.com/ is an online E-Book which walks through creating Angular unit tests in Jasmine & Angular end-to-end tests in Cypress.

Checklist for building good tests

...

  • Specs are required for all Angular Components, Services and other classes.
  • All specs should be placed in the same directory as the Angular Component which they test. The filename should end in ".spec.ts".  For example, the login-page.component.ts has a corresponding login-page.component.spec.ts test file.
  • As much as possible/reasonable, follow the Angular Testing Guide, which provides detailed example tests. Jasmine also has good documentation/tutorials on learning to write tests.
  • Always mock all providers. Doing so ensures that you're only testing your own code, so a change to the service won't break your test. It also ensures that successive tests can't influence each other by sharing data through an service
  • When testing asynchronous code, verify that your expect is actually executed. The following test will always succeed, because the expect is only executed after the it function has already completed:
    it("should encounter an expect", () => {
    timer(1000).subscribe(() => {
    expect(true).toBe(false);
    })
    })

    The easiest way to fix this would be to use the callback function it provides:
    it("should encounter an expect", (done) => {
    timer(1000).subscribe(() => {
    expect(true).toBe(false);
    done();
    })
    })

    Now the test won't complete until the callback function done() is called, so the test above will fail. Other ways of testing asynchronous code include marbles, and fakeAsync.

    A quick way to verify that your expect is actually being used is to flip it and see if that causes the test to fail.

    Note that this applies to all functions in a test suite, not just it. Here's a commit that fixes a number of these issues in beforeEach and a few in it: 066e6cd.
  • If you are working on debugging specific tests, you can add a "focus" on those tests (e.g. fdescribe instead of describe).  However, be warned that you must remove that focus before the PR can be merged, as otherwise you'll see a large decrease in code coverage (i.e. all non-focused tests will be ignored)

Writing Integration (e2e) Tests

  • https://testing-angular.com/ is an online E-Book which walks through creating Angular unit tests in Jasmine & Angular end-to-end tests in Cypress.

Writing Integration (e2e) Tests

A A few quick guidelines on writing Angular end-to-end (e2e) tests using Protractor (and Jasmine) Cypress:

  • All e2e tests should be in the /e2ecypress/srcintegration/ directory, per the Angular CLI best practices.
  • A single e2e test consist of two related files:
    • A Page object (ends in "po.ts") which is a class describing a high level page view, including logic for finding all elements on the page and navigating to the page URL. 
    • An e2e test file (ends in "e2e-spec.ts") which include Jasmine-based tests using the Page object.
  • Tests should be named similar to the component or page they test.
    • For example "homepage.spec.ts" obviously tests the homepage, while "header.spec.ts" may test specific aspects of the header of the entire site.
  • docs.cypress.io has great guides & documentation helping you learn more about writing/debugging e2e tests in Cypress.

  • https://testing-angular.com/ is an online E-Book which walks through creating Angular unit tests in Jasmine & Angular end-to-end tests in CypressExamples of writing Angular e2e tests can be found in this Introduction to e2e Testing with Angular CLI and Protractor blog post, or by referencing the existing tests in our codebase.
  • NOTE: be aware that when e2e tests run, they require using a REST API backend & test data. Therefore in GitHub Actions CI, our tests run against a Docker based REST API (preloaded with basic test data) defined in the docker-compose-ci.yml