How can I add shared variable to chakram? - mocha.js

I'am using chakram + mocha.
How can I use shared variables for all test?
For example, I would like to use variable API_PATH="http://example.com/v1/" in tests. And this variable could be changed during running test. So, my test looks like this.
var response = chakram.get(API_PATH + "products");
expect(response).to.have.status(200);
As example, protractor has conf.js with parameter baseUrl. Running test looks like protractor conf.js --baseUrl http://example.com/

what have you tried so far? Have you tried using beforeEach to reinitialize the object that you are using? You could just make the the shared variables declared outside of your tests.
EDIT: Adding details from what Jerry said:
If you want all variable to be reused within the same test, you must make them global variables. See example below
///include dependencies
var assert = require('assert'),
chai = require('chai'),
expect = chai.expect,
chakram = require('chakram');
//INIT GLOBAL VARAIBLES FOR within the same test
var testObj,
dummyData = {
user: 'John Kim',
lastSeenOnline: 'Wed August 11 12:05 2017'
};
describe ('#User', function () {
beforeEach(function () {
//init what the object contains
testObj = new DataStore(data, ContainerStore);
});
it ('#Should return the name of the user', function () {
assert.equal(testObj.get('user'), dummyData.user);
});
it("should offer simple HTTP request capabilities", function () {
return chakram.get("http://httpbin.org/get");
});
});
Note: I work with react but this is an example. We assume that the ContainerStore contains a method that has a method for get() which just gets the value of our JSON object. You can use testObj many time in different describe blocks since it is declared outside of your tests. But you should remember to always reinitialize your tesObj in a beforeEach(); otherwise, you risk populating your individual tests. There are cases were you do not have to initialize the beforeEach() and it is optional.

For Example in config.js
module.exports = {
"baseUrl": "http://example.com/",
"googleUrl": "http://www.google.com.tr/"
};
And use in javascript code:
let config = require('/config');
describle("test describle", () => {
it("test", () => {
chakram.get(config.baseUrl + "products"); //for example use
})
})

Related

Why allowRespy is set to false by default in jasmine?

I am a beginner in Jasmine and I was wondering, why the default value for allowRespy is set to false?
I found this answer, where explained that jasmine.spyOn() always returns the first created spy, so I assume that the reason for flag it to prevent usage of mock with state.
I can come out with a simplified example where such a behavior could be problematic:
describe("TestedService", () => {
const testedService = TestBed.inject(TestedService) // configuration is ommited for simplicity
it("calls foo only once", () => {
const fooSpy = spyOn(testedService, 'foo')
testedService.doAction()
expect(fooSpy).toHaveBeenCalledOnce()
fooSpy = spyOn(testedService, 'foo') // creating new spy to check if it will be called for the second time
testedService.doAction()
expect(fooSpy).not.toHaveBeenCalledOnce() // fails the test because it still points to the same spy,that was called few moments later.
})
})
Another, more realistic example of problematic behavior is when you want to reset a spy used in your test by creating a new spy with spyOn function, but instead of it you will not be created and spy with old state will be used.
Example
describe("TestedService", () => {
beforeEach(() => {
TestBed.inject(TestedService) // configuration is ommited for simplicity
spyOn(TestedService, 'foo').and.returnValue(100)
})
....
it('tests TestedService behavior when foo returns undefined', () => {
spyOn(TestedService, 'foo') // expect it to set spy return value to undefined,
but it don't, so the test below does not tests behavior when foo returns undefined
.....
})
})
Other examples and corrections would be appreciated!

How to make variable globle in cypress which can we used in all TestCase in a spec file

I need to pass the Randomly generated string data in all my Test Cases but it is only working when i put this below code in all it() block
but i need to set this code somewhere i can access these values in all my it() block or in all my TestCases
FYI-beforeAll() and beforeEach() also not able to do this
so how can i make these thing global form where in can read in all my TestCases??
`const Rs = new RandomString();
var UserEmaill = Rs.getRandomUserEmail();
cy.log(UserEmaill);
var UserData = Rs.getRandomUser();
cy.log(UserData)`
You can do in multiple ways. If you want to generate random strings in your tests, you can use faker npm module and you can do it easily... So you can do this in as many as tests possible....
npm install faker
let faker = require('faker');
cy.log(faker.internet.email());
But as you are saying that you want to use globally across multiple tests, So I suggest you to do below stuff in before hooks of support/index.js. and call those variable wherever you want.
Do as below in index.js and it will be done at before your tests execution..
let faker = require('faker');
before(() => {
global.EMAIL1 = getRandomEmail();
global.EMAIL2 = getRandomEmail();
global.EMAIL3 = getRandomEmail();
global.EMAIL4 = getRandomEmail();
function getRandomEmail() {
return faker.internet.email();
}
})
In your test you can access as below
cy.log(global.EMAIL1);
It will work like charm, please use it and like the answer to reach to more people...
Then it is super easy, all you have to do is generate the random email per test case. So that it would not be impacted by any other test and it will not impact others too. I still suggest you to use test data per test so that other test do not get effected... I think below snippet is enough for you.
let faker = require('faker');
describe('test suite', () => {
it('test1', () => {
var email1 = faker.internet.email().split('#')[0]+'#mailinator.com';
cy.log(`test1 email is ${email1}`);
});
it('test2', () => {
var email2 = faker.internet.email().split('#')[0]+'#mailinator.com';
cy.log(`test2 email is ${email2}`);
})
})

