---
url: https://huldoser.github.io/test-inventory/frameworks/jasmine.md
description: >-
  Scan Jasmine tests without running them, interpret the inventory, and check
  Jasmine syntax and limitations.
---

# Jasmine

This guide covers **Jasmine 4.0 or newer**. You need Node.js 22.12 or newer to run test-inventory and an
existing JavaScript or TypeScript test suite. The scanner reads your source without executing your tests or starting
a browser. These are minimum supported versions; [CI comparisons](/guide/runners#checked-in-ci) list tested versions.

[Choose another framework](/frameworks/) · [Use an AI client](/guide/agents)

## Install

```sh
npm install --save-dev test-inventory
```

## Scan your suite

Run from the folder containing your project's `package.json`:

```sh
npx test-inventory --framework jasmine --pretty --output inventory.json
```

To select files explicitly, use quoted globs. This example matches the `risk-service` fixture used below;
adjust the globs to your suite's layout:

```sh
npx test-inventory "spec/*.spec.js" "spec/limits/**/*.spec.js" --framework jasmine --output inventory.json
```

The command replaces `inventory.json` once the new output is complete. It does not change your test files.

## Check the result

Print the counts and diagnostics from the saved file:

```sh
node -e "const i = require('./inventory.json'); console.log(i.summary); console.log(i.diagnostics)"
```

For matching tests, `summary.fileCount` and `summary.testCount` should be greater than zero. Review diagnostics
even when the command exits with 0: errors can mean tests are missing. If the result is empty or unexpected,
use [troubleshooting](/guide/troubleshooting).

The inventory describes source declarations, not execution results. Conditional skips are not proof that a run
skipped the test. Loops and tables are one record by default; supported cases can be expanded with `--expand-cases`.
Expected-to-fail tests execute and check for failure; they are not disabled tests.

Tests created by unreadable helpers can be missing without a diagnostic. A dependency hash does not prove complete
coverage of runtime dependencies. Read the [shared limits](/guide/limits) before using scans to make CI decisions.

## Find skipped tests

```sh
npx test-inventory --framework jasmine --state skip --fields fullName,state,condition,reason --pretty
```

This uses the same file selection as the first scan. If you supplied globs, `--root` or `--framework-version`,
repeat those options here.

This selects source declarations marked skip; it is not a report of a test run.
See [query recipes](/guide/recipes) for other inventory queries.

## Example

`risk-service` measures exposure and value at risk, and is tested with the jasmine command, in plain CommonJS. Its
config, `spec/support/jasmine.json`, runs `**/*.spec.js` under `spec`, and its `!fixtures/**` leaves the sample
positions out.

Specs mark themselves pending at run time, with a reason, and take a timeout as their third argument:

```js excerpt
// spec/exposure.spec.js
  it('reads positions from the prime broker', async () => {
    expect(positions.length).toBe(2);
  }, 15_000);
  // ...
  it('includes futures at their notional', () => {
    pending('RISK-81: futures need the contract multiplier');
  });

  it('includes positions in the overnight session', () => {
    if (!process.env.EXTENDED_HOURS) pending('Only with extended hours');
```

```sh
npx test-inventory "spec/*.spec.js" "spec/limits/**/*.spec.js" --framework jasmine --output inventory.json
```

Without the globs and `--framework`, the scan finds the same files from `jasmine.json`, and Jasmine from
`package.json`. `pending()` keeps its reason, and under a condition the test is conditional:

```json
{
  "fullName": "exposure > includes positions in the overnight session",
  "state": "skip",
  "isConditional": true,
  "condition": "!process.env.EXTENDED_HOURS",
  "reason": "Only with extended hours"
}
```

## Configuration and limits

The scan reads `spec/support/jasmine.mjs` from Jasmine 5, then `.json` or `.js`, in the root.
Without a config it selects no files unless files are explicitly supplied, as Karma and Angular supply them.
Scan globs replace `spec_files`; `JASMINE_CONFIG_PATH` and the runner's `--config` are not read.

Helper globs are included in dependency hashes. Setup and helper code is not executed to discover arbitrary
runtime effects. The record describes `pending()` and disabled declarations from source, not a result from a run.

::: details Exact file selection

For Jasmine: the files under `spec_dir` that a
`spec_files` glob matches, without those a glob starting with `!` matches. Without a config it runs no file; scanned
with globs, every file they match counts as run, as files given to Jasmine replace `spec_files`. `JASMINE_CONFIG_PATH`
and `--config` are not read.

:::

## Supported syntax

Jasmine 4.0 and newer.

### Where test comes from

| Form               | Example                                                                                                                                                                      |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Globals            | `describe`, `xdescribe`, `fdescribe`, `it`, `xit` and `fit`, which the jasmine command, Karma or a browser page set; Jasmine has no module to import them from               |
| Kept in a variable | `const later = xit`: the variable keeps the `x` or `f`; of a choice, also one written in place, as `(process.env.CI ? xit : it)(...)`, only what both branches share applies |
| Local helpers file | `import { spec } from './helpers'` or `require('./helpers')`, followed through local imports, and helper functions that declare specs, read at each call                     |

`xit` and `xdescribe` are `.skip`, and `fit` and `fdescribe` `.only`. Jasmine's functions have no members, so a call
such as `it.only()` is an `invalid-chain` error. Jasmine runs the innermost focus: a `fit` or `fdescribe` runs also
inside an `xdescribe`, while an `xdescribe` inside an `fdescribe` stays skipped, and in an `fdescribe` with a `fit` or
`fdescribe` below it, only those run, so its other specs have `isOnly: false`. WebdriverIO on Jasmine follows the same
rules.

### Calls

| Call                                                              | Read as                                                                                                                                                                                                                                                                                       |
| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `it(title, fn)`, `it(title, fn, timeout)`                         | A spec, with `timeout` when the third argument is a number the scan can work out.                                                                                                                                                                                                             |
| `it(title)`, `xit(title)` without a function, or with `undefined` | A skipped spec: Jasmine reports it as pending; `it()` is one titled `''`. `fit(title)` without one is a `test-without-body` error.                                                                                                                                                            |
| `it(title, 42)`                                                   | A `test-without-body` error: Jasmine takes the function second.                                                                                                                                                                                                                               |
| `describe(title, fn)`                                             | A describe. Without a function, a `test-without-body` error, also for `xdescribe`; with an async callback, an `async-describe` error; with a callback whose `length` is above 0, as `(fills) => {}`, or that declares no spec or describe, as one with only hooks, a `describe-throws` error. |
| `beforeAll`, `beforeEach`, `afterEach`, `afterAll`                | Hooks, also with a timeout as their second argument.                                                                                                                                                                                                                                          |
| `pending(reason)` in a spec, `beforeEach` or `afterEach`          | The spec skipped with the reason; under a condition, `isConditional`. In `beforeAll` or `afterAll`, Jasmine reports it as an error of the describe, and the specs keep their state.                                                                                                           |
| `notApplicable(reason)` in a spec                                 | From Jasmine 7, the spec skipped with the reason. Before, the call fails the spec.                                                                                                                                                                                                            |

Where an error is written decides what Jasmine does. At the top level of a file, it stops Jasmine before it runs any
spec, in this file or any other, and every test in the file is `notLoaded`. Inside a describe, Jasmine catches it: it
reports the describe as failed and registers none of the specs written after the call in it; the scan reports the
error, keeps the file's tests as they are, and still lists those later specs. `jasmine.DEFAULT_TIMEOUT_INTERVAL` set in
a helper or spec file is not read. A `beforeEach` in a helper file runs around every spec, but is not counted in
`hooks`.

The [shared syntax rules](/reference/syntax#in-every-runner) also apply.

## Next

* [Shared limits](/guide/limits): imports, generated tests, conditions and dependency coverage.
* [Key concepts](/guide/concepts): counts, states, IDs and hashes.
* [Output reference](/reference/output) and [diagnostics](/reference/diagnostics): interpret every field and warning.
* [CLI](/guide/cli), [library](/guide/library) and [MCP](/guide/agents): use the same inventory through each interface.
* [Compare with Jasmine](/guide/runners#jasmine-s-list): differences from runner collection and execution reports.
