Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: global before/after support #121

Open
sberserker opened this issue Dec 16, 2017 · 14 comments
Open

Question: global before/after support #121

sberserker opened this issue Dec 16, 2017 · 14 comments
Labels

Comments

@sberserker
Copy link

Does this lib support global before and after hooks?
In regular mocha if before and after are outside the describe block they becoming global hooks means they run before and after all the tests in all the suites.
This seems doesn't work for this library. Is there anyway to achieve this behavior? I need to setup tokens in before hook to use them in all the test cases.

@1999
Copy link
Collaborator

1999 commented Dec 16, 2017

Yes, you can do this with --require mocha option. Files which you specify in this option will be executed before parallel tests.

@sberserker
Copy link
Author

In general it'll work but I'm not sure how to achieve the following.
I'm using mocha for api testing so i have to supply oauth token with every api call.

in the global before I can asynchronously get the token and set global request defaults

before(function(){  
	return getOauthToken().then(function(){
		setRequestDefaults();
	});
})

with mocha --require i'll have to resolve the token in every describe file. Is there any better option to achieve the former behavior? essentially get the tests wait on async call complete to be able to use global values

@1999
Copy link
Collaborator

1999 commented Dec 19, 2017

If I understand you correct, this is what you need:

CLI: mocha-parallel-tests --require base.js test/
base.js

before(function(){  
	return getOauthToken().then(function(token){
		global.token = token;
	});
});

test/foo.js

describe('suite', () => {
const req = request.defaults({ headers: { Authorization: Bearer ${global.token} } });

it('case', () => {
req(...);
});
})

@sberserker
Copy link
Author

That's right.
The only issue seems like you cannot call any of mocha before, it, describe in require(d) files.
Tried to trick it but didn't work. Either getting before is undefined or before is not a function
var Mocha = require('mocha');
var before = require('mocha').before.

@1999
Copy link
Collaborator

1999 commented Dec 20, 2017

Gotcha. Double checked that, mocha doesn't wait until --require'd file finishes its execution, so in your case the quick way to get things done is this hack:

// base.js
(async () => {
  global.token = await getOauthToken();
})();

// test.js
let req;

before(async () => {
  const authToken = await global.token;
  req = request.defaults({ headers: { Authorization: Bearer ${authToken} } });
});

describe('suite', () => {
  it('case', () => {
    req(...)
  })
});

@sberserker
Copy link
Author

That will work. The only inconvenience we'll have to have before for each describe but seems like there is no any other easy way.

What about global after? Any suggestions how to achieve that?

@1999
Copy link
Collaborator

1999 commented Dec 21, 2017

Nope, no easy way for now. I think it would be better to leave this issue open so that we can think of a better solution when we have time for that.

@gingur
Copy link

gingur commented Jan 23, 2018

@1999 1999 added the question label Jul 28, 2018
@ghost
Copy link

ghost commented Aug 20, 2018

So... I have the distinct impression that if you have 2 test files, your --require file gets run twice. Is that intentional? If so, any way to avoid it?

@1999
Copy link
Collaborator

1999 commented Aug 20, 2018

@erwinw I'm not 100% sure but this sounds like an expected behaviour of mocha-parallel-tests v2 because it runs each file in parallel. We can run this --require'd file inside the main process for sure but in this case there's no way to pass the results to forked test processes.

@ghost
Copy link

ghost commented Aug 20, 2018

Thanks for the reply, @1999 . It’s a bit unfortunate since it’s leaves only hacky solutions; I’m trying to share some info between the processes and I guess the only thing we might have is the ID of the parent process (process.ppid — haven’t tested if that is correct in this case, and a file on disk based on this ID. Cleanup after running is a whole different kettle of fish...

@1999
Copy link
Collaborator

1999 commented Aug 21, 2018

@erwinw right. Maybe that's a good area for mocha-parallel-tests improvement - some kind of lock/release API so that the processes can share some state between them. Right now using a file as a lock is probably the only way I can think of to make it work.

@ghost
Copy link

ghost commented Aug 21, 2018

Well, you have the ipc channel you can use, @1999?

@ghost
Copy link

ghost commented Aug 21, 2018

What I'm thinking is that a mechanism to run some code exclusively before all tests are run, and after all test are run.

Maybe you could have an event emitter exposed on the mocha-parallel-tests module. The trick would be to decide which of the instances would run the 'parallel-before' and 'parallel-after'? I don't know if Mocha has any way of allowing the definition of these -- otherwise --require could be the mechanism to define the user's 'parallel-before' and 'parallel-after' event handler. I guess the runner could evaluate those files, and if the parallel-before handler is defined, ask the main process whether to run it or not, where the main process, if it's the first, could say 'yes', and if it's not, either continue (if the 'parallel-before' has already finished) or wait until the 'parallel-before' has finished. A similar thing could happen at the end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants