Skip to content

Subtests cause the parent test to stop showing up as green even if it asserts. #4482

Description

@nicholaswmin

v22.8

Creating subtests reports the parent as if they on't test anything are only a placeholder.

In the following, all the test assert something.
The output makes it appear as if only:

✔ with a name
✔ in the correct format

actually asset and have passed.


I follow the below pattern when writing tests.

If I'm asserting something deep I drill down to it contextually, step by step, to avoid duplication, because I think tests should be as concise and easy to digest as possible. it's a recommended pattern to group tests as far as I know.

The spec reporter stops showing a test as "green" when it contains subtests, even though it does assert.

This might sound pedantic but the I treat my tests as a .. spec. If I'm asserting something I want to have visual feedback in 6 months that I'm checking that title and it does pass which gives me a hint that's a valid use-case I've covered.

I routinely end up with modules with > 150 tests and the spec reporter output looks.. anemic I suppose?

Is there a reason for this?

Hope tihs makes sense.

Minimal Reproduction

import test from 'node:test'


test('Returns a parent with and its children', async t => {
  const parent = { name: 'foo', children: ['bar', 'baz'] }
  
  await t.test('is an object', async t => {
    t.assert.strictEqual(typeof parent, 'object')
    t.assert.notStrictEqual(parent, null)

    await t.test('with a name', async t => {
      t.assert.ok(Object.keys(parent).includes('name'), '"name" prop. missing')
      t.assert.notStrictEqual(parent.name.length, 0, 'name is empty ')
    })
    
    await t.test('and some children', async t => {
      t.assert.ok(Object.keys(parent).includes('children'))

      await t.test('in the correct format', t => {
        t.assert.ok(Array.isArray(parent.children), 'parent.child !== Array')
        t.assert.notStrictEqual(parent.children.length, 0, 'no children')
      })
    })
  })
})

Output

Current Output:

▶ Returns a parent with and its children
  ▶ is an object
    ✔ with a name (0.445583ms)
    ▶ and some children
      ✔ in the correct format (0.060583ms)
    ▶ and some children (0.192375ms)
  ▶ is an object (1.092125ms)
▶ Returns a parent with and its children (1.47275ms)

Expected Output

▶ Returns a parent with and its children
  ✔  is an object
    ✔ with a name (0.445583ms)
    ✔ and some children
      ✔ in the correct format (0.060583ms)
    ✔ and some children (0.192375ms)
  ✔ is an object (1.092125ms)

I would expect the current output to match something like this, without assertions in the parents, which I think is unnecessary nesting, unless there are assertions in the parent as explained above.

test('Returns a parent with and its children', async t => {
  const parent = { name: 'foo', children: ['bar', 'baz'] }
  
  await t.test('is an object', async t => {
    await t.test('with a name', async t => {
      t.assert.ok(Object.keys(parent).includes('name'), '"name" prop. missing')
      t.assert.notStrictEqual(parent.name.length, 0, 'name is empty ')
    })
    
    await t.test('and some children', async t => {
      await t.test('in the correct format', t => {
        t.assert.ok(Array.isArray(parent.children), 'parent.child !== Array')
        t.assert.notStrictEqual(parent.children.length, 0, 'no children')
      })
    })
  })
})

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions