I am trying to write unit test for async db calls. I'm using NodeJS with ORMnomnom package installed as orm db access and nodeunit for unit testing.
But it hang for this simple test:
Here is code test\test1.js
modelsdb = require('../model/model_db')
exports['test db'] = function (test) {
test.expect(1);
console.log('test db');
modelsdb.MyTable.objects.all( function (err, data) {
test.ok(true, "this assertion should pass");
test.done();
console.log('test must finish here!');
});
}
exports.testSomething = function(test){
console.log('testSomething');
test.expect(1);
test.ok(true, "this assertion should pass");
test.done();
};
When I run this test all assertions passed, I see my messages in console: 'test db' 'test must finish here!' 'testSomething' (means that test.done() reached inside callback function) but test doesn't finish. I need to stop it manually, get: 'Process finished with exit code 1'. If I change to test.ok(false,""), so I get AssertionError but test doesn't finish either. If I remove 'test db' and left only testSomething function - test finished as expected, all assertion passed.
I also try testpilot package which is based on nodeunit.
It gives
test1
FAIL : test db
an error occurred during test:
Error: timed out waiting for test
Any suggestions?
Thanks.
Add a tearDown method to your exports to close mongoose's connection pool. As long as it's still open the test won't exit.
You don't show how you're opening your mongoose connection, but something like this:
exports.tearDown = function (callback) {
mongoose.disconnect(callback);
};
I'm having a similar issue with nodeunit and q/mongoose - There is a bug that has been opened for it. I've tried to do the terrible process.exit(0) after calling test.done(), but any logging that is pending may not be flushed, so it isn't ideal. Ended up having to call process.exit(0) in a timeout block.
Related
Programming language used is javascript (promises flow disabled) : using async await to disable the asynchronous nature of javascript
My every test case in test suite has structure like above. Now, How can i want every test case belonging to test suite to be run in a sequence following the trend like
Opening of browser instance for a first test case & running the whole test case which is happening
then closing the above instance of first test case irrespective of the failure/success run.
Now opening the new browser instance for 2nd test case-->>running whole test case--->>closing the browser instance of this particular test case--->>
Now opening the new browser instance for 3rd test case-->>running whole test case--->>closing the browser instance of this particular test case--->>
Is this advisable to run the test suite in this way? If yes, then how should i manage with the commands like browser.close() or whatever your approach is. I have tried this but getting such errors like
AfterAll Failed: invalid session id
Every test case structure
describe("Login Suite", () => {
beforeEach(async function () {
//browser instance initialization & application navigation is happening here
})
it('Test case name', async function () {
try {
// Include test steps
} catch (e) {
browser.logger.info("Test SWM-2019065 failed with exception: " + e)
expect(true).toBe(false, e)
}
})
afterEach(async function () {
//await browser.restart();
or
//await browser.close();
})
})
I am trying to run a shell script on a Google Cloud Function.
I am using Node as the framework, and have tried different ways to run the script: execSync, execFileSync, spawnSync, etc:
module.exports.main = function() {
try {
const output = require('child_process').execSync(__dirname + '/run.sh', [],
{
stdio: 'inherit',
shell: '/bin/bash'
});
}
catch (error) {
process.exit(error.status);
}
}
The behavior I get is very erratic. Overall I think it worked once, but the rest of the time I either get a connection error and nothing happens, or the function terminates "successfully", but nothing from the shell script gets outputted, so I don't know whether it even ran or not.
To be more precise, the log lines I see when the function "fails" are only the following:
Function execution started
Function execution took 122 ms, finished with status: 'connection error'
I couldn't detect a pattern in when it fails and when it runs.
Exact reproduction steps:
Create a Google Cloud Function
set its runtime to Node 8
set its trigger to Pub/Sub topic
set its function to call to main
create a zip containing
index.js with the content above (module.exports.main = ...)
run.sh containing only
#! /bin/bash
echo "hi"
upload zip as source for Cloud Function
go to Testing tab of Cloud function and hit "Test this functions"
view logs
The solution I found was to switch to IBM Cloud Functions. They enable you to run a docker image, thus executing any binary is possible.
My suspicion as to why Google Cloud Function failed though, is that it probably ran out of memory. But that is just a guess
I'm writing a unit test framework. I noticed Mocha purports to handle exceptions in your test code gracefully, mapping the exception to the correct test in the log output. I'm attempting to do the same thing here. Let's ignore mapping the exception to the correct test for now (I'll def take a suggestion though, I'm stumped on how I'll do that for now)
I add all the test functions into the testmap, iterate over the keys in the testmap, and call each test's function one by one. I stall till the tests report back completed. I wrap around this a try-catch block to catch any exceptions that happen in any of the tests. It works - I can catch exceptions generated in the tests but even though I catch them, the program terminates. I do not want the program to terminate, and I don't think it's supposed to if you catch the exception... what gives?
Here is the try-catch in my library code
this.runtests = () => {
try {
Object.keys(this.testmap).forEach((test) => {
performance.mark(test)
this.testmap[test].testfunc();
});
this.stalltillgood(() => {
this.finallog();
});
}
catch (e) {
console.log('UNHANDLED EXCEPTION IN TEST');
console.log(e.stack);
}
};
Here is the client code which generates the exception - it is ENOENT - no such file or directory - hello.htm doesn't exist (on purpose)
expected('<fuck>&<fuck>');
testinfo('A Hello World Test', //the name of the test [MUST PASS TO ACTUAL AS WELL]
'This is the hello world test doc lol'); //the doc
comparator(cmp.equals); //you can use the pre built compare functions or your own
test(() => { //pass your test function to test
const file = fs.readFileSync('./hello.htm');
actual('A Hello World Test', file.toString());//make a call to actual in your test code
}); //to pass it your test result
//write more tests with the same sequence of commands
I think my problem is that this.runtests is the last method called, and after continuing on from my catch block, the program literally never has anything to output to me again, everything should be logged by then. The program just terminates after the catch block. I think I will have an extra var in test 'started' and just restart this.runtests, which will now check to see if a test has been started before trying to start it! Hooray! Still don't know how to map the exception to the proper test, maybe e.stack? Actually yeah that should be easy I guess lol.
I think my problem is that this.runtests is the last method called, and after continuing on from my catch block, the program literally never has anything to output to me again, everything should be logged by then. The program just terminates after the catch block. I think I will have an extra var in test 'started' and just restart this.runtests, which will now check to see if a test has been started before trying to start it! Hooray! Still don't know how to map the exception to the proper test, maybe e.stack? Actually yeah that should be easy I guess lol.
So I am brand new at Javascript, my only language before this was Ruby. I have written API tests with Cucumber and Ruby for years, but now I am trying to figure out UI tests for an angular app using Protractor and Cucumber.js. I have the framework set up and the test steps run are passing, but falsely so.
Here is a snippet of my step definitions, with a few edits to change data in assertions and the string for the assertion is intentionally wrong to trigger a failure. They run and are passing, but only because it ignores the assertion. I don't see it actually doing anything in the browser, but if I put in console.log messages I do see them in the console. However, if I comment out the last callback, then I can see it run in the browser and it actually checks the assertions and fails as it should.
Cucumber doesn't require callbacks, and removing them results in it running in exactly the same way... only I can't comment out a callback of course and watch it run like I mentioned above.
And if I don't put that timeout in the first step, then the whole thing errors out at the first step with "Error: function timed out after 5000 milliseconds"
Why?!? Thanks!!
Protractor 5.3.0 with Cucumber 4.0.0 and protractor-cucumber-framework 4.2.0
Given('I am on the home page', {timeout: 30000}, (callback) => {
browser.waitForAngularEnabled(false);
browser.get(browser.params.env.int).then(callback);
});
Then('the log in form is displayed', callback => {
expect(element(by.id('email')).isPresent()).to.eventually.be.true;
expect(element(by.id('password')).isPresent()).to.eventually.be.true;
callback();
});
When('I enter my user name', callback => {
element(by.name('email')).sendKeys('my_addy#example.com');
expect(element(by.id('email')).getAttribute('value')).to.eventually.equal('something that does match');
callback();
});
When('I enter my password', callback => {
element(by.name('password')).sendKeys('blah');
callback();
});
When('I click the log in button', callback => {
element(by.buttonText('Log In')).click();
callback();
});
Then('I am on the X page', callback => {
expect(browser.getCurrentUrl()).to.eventually.contains('Y');
// callback();
});
1) For issue: "Error: function timed out after 5000 milliseconds
This is due to your step definition function execution time duration exceeds the default timeout: 5 secs.
You can change this time out globally by following my another post, or as you did
add timeout only on needed step definition functions individually.
2) For Cucumber callback issue,
You can choose to use callback, or choose to return a promise likely in each step definition function. I prefer the latter approach.
var { Given, Then, When } = require("cucumber");
Given(/^open cucumberjs github page$/, ()=> {
browser.get("https://github.com/cucumber/cucumber-js");
return expect(browser.getTitle()).to.eventually
.equal("cucumber/cucumber-js: Cucumber for JavaScript");
});
When('I enter my password', ()=> {
return element(by.name('password')).sendKeys('blah');
});
When('I click the log in button', ()=> {
return element(by.buttonText('Log In')).click();
});
More code example, you can find from my example project here
I'm writing a script in Nightwatch that tests a specific element on a page. It's possible that the script could be testing a URL in which the element is not present on the page, in which case I want the script to end the test without any failures being logged.
I cannot seem to find a way to abort the test early without invoking a failure, however. Is there any way to have a Nightwatch test abort on a pass?
Here's a part of the code I'm working with for reference:
//End test if pagination is not present
'Pagination Present' : function (browser) {
browser
.execute(function() {
return document.querySelectorAll("ul[class='pagination']").length;
},
function(count){
if (count.value == 0) {
browser.assert.equal(count.value, 0, "There is no pagination on this page.");
browser.end();
}
})
},
Invoking browser.end(); closes the browser, but it reopens immediately after and the tests continue. Every single case fails, since the pagination does not exist on the given page. I'd like to end the test immediately after browser.assert.equal passes. Is there any way to do so?
You can use try/catch.
I had the same issue with some tests and i've got it to skip that assertion like this: you try to check something, but if you don't find the element, instead of failing the test, i just display a message in the console and exit the whole test:
'Test product\'s UPSs' : function (browser) {
try {
browser.assert.elementPresent('#someElement');
}
catch(err) {
console.log('this product has no Special features! Skipping');
process.exit();
}
}
In case you have further tests that you know they wouldn't fail and you'd like to continue with them, just leave out the process.exit() function. While it might not be the safest way to do it, at least it gets the job done.