Testing ember js with mocha? - javascript

I'm using lineman with testem, ember, and mocha+chai.
I want to test ember. So far, because of how the test scripts and test pages are handled, I can visit a page and test it's contents.
The test page looks like
------------------------
Loop through mocha test cases
------------------------
Ember App View
------------------------
However, when I try to test for stuff outside of the content like page title:
describe('testing page title', function () {
it('should equal ember-template', function () {
visit('/');
find('title').text().should.equal('ember-template');
find('title').length; // this is 0
});
});
it gives me an error of
✘ expected '' to equal 'ember-template'
AssertionError: expected '' to equal 'ember-template'
How do I test ember completely with mocha?

visit() is asynchronous, whereas find() is synchronous (it's just a jquery selection under the hood), so the transition to the page likely isn't finished by the time you check the title. The andThen() test helper will wait for the preceding async activity to finish before executing a callback. Try the following:
describe('testing page title', function () {
it('should equal ember-template', function () {
visit('/');
andThen(function() {
find('title').text().should.equal('ember-template');
find('title').length; // this is 0
});
});
});

Related

Cucumber-Protractor tests skipping over assertions, falsely passing

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

How to skip to next next describe on error in Mocha?

I have a bunch of describes that test different parts of an API. In one section, all the tests are dependent on one test succeeding. I want to make Mocha run the first test, and if it fails, skip all following tests and run the next test suite for the next section of the API.
mocha --bail would stop testing altogether after the first fail, and won't continue to the next section.
mocha-steps is a viable solution, but I prefer not to use any external libraries. In addition, it doesn't skip steps after the failure, it doesn't print them altogether. Like I said, it's a viable solution, but not ideal.
What would be the best way to implement this behavior in vanilla Mocha?
Put what you call your "first test" in a before hook inside a describe block that contains all the other tests:
describe("bunch of related tests", function () {
before(function () {
// "first test" here
});
it("test 1", function () { ... });
it("test 2", function () { ... });
// ...
});
This is the proper way in "vanilla Mocha" to set a dependency between the code in the before hook and each of the tests. If the before hook fails, Mocha will report it, and it will skip all the tests in the describe block. If you have other tests elsewhere, they will still run.
Although I up-voted the accepted answer, I wasn't able to get a Mocha it test to run inside a before function. Instead I had to separate the first test into its own describe and set a variable if the test passed, then check the variable in the before of the describe containing all the other tests.
let passed = false
describe('first test', function() {
it('run the first test', function(done) {
if (theTestPassed)
passed = true
done()
})
})
describe('rest of the tests', function() {
before(function() {
if (!passed)
throw new Error('skip rest of the tests')
});
it('second test', ...)
it('third test', ...)
});

Conditional mocha test

I use mocha for some integration testing and have many test sets.
Each set has initialization tests. When such tests fail, the rest of the set should not run at all, because if one fails then each will fail.
The thing is that I can't avoid such initialization tests, because part of the code/environment is generated by some tool which does not guarantee any correct result.
Is it possible to implement this using mocha ?
Using the BDD interface, the normal way to do this with Mocha is to put anything that sets up the testing environment into before or beforeEach:
describe("foo", function () {
describe("first", function () {
before(function () {
// Stuff to be performed before all tests in the current `describe`.
});
beforeEach(function () {
// Stuff to perform once per test, before the test.
});
it("blah", ...
// etc...
});
describe("second", function () {
before(function () {
// Stuff to be performed before all tests in the current `describe`.
});
beforeEach(function () {
// Stuff to perform once per test, before the test.
});
it("blah", ...
// etc...
});
});
If the before or beforeEach that a test depends on fails, then the test is not run. Other tests that don't depend on it will still run. So in the example above if the callback passed to before in the describe named first fails, the tests in the describe named second won't be affected at all and will run, provided that their own before and beforeEach callbacks don't fail.
Other than this, Mocha is designed to run tests that are independent from each other. So if one it fails, then the others are still run.
I found mocha-steps which basically allow you to write a "chain" of it()s (called step()) and mocha will abort the suite if one of them breaks, thus avoiding the cascade of inevitable failures, and I found pull request 8 marks subsequent steps and subsuites as pending. So I can write:
describe("businessCode()", function() {
step("should be not null", function() {
assert(businessCode() != null)
});
step("should be a number", function() {
assert(typeof businessCode() === 'number');
});
step("should be greater than 10", function() {
assert(businessCode() > 10);
});
describe("thingThatCallsBusinessCode()", function() {
step("should be greater than 10", function() {
assert(thingThatCallsBusinessCode() != null);
});
});
});
If e.g. businessCode() returns a boolean, only the should be a number test will fail; the subsequent ones (and the subsuite will be marked as pending).

How do I run a mocha test only after the prior asynchronous test has passed?

Using the mocha javascript testing framework, I want to be able to have several tests (all asynchronous) only execute after the previously defined test has passed.
I don't want to have to nest these tests within each other.
describe("BBController", function() {
it("should save", function(done) {});
it("should delete", function(done) {});
})
Use the --bail option. Make sure you are using at least mocha 0.14.0. (I've tried it with older versions without success.)
First, there's nothing you need to do for mocha to run a test only after the previous one has finished. That's how mocha works by default. Save this to test.js:
describe("test", function () {
this.timeout(5 * 1000); // Tests time out in 5 seconds.
it("first", function (done) {
console.log("first: do nothing");
done();
});
it("second", function (done) {
console.log("second is executing");
// This test will take 2.5 seconds.
setTimeout(function () {
done();
}, 2.5 * 1000);
});
it("third", function (done) {
console.log("third is executing");
// This test will time out.
});
it("fourth", function (done) {
console.log("fourth: do nothing");
done();
});
});
Then execute it with:
mocha -R spec test.js
You will not see the fourth test start until:
The first and second tests are finished.
The third tests has timed out.
Now, run it with:
mocha -R spec --bail test.js
Mocha will stop as soon as test 3 fails.
if your tests are set up properly, only testing a small piece of business logic then you can run your tests asynchronously but they should not hold up other tests. the way to get a test to complete is to do the following:
describe("BBController", function() {
it("should save", function(done) {
// handle logic
// handle assertion or other test
done(); //let mocha know test is complete - results are added to test list
});
it("should delete", function(done) {
// handle logic
// handle assertion or other test
done(); //let mocha know test is complete - results are added to test list
});
});
again, no test should need to wait for another test to run to pass, if you have this issue then you should look at ways to impove your dependency injection or prep your tests with a before method

Nodeunit test hangs for async db call ORMnomnom

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.

Categories