Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    assertIssues and PRs related to the assert subsystem.feature requestIssues requesting new Node.js features.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions