I have a vanilla Angular7 project that was generated via ng CLI and in there I have a component that I would like to test: src/app/mini-cal/mini-cal.component.spec.ts

I don't know of any way to ask angular cli tool to do this for me, the following combinations failed:

ng test --specs='src/app/mini-cal/mini-cal.component.spec.ts'
ng test -- --specs='src/app/mini-cal/mini-cal.component.spec.ts'

So I decided to point protractor at it like so:

protractor e2e/protractor.conf.js --specs='src/app/mini-cal/mini-cal.component.spec.ts'

which worked in getting at the file of interest but its missing additional configuration for:

  • zone

    - Failed: Zone is needed for the async() test helper
              but could not be found. Please make sure
              that your environment includes
  • testbed initialization
    - Failed: Cannot read property 'injector' of null

Usually all of this is available in src/test.ts and used by ng test automatically ... but now that I'm starting the process via protractor, I need to incorporate it into my e2e/protractor.conf.js file's onPrepare() method somehow.

How can I accomplish this?

1 Answers

Scotty Waggoner On Best Solutions

Since you are testing a single component, I believe you are trying to write and run a unit test, not an e2e (end to end) test. Unit tests generally only test a small unit (like a component or service or function) and are purposely scoped to make sure that unit does what is expected without having to worry about how external units are implemented. An end to end test (I've never written one so correct me if I'm wrong) would fire up your whole app and interact with it to test if units are working together correctly (think testing whole pages, multiple components interacting, navigating, etc).

The Angular CLI uses the Karma test runner to run the unit tests in a browser environment and Protractor for e2e tests (I don't know the specifics of how Protractor runs tests.) See Angular's Testing Guide. So ng test runs Karma and ng e2e runs Protractor. Both types of tests use Jasmine as the testing framework for actually writing the test code.

It appears others have struggled with running a single unit test. You can use Jasmine's focused test feature to display output from a single it or describe block by changing them to fit or fdescribe. But that doesn't stop the code in other test files from being compiled or loaded, just keeps other describe or it blocks from running. You can see How to execute only one test spec with angular-cli for attempts at doing other things.

I've enjoyed using Jest for all my React tests and I believe Jest gives a much better test running experience (ability to run specific tests by pattern matching, run only on changed files in your git working copy, interactive watching mode, updating snapshots, etc). You can look at the Jest cli options to see how to run only specific tests. Jest is both a testing framework (which is very much a copy of Jasmine syntax) and a test runner. Jest can use jsdom or node to run your tests and doesn't need to run a real browser. Looks like Karma might have some support for jsdom now too...

If you want to go the Jest route, using Jest Angular Schematic seems like the easiest way to add Jest to an Angular project and has a corresponding article about it.