lorenzofox3 / zora

Lightest, yet Fastest Javascript test runner for nodejs and browsers
MIT License
539 stars 93 forks source link

Weird behaviour with imported sequence tests #10

Closed oles closed 6 years ago

oles commented 6 years ago

It seems like there's something weird going on when a test is imported to be used in a plan of plans.

index.js

import zora from 'zora'
import example from './example.js'

zora()
.test(example)
.run()

example.js

import zora from 'zora'
export default zora({sequence: true})

.test('is run before', async assert => {
    await new Promise(resolve => setTimeout(() => resolve(), 1000))

    console.log('before')
    assert.ok(true, 'before')
})

.test('is run after', assert => {
    console.log('after')
    assert.ok(true, 'after')
})

Now, 'after' is logged at once, followed by 'before' after a second, if you run node -r @std/esm index.js.

If I append .run() and remove export default from example.js, and run it directly - it works! 'before' pops up first, followed by 'after'.

Thought I'd let you know, even though the sequenced option is not yet documented :)

lorenzofox3 commented 6 years ago

No this is "normal" behaviour. For performance reasons tests are run in parallel (but reported in sequence). If you wish to respect the sequence you can pass the option {sequence:true} when you create your plan:

plan({sequence:true})
   .test('test1',async t=>{})
   .test('will not start before test 1 is done', t => {})
oles commented 6 years ago

Huh... but isn't that what I'm doing in example.js above? export default zora({sequence: true})

oles commented 6 years ago

In case it wasn't clear - I'd like to get multiple plans running sequentially concurrently.

zora()

.test(plan1) // has {sequence: true} 
.test(plan2) // also has {sequence: true} 

.run()

... for example!

oles commented 6 years ago

Actually, it seems like I'm overthinking it. I'll go ahead with a different approach :)

lorenzofox3 commented 6 years ago

@oles A new pre major release is available. Can you try a little bit and tell me what you think. Thanks

oles commented 6 years ago

Awesome! Great timing as well - working on my tests tonight 👍

I'll try it out and will report back later today or early next week :)

oles commented 6 years ago

@lorenzofox3

Alright! First - I'm wondering... How to convert this to v2?

index.js

import zora from 'zora'
import example from './example.js'

zora()
.test(example)
.run()

example.js

import zora from 'zora'
export default zora()

.test('example!', assert => {
    assert.ok(true)
})

This is what I'm at currently:

index.js

import test from 'zora'
import example from './example.js'

example()

example.js

import test from 'zora'

export default () => {
    test('example!', assert => {
        assert.ok(true)
    })
}
oles commented 6 years ago

It works, but seems a bit unintuitive - that extra indentation 🤔

lorenzofox3 commented 6 years ago

Technically you don't need anymore an entry point. So the index.js is a bit useless.

If you still want to use one. (to be used with a module bundler for instance)

you can simply in your entry point import the files even though they don't export anything. It works at least with rollup (and natively with nodejs).
test/test1.js

import test from 'zora';
test('foo',t=>{
 //
});

test/index.js

import whathever from 'test/test1.js';

You could as well simply concat the files index.js

// only the import of the libraries 
import test from 'zora';

test.js

// no import at all
test('foo', t => {
 t.ok(true);
});

then cat intex.js ./test.js > debug.js

However this one introduces implicit globals (loaded in index.js).

you could as well export all your tests (a bit troublesome) test.js

import test from 'zora';
export const t1 = test('foo',t=>{});
export const t2 = test('foo',t=>{});
//index.js
import * as t1 from './test.js'

otherwise you can do as you did. It indeed add an indentation but you had it before anyway by exporting the plan and then by importing it to be able to call run

oles commented 6 years ago

If you still want to use one. (to be used with a module bundler for instance)

you can simply in your entry point import the files even though they don't export anything. It works at least with rollup (and natively with nodejs).

Aha! I think this suits me even better - I'll try it soon! Thanks a lot for the answer :)

oles commented 6 years ago

Confirmed - seems to work well 👍

oles commented 6 years ago

Made my setup and structure for the tests even better and simpler. Wonderful job, @lorenzofox3! Really glad to not have to be limited by the quirks of all the other alternatives.

lorenzofox3 commented 6 years ago

Glad you liked it ! Note: If you or your tool is annoyed by the empty export you can also semantically group your tests in a test suite.

funcX.js

import test from 'zora';
export default test('testing functionality x',t=>{
  t.test('test 1', t=> {
    //
  });

  t.test('test 2', t=>{
   //
  });

});

then in index.js

import funcX from './funcX.js';
  1. It will be transparent for most of the tap reporters.
  2. It is aligned with ES module spec. (rollup is not exactly aligned as it inlines import, which has the nice effect of concatenating files...even they have no export and therefore should not considered as module).
  3. You can run your test files individually or by importing them (or by spawning process, etc) without any extra work)
oles commented 6 years ago

Ahh, great to know. Currently rolling with just a simple import './tests/set.js' - works for now!