<commit_before># Testing

Testing with TypeScript mostly works just the same as you'd expect in a non-TypeScript Ember application—so if you're just starting out with Ember, we recommend you read the official Ember [Testing Guides] first. The rest of this guide assumes you're already comfortable with testing in Ember!

[Testing Guides]: https://guides.emberjs.com/release/testing/

When working with TypeScript in Ember tests, there are a few differences in your experience, and there are

##  Differences

### App tests

One major difference when working with TypeScript in *app* code is that once your app is fully converted, there are a bunch of kinds of tests you just don't need to write any more: things like testing bad inputs to functions. We'll use an admittedly silly and contrived example here, an `add` function to add two numbers together, so that we can focus on the differences between JavaScript and TypeScript, rather than getting hung up on the details of this particular function.

First, the function we're testing might look like this.

<aside>

Here we’re using the `assert` from `@ember/debug`. If you’re not familiar with it, you might want to take a look at its [API docs][debug-assert]! It’s a development-and-test-only helper that gets stripped from production builds, and is very helpful for this kind of thing!

[debug-assert]: https://api.emberjs.com/ember/3.14/functions/@ember%2Fdebug/assert

</aside>

```js
// app/utils/math.js

export function add(a, b) {
  assert(
    'arguments must be numbers',
    typeof a === number && typeof b === number
  );

  return a + b;
}
```

Then the test for it might look something like this:

```js
// tests/unit/utils/math-test.js

import { module, test } from 'qunit';
import { add } from 'app/utils/math';

module('the `add` function', function(hooks) {
  test('adds numbers correctly', function(assert) {
    assert.equal('2 + 2 is 4', add(2, 2), 4);
    assert.notEqual('2 + 2 is a number', add(2, 2), NaN);
    assert.notEqual('2 + 2 is not infinity', add(2, 2), Infinity);
  });

  test('throws an error with strings', function(assert) {
    assert.throws(
      'when the first is a string and the second is a number',
      () => add('hello', 1)
    );
    assert.throws(
      'when the first is a number and the second is a string',
      () => add(0, 'hello')
    );
    assert.throws(
      'when both are strings',
      () => add('hello', 'goodbye')
    );
  })
});
```

In TypeScript, that wouldn't make any sense at all, because we'd simply add the types to the function declaration:

```ts
// app/utils/math.ts

export function add(a: number, b: number): number {
  assert(
    'arguments must be numbers',
    typeof a === number && typeof b === number
  );

  return a + b;
}
```

We might still write tests to make sure what we actually got back was what we expected—

```ts
// tests/unit/utils/math-test.ts

import { module, test } from 'qunit';
import { add } from 'app/utils/math';

module('the `add` function', function(hooks) {
  test('adds numbers correctly', function(assert) {
    assert.equal('2 + 2 is 4', add(2, 2), 4);
    assert.notEqual('2 + 2 is a number', add(2, 2), NaN);
    assert.notEqual('2 + 2 is not infinity', add(2, 2), Infinity);
  });
});
```

—but there are a bunch of things we *don't* need to test. All of those special bits of handling for the case where we pass in a `string` or `undefined` or whatever else? We can drop that. Notice, too, that we can drop the assertion from our function definition, because the *compiler* will check this for us:

```ts
// app/utils/math.ts

export function add(a: number, b: number): number {
 return a + b;
}
```

### Addon tests<commit_msg>docs: improve text and fix headings of Testing guide<commit_after># Testing

Testing with TypeScript mostly works just the same as you'd expect in a non-TypeScript Ember application—so if you're just starting out with Ember, we recommend you read the official Ember [Testing Guides] first. The rest of this guide assumes you're already comfortable with testing in Ember!

[Testing Guides]: https://guides.emberjs.com/release/testing/

When working with TypeScript in Ember tests, there are a few differences in your experience, and there are also differences in how you should handle testing app code vs. addon code.

## App tests

One major difference when working with TypeScript in *app* code is that once your app is fully converted, there are a bunch of kinds of tests you just don't need to write any more: things like testing bad inputs to functions. We'll use an admittedly silly and contrived example here, an `add` function to add two numbers together, so that we can focus on the differences between JavaScript and TypeScript, rather than getting hung up on the details of this particular function.

First, the function we're testing might look like this.

<aside>

Here we’re using the `assert` from `@ember/debug`. If you’re not familiar with it, you might want to take a look at its [API docs][debug-assert]! It’s a development-and-test-only helper that gets stripped from production builds, and is very helpful for this kind of thing!

[debug-assert]: https://api.emberjs.com/ember/3.14/functions/@ember%2Fdebug/assert

</aside>

```js
// app/utils/math.js

export function add(a, b) {
  assert(
    'arguments must be numbers',
    typeof a === number && typeof b === number
  );

  return a + b;
}
```

Then the test for it might look something like this:

```js
// tests/unit/utils/math-test.js

import { module, test } from 'qunit';
import { add } from 'app/utils/math';

module('the `add` function', function(hooks) {
  test('adds numbers correctly', function(assert) {
    assert.equal('2 + 2 is 4', add(2, 2), 4);
    assert.notEqual('2 + 2 is a number', add(2, 2), NaN);
    assert.notEqual('2 + 2 is not infinity', add(2, 2), Infinity);
  });

  test('throws an error with strings', function(assert) {
    assert.throws(
      'when the first is a string and the second is a number',
      () => add('hello', 1)
    );
    assert.throws(
      'when the first is a number and the second is a string',
      () => add(0, 'hello')
    );
    assert.throws(
      'when both are strings',
      () => add('hello', 'goodbye')
    );
  })
});
```

In TypeScript, that wouldn't make any sense at all, because we'd simply add the types to the function declaration:

```ts
// app/utils/math.ts

export function add(a: number, b: number): number {
  assert(
    'arguments must be numbers',
    typeof a === number && typeof b === number
  );

  return a + b;
}
```

We might still write tests to make sure what we actually got back was what we expected—

```ts
// tests/unit/utils/math-test.ts

import { module, test } from 'qunit';
import { add } from 'app/utils/math';

module('the `add` function', function(hooks) {
  test('adds numbers correctly', function(assert) {
    assert.equal('2 + 2 is 4', add(2, 2), 4);
    assert.notEqual('2 + 2 is a number', add(2, 2), NaN);
    assert.notEqual('2 + 2 is not infinity', add(2, 2), Infinity);
  });
});
```

—but there are a bunch of things we *don't* need to test. All of those special bits of handling for the case where we pass in a `string` or `undefined` or whatever else? We can drop that. Notice, too, that we can drop the assertion from our function definition, because the *compiler* will check this for us:

```ts
// app/utils/math.ts

export function add(a: number, b: number): number {
 return a + b;
}
```

## Addon tests
{'fraction_non_alphanumeric': 0.11555377848860456, 'fraction_numerical': 0.009063041450086632, 'mean_word_length': 3.69, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4732462', 'n_tokens_mistral': 2277, 'n_tokens_neox': 2176, 'n_words': 1013}