koa-route Unable to run

Why below code output as 'one', not 'one' 'two'? but using express-route is ok
app.use(route.get('/admin',requiredUser,index));
function *requiredUser(next){
console.log("one"); //required session
yield next;
}
function *index(next) {
console.log("two"); //ok save login
this.body = yield render('admin');
}
koa-route only takes one handler - whatever you give its 2nd argument. That's why it's only executing your first handler.
You can use https://github.com/koajs/compose to combine an array of handlers into one:
var compose = require('koa-compose');
app.use(route.get('/', compose([requiredUser, index])));
Or you can use another routing library like https://github.com/alexmingoia/koa-router which has the behavior that you originally expected from koa-route:
var app = require('koa')();
var router = require('koa-router')();
router.get('/', requiredUser, index);
app.use(router.routes());
app.listen(3000);

AngularJS testing error: Unknown provider: $_httpBackend_Provider <- $_httpBackend_

I am attempting to test an AngularJS controller with a Jasmine unit test spec file. My approach is to use $httpBacked, in the following test:
describe('SubmissionsController', function() {
var minimal_mock_response = [ { id: 1 } ];
var scope, routeParams, $httpBackend;
beforeEach(module('submissionServices'));
beforeEach(inject(function($_httpBackend_, $rootScope) {
scope = $rootScope.$new();
$httpBackend = $_httpBackend_;
$httpBackend.expectGET('/submissions').respond(minimal_mock_response);
routeParams = {};
}));
it('passes a trivial test', function() {
expect(true).toBe(true);
});
});
I inserted the expect(true).toBe(true) just to get the test to execute and fail, even though it does not touch the angular controller. When I I attempt to run the test with jasmine-headless-webkit, I receive the following error:
jasmine-headless-webkit spec/javascripts/SubmissionsControllerSpec.js
Running Jasmine specs...
F
FAIL: 1 test, 1 failure, 0.011 secs.
Submissions controllers SubmissionsController passes a trivial test. (XXX/spec/javascripts/SubmissionsControllerSpec.js:18)
Error: Unknown provider: $_httpBackend_Provider <- $_httpBackend_
Test ordering seed: --seed 9254
Are there any hints on how I can correct this error and make the trivial test execute?
Enclosing service names with underscores has some benefit.
From your code, I can see that you probably wanted to save the reference to $httpBackend. This is how you wanted to do. The placement of underscore was one off.
beforeEach(inject(function(_$httpBackend_, $rootScope) {
scope = $rootScope.$new();
$httpBackend = _$httpBackend_;
...
Angular is smart enough to remove underscores and returns $httpBackend back to you, and you can save it to your own $httpBackend.
I believe this is because you're injecting the wrong service. It doesn't know what $_httpBackend_ is. You should be able to just do this:
beforeEach(inject(function($httpBackend, $rootScope) {
scope = $rootScope.$new();
$httpBackend.expectGET('/submissions').respond(minimal_mock_response);
routeParams = {};
}));
If you want to get a reference to the $httpBackend service once and store that as $httpBackend, ghiden's answer is the way to go.

Is there a way to add a Jasmine matcher to the whole environment

There are plenty of documents that show how to add a matcher to a Jasmine spec (here, for example).
Has anyone found a way to add matchers to the whole environment; I'm wanting to create a set of useful matchers to be called by any and all tests, without copypasta all over my specs.
Currently working to reverse engineer the source, but would prefer a tried and true method, if one exists.
Sure, you just call beforeEach() without any spec scoping at all, and add matchers there.
This would globally add a toBeOfType matcher.
beforeEach(function() {
var matchers = {
toBeOfType: function(typeString) {
return typeof this.actual == typeString;
}
};
this.addMatchers(matchers);
});
describe('Thing', function() {
// matchers available here.
});
I've made a file named spec_helper.js full of things like custom matchers that I just need to load onto the page before I run the rest of the spec suite.
Here's one for jasmine 2.0+:
beforeEach(function(){
jasmine.addMatchers({
toEqualData: function() {
return {
compare: function(actual, expected) {
return { pass: angular.equals(actual, expected) };
}
};
}
});
});
Note that this uses angular's angular.equals.
Edit: I didn't know it was an internal implementation that may be subjected to change. Use at your own risk.
jasmine.Expectation.addCoreMatchers(matchers)
Based on previous answers, I created the following setup for angular-cli. I also need an external module in my matcher (in this case moment.js)
Note In this example I added an equalityTester, but it should work with a customer matcher
Create a file src/spec_helper.ts with the following contents:
// Import module
import { Moment } from 'moment';
export function initSpecHelper() {
beforeEach(() => {
// Add your matcher
jasmine.addCustomEqualityTester((a: Moment, b: Moment) => {
if (typeof a.isSame === 'function') {
return a.isSame(b);
}
});
});
}
Then, in src/test.ts import the initSpecHelper() function add execute it. I placed it before Angular's TestBed init, wich seems to work just fine.
import { initSpecHelper } from './spec_helper';
//...
// Prevent Karma from running prematurely.
__karma__.loaded = function () {};
// Init our own spec helper
initSpecHelper();
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
//...

Resources