Append error message to target ".not.empty"? - mocha.js

I have several tests that check if a string is empty.
expect(Cypress.env('ACT_PROVIDER_KEYS')).to.be.an('string').not.empty;
Is there a way to add a message to .not.empty to specifically indicate which test failed?

A custom error message can be given as the second argument to expect.
const { expect } = require('chai');
describe('73450550', () => {
it('should pass', () => {
const ACT_PROVIDER_KEYS = '';
expect(ACT_PROVIDER_KEYS, 'api provider keys is empty').to.be.an('string').not.empty;
});
});
Test result:
73450550
1) should pass
0 passing (7ms)
1 failing
1) 73450550
should pass:
AssertionError: api provider keys is empty: expected '' not to be empty
at Context.<anonymous> (src/stackoverflow/73450550/index.test.js:6:83)
at processImmediate (internal/timers.js:464:21)

Related

Cypress test validation

I have function to convert text to Uppercase, what i want to do is to write test in cypress for the fonction and print the result in htmml
here the function :
module.exports = () => ({
upperCaseName: (name) => {
return name.toUpperCase()
}
});
here i print it :
<h1 cy-data='uppercase'> the result </h1>
so how i should write the test :
i know i could do this :
cy.get('[cy-data=uppercase]').contains('the result')
but i want somthing like this :
example:
cy.get('[cy-data=uppercase]').to.be.upperCase
is it possible?
How about
cy.get('[cy-data=uppercase]').contains('THE RESULT', { matchCase: true })
but { matchCase: true } is the default setting, so can be just
cy.get('[cy-data=uppercase]').contains('THE RESULT')
Custom Chai assertion for uppercase
window.chai.Assertion.addProperty('uppercase', function () {
var obj = this._obj;
new chai.Assertion(obj).to.be.a('string');
this.assert(
obj === obj.toUpperCase()
, 'expected #{this} to be all uppercase' // error message when fail for normal
, 'expected #{this} to not be all uppercase' // error message when fail for negated
);
});
it('test for upper case (and not uppercase)', () => {
cy.get('[cy-data=uppercase]').invoke('text').should('be.uppercase')
cy.get('[cy-data=lowercase]').invoke('text').should('not.be.uppercase')
})
Extends internal Cypress version of Chai with new assertion, works in .should() with retry and timeout as well.
Or without custom chai assertion
it('test for upper case (and not uppercase)', () => {
cy.get('[cy-data=uppercase]').invoke('text')
.should(text => expect(text).to.eq(text.toUpperCase())
cy.get('[cy-data=lowercase]').invoke('text')
.should(text => expect(text).not.to.eq(text.toUpperCase())
})
You can use regex as well to check that the text has uppercase or not.
cy.get('[cy-data=uppercase]')
.invoke('text')
.should('match', /\b[A-Z]+\b/)
To check if everything in the sentence is in uppercase along with special characters you can use the regex ^[^a-z]*$
cy.get('[cy-data=uppercase]')
.invoke('text')
.should('match', /^[^a-z]*$/)
You can play around with regex as per your requirement.

Cypress custom command wont return value

I have a function that I want to add as a command so i can reuse it.
Its on cypress/support/commands.js:
Cypress.Commands.add("generatePassword", () => {
return 'randomstring';
}
);
Then on my test I want to use it as:
it("Visits page", () => {
const password = generatePassword();
cy.log({password})
// Here it logs this:
//{password: {chainerid: chainer146, firstcall: false}}
});
Any idea on how to get the actual value? Now i get this:
{chainerid: chainer146, firstcall: false}
Thanks.
Basically cypress works in promise chain and you're returning the promise chainerid from your custom command. You have to chain it to use in next statement. Use something like below.
it("Visits page", () => {
return cy.generatePassword().then(pwd => {
cy.log(pwd);
});
});

Mocha Chai Sequelize: I can't make tests fail

I am trying to write test for a model in sequelize, but I do not understand why it is not failing
it('should find user by id', (done) => {
users.findByPk(2)
.then((retrievedUser) => {
expect(retrievedUser.dataValues).to.deep.equal('it should break');
done();
})
.catch((err) => {
console.log(`something went wrong [should find user by id] ${err}`);
done();
})
});
When I run the test the output is the following
something went wrong [should find user by id] AssertionError: expected { Object (id, email, ...) } to deeply equal 'it should break'
1 -__,------,
0 -__| /\_/\
0 -_~|_( ^ .^)
-_ "" ""
1 passing (40ms)
If someone want to watch the full code, I created a project
For an asynchronous Mocha test to fail, pass an error as an argument to the done callback function
it('should find user by id', (done) => {
users.findByPk(2)
.then((retrievedUser) => {
expect(retrievedUser.dataValues).to.deep.equal('it should break');
done();
})
.catch((err) => {
console.log(`something went wrong [should find user by id] ${err}`);
done(err);
})
});
Alternatively, use an async function without a callback:
it('should find user by id', async () => {
const retrievedUser = await users.findByPk(2);
try {
expect(retrievedUser.dataValues).to.deep.equal('it should break');
} catch (err) {
console.log(`something went wrong [should find user by id] ${err}`);
throw err;
}
});
That said, I wouldn't recommend logging the error message of failing tests, because that's what Mocha already does for you in a typical setup. So I would get rid of the try-catch block in the example above.
it('should find user by id', async () => {
const retrievedUser = await users.findByPk(2);
expect(retrievedUser.dataValues).to.deep.equal('it should break');
});

How will write jasmine to cover my function? I am getting error "config method in not exist"

Getting error to my function which I am trying to cover in Jasmine
"Error is config method does not exist" And config the method which I am trying to cover.
I am expecting to cover the right test case scenario to my config method.
const config = () => {
return ({
name: 'modal.name',
class: 'modal.class',
choice: 'modal.choice'
});
}
describe('Config', () => {
it('config is defined', () => {
let data = {
name: 'modal.name',
class: 'modal.class',
choice: 'modal.choice'
};
Object.assign(config, data);
spyOn(data, 'config').and.returnValue(Promise.resolve(data));
});
});
You are getting that error because you are trying to spy the config method in your data object with the statement:
spyOn(data, 'config').and.returnValue(Promise.resolve(data));
The data object has no config method so, when you call spyOn it throws that error.
Your it says that you are trying to test that config is defined, but you are doing really strange things in your test. If you want to check that config is defined you could do:
it('config is defined', () => {
expect(config).toBeDefined();
});
A more elaborated test would be to test that the method, besides existing, returns the data you want:
it('config returns the configuration', () => {
expect(config()).toEqual({
name: 'modal.name',
class: 'modal.class',
choice: 'modal.choice'
});
});

Test ethereum Event Logs with truffle

I have a contract's function which emit events on each call.
I would like to have an event emitted on each test which are passing, here are some tests :
it("should emit Error event when sending 5 ether", function(done){
var insurance = CarInsurance.deployed();
insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(done).catch(done);
});
it("should emit Error event when sending 5 ether", function(done){
var insurance = CarInsurance.deployed();
insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(function(txHash){
assert.notEqual(txHash, null);
}).then(done).catch(done);
});
it("should emit Error event when sending 5 ether", function(done){
var insurance = CarInsurance.deployed();
insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(function(done){
done();
}).catch(done);
});
The results are :
1) should emit Error event when sending 5 ether
Events emitted during test:
---------------------------
Error(error: Must send 10 ether)
---------------------------
✓ should emit Error event when sending 5 ether (11120ms)
✓ should emit Error event when sending 5 ether (16077ms)
3 passing (51s)
1 failing
1) Contract: CarInsurance should emit Error event when sending 5 ether:
Error: done() invoked with non-Error: 0x87ae32b8d9f8f09dbb5d7b36267370f19d2bda90d3cf7608629cd5ec17658e9b
You can see that the only one which is logged fail.
Any idea ?
Thank you
You are passing tx hash into done() function. I think the problem is in line:
insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(done).catch(done);
Change it to:
insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(function() { done(); }).catch(done);
To test for events:
it("should check events", function(done) {
var watcher = contract.Reward();
// we'll send rewards
contract.sendReward(1, 10000, {from: accounts[0]}).then(function() {
return watcher.get();
}).then(function(events) {
// now we'll check that the events are correct
assert.equal(events.length, 1);
assert.equal(events[0].args.beneficiary.valueOf(), 1);
assert.equal(events[0].args.value.valueOf(), 10000);
}).then(done).catch(done);
});
Since Truffle v3 you get the logs in the callback result. So you could do something like:
insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then((result) => {
assert.equal(result.logs[0].event, "Error", "Expected Error event")
})
See https://github.com/trufflesuite/truffle-contract#processing-transaction-results
There is a helper to do just this:
npm install --save truffle-test-utils
At the top of your test:
require('truffle-test-utils').init();
In your test:
let result = await insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')});
assert.web3Event(result, {
event: 'Error',
args: {
error: 'Must send 10 ether'
}
}, 'Error event when sending 5 ether');
Full disclosure: I'm the author of this package. I wrote it after looking for such solution on SO, but couldn't find it.
Instead of writing your own, you can also use Truffle's test utils expectEvent.js:
const { inLogs } = require('openzeppelin-solidity/test/helpers/expectEvent')
require('chai').use(require('chai-bignumber')(BigNumber)).should()
...
{ logs: this.logs } = await this.token.burn(amount, { from: owner })
...
const event = inLogs(this.logs, 'Burn')
event.args.burner.should.eq(owner)
event.args.value.should.be.bignumber.equal(amount)
An example can be found in Truffle's BurnableToken.behavior.js.
You can use the truffle-assertions package, which has an assertion to check that an event has been emitted. It also has the option to pass a filter function in order to check complex conditions to the event arguments.
npm install truffle-assertions
You can import it at the top of your test file:
const truffleAssert = require('truffle-assertions');
And use it inside your test:
let txResult = await insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')});
truffleAssert.eventEmitted(txResult, 'Error', (ev) => {
return ev.error === 'Must send 10 ether';
}
Disclaimer: I created this package to use in my own tests, and by adding the filter function, it is possible to check complex conditions to the event arguments, in a very straightforward way. I wrote an article explaining this in more detail on my blog.
I was able to track down some references to help with this, especially if you want to use async/await.
it('can create a unique star and get its name', async function () {
const event = this.contract.starClaimed({});
event.watch(async (err, result) => {
if (err) console.log("Somethings wrong...");
if (result.args.owner === accounts[0]) {
let token = result.args._token;
event.stopWatching;
const star = await this.contract.tokenIdToStarInfo(token);
assert.equal(star[0], 'awesome star!');
assert.equal(star[1], 'yada yada yada');
assert.equal(star[2], 'dec_test');
assert.equal(star[3], 'mag_test');
assert.equal(star[4], 'cent_test');
}
});
await this.contract.createStar('awesome star!', 'yada yada yada', 'dec_test', 'mag_test', 'cent_test', {from: accounts[0]});
});
Here's the reference I found: https://github.com/trufflesuite/truffle-contract/issues/117

Resources