Skip to content

Show diff if test fails with an assertion that has a message #48465

Closed
@remcohaszing

Description

@remcohaszing

What is the problem this feature will solve?

Let’s say we have the following test:

import assert from 'node:assert/strict'
import {test} from 'node:test'

test('test', () => {
  assert.deepEqual({foo: 1}, {bar: 2})
})

This yields:

✖ test (2.74485ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
  + actual - expected
  
    {
  +   foo: 1
  -   bar: 2
    }
      at TestContext.<anonymous> (file:///tmp/test.js:5:10)
      at Test.runInAsyncScope (node:async_hooks:203:9)
      at Test.run (node:internal/test_runner/test:550:25)
      at Test.start (node:internal/test_runner/test:466:17)
      at startSubtest (node:internal/test_runner/harness:203:17) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: [Object],
    expected: [Object],
    operator: 'deepStrictEqual'
  }

ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 9.405037

✖ failing tests:

✖ test (2.74485ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
  + actual - expected
  
    {
  +   foo: 1
  -   bar: 2
    }
      at TestContext.<anonymous> (file:///tmp/test.js:5:10)
      at Test.runInAsyncScope (node:async_hooks:203:9)
      at Test.run (node:internal/test_runner/test:550:25)
      at Test.start (node:internal/test_runner/test:466:17)
      at startSubtest (node:internal/test_runner/harness:203:17) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: [Object],
    expected: [Object],
    operator: 'deepStrictEqual'
  }

Now we want to provide some more context for the assertion, so we add a message.

import assert from 'node:assert/strict'
import {test} from 'node:test'

test('test', () => {
  assert.deepEqual({foo: 1}, {bar: 2}, 'objects should be equal')
})

Now this yields (the diff is gone):

✖ test (1.631264ms)
  AssertionError [ERR_ASSERTION]: objects should be equal
      at TestContext.<anonymous> (file:///tmp/test.js:5:10)
      at Test.runInAsyncScope (node:async_hooks:203:9)
      at Test.run (node:internal/test_runner/test:550:25)
      at Test.start (node:internal/test_runner/test:466:17)
      at startSubtest (node:internal/test_runner/harness:203:17) {
    generatedMessage: false,
    code: 'ERR_ASSERTION',
    actual: [Object],
    expected: [Object],
    operator: 'deepStrictEqual'
  }

ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 9.309917

✖ failing tests:

✖ test (1.631264ms)
  AssertionError [ERR_ASSERTION]: objects should be equal
      at TestContext.<anonymous> (file:///tmp/test.js:5:10)
      at Test.runInAsyncScope (node:async_hooks:203:9)
      at Test.run (node:internal/test_runner/test:550:25)
      at Test.start (node:internal/test_runner/test:466:17)
      at startSubtest (node:internal/test_runner/harness:203:17) {
    generatedMessage: false,
    code: 'ERR_ASSERTION',
    actual: [Object],
    expected: [Object],
    operator: 'deepStrictEqual'
  }

Although the intent of adding an assertion message is good, IMO the former is much more useful.

What is the feature you are proposing to solve the problem?

Show both the custom message and the diff. I.e.

✖ test (2.74485ms)
  AssertionError [ERR_ASSERTION]: objects should be equal
  + actual - expected
  
    {
  +   foo: 1
  -   bar: 2
    }
      at TestContext.<anonymous> (file:///tmp/test.js:5:10)
      at Test.runInAsyncScope (node:async_hooks:203:9)
      at Test.run (node:internal/test_runner/test:550:25)
      at Test.start (node:internal/test_runner/test:466:17)
      at startSubtest (node:internal/test_runner/harness:203:17) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: [Object],
    expected: [Object],
    operator: 'deepStrictEqual'
  }

ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 9.405037

✖ failing tests:

✖ test (2.74485ms)
  AssertionError [ERR_ASSERTION]: objects should be equal
  + actual - expected
  
    {
  +   foo: 1
  -   bar: 2
    }
      at TestContext.<anonymous> (file:///tmp/test.js:5:10)
      at Test.runInAsyncScope (node:async_hooks:203:9)
      at Test.run (node:internal/test_runner/test:550:25)
      at Test.start (node:internal/test_runner/test:466:17)
      at startSubtest (node:internal/test_runner/harness:203:17) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: [Object],
    expected: [Object],
    operator: 'deepStrictEqual'
  }

What alternatives have you considered?

None

Metadata

Metadata

Assignees

No one assigned

    Labels

    assertIssues and PRs related to the assert subsystem.feature requestIssues that request new features to be added to Node.js.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions