How to add text to the Mocha output reports - javascript

I want to track some values, like timings and gasused. I can return this using console.log(), collecting it, is not the problem. But would like a more robust and nicer method to report it than console.log().
A simplyfied example:
it("I can reserve up to 10.000", async() => {
let instance = await FullCoupon.new(10000);
// in reality this is a helper function to collect and output the values.
var tx = await web3.eth.getTransactionReceipt(instance.transactionHash);
console.log(tx.gasUsed);
//...
});
The above example would print inline and unpadded number (the 53855 in the screenshot):
What I am looking for, is, preferably to collect messages during the test-run and print them below the test-output. Where my test-suite prints the > No events were emitted for example.
Or, alternatively, to add texts to the test-line being printed, similar to the slow-test-timing flags, the (185ms) for example.
Does Mocha offer an API to set messages to be printed into its reports?

There certainly is a way of doing it. You can use some other reporter which supports this kind of feature. You can try using mochaawesome it has a feature to add details to individual test result.
To add some test to your test report, you can use code as below:
const addContext = require('mochawesome/addContext');
From inside it block:
addContext(<value you want to print>);
To use this reporter use --reporter mochawesome while triggering your test suite.
This will print the text in test report. There are other reporters as well which support this kind of features. Hope this solves the problem.

Related

how validation works in mongoose

I was reading documentation of mongoose: http://mongoosejs.com/docs/guide.html
It is said that validation occurs before saving document in the database.
And to turn this feature off we have to set option: validateBeforeSave to false.
However I have another decent Node.js tutorial example where they just use .validate as follows:
var course = new Course({});
course.validate(function(err) {
assert.ok(err);
assert.equal(err.errors['title'].kind, 'required');
course.title = 'Introduction to Computer Science';
assert.equal(course.title, 'Introduction to Computer Science');
var s = '0123456789';
course.title = '';
while (course.title.length < 150) {
course.title += s;
}
course.validate(function(err) {
assert.ok(err);
assert.equal(err.errors['title'].kind, 'maxlength');
++succeeded;
done();
});
});
I can't understand the underlying reason for using validate without setting validateBeforeSave option to false? Could someone please clarify how the provided code above works?
validateBeforeSave, as the name implies, validates the mongoose object before persisting it to database. This is a schema level check, which, if not set to false, will validate every document. It includes both built-in (like a Number cannot contain string or a required field should exist etc.) and custom defined validations.
validate does the same, only it has no concern with saving the document afterwards. It's the method on the object which you invoke, like course.validate(callback), and get to know if the object is valid or not through err in the callback.
Both are doing one and the same thing but at different times and different level. Also, both are not mutually exclusive, so one does not need to be set off for other to work.
As for the use case of validate, unit testing is one example. You may want to test your validators without the trouble of mocking save or setting up a test database. I believe the example is trying to do something like that, though not in a structured way.
As you said mongoose is fireing up validation before save operation, but there are some cases when you want to validate document schema without save. For this you can use validate method directly.
Your example from tutorial show us piece of code representing unit tests. So for example we can check methods which generate some model to save without saving him.
Also validate method could help when you have complicated action flow with many saves and dependencies. For example you want to save user dashboard model with proper structure but firstly you saving user profile. With validate method and for instance wrong dashboard structure you can check request and throw exception before saving user profile.
In the example code, they are using Async Custom Validator which you would understand better if you check this: http://mongoosejs.com/docs/validation.html#built-in-validators
They are used when standard validation is not enough and this is purely my observation that they are usually used in testing along with some testing framework and assetion library.

Is there exists any tool for generating a JavaScript Unit test from spying in on running code, say in browser?

I understand that taking time and thinking to write tests with proper assumptions is important. However something like this can serve as starting boilerplate code.
For example , consider a function
function sum(a,b) {
return a+b;
}
console.log(sum(3,4));
console.log(sum(0,2));
so we inject/include a function , i.e it listens
in on the input given to sum while it is running(like dojo connect, listens in on the arguments object for expected inputs and the result of the function for the expected output) and auto generates the test cases.
so the tool will automatically generate tests as
describe("sum tests", function(){
SpyOn(sum);
expect(sum(3,4).to.Equal(7));
expect(sum(0,1).to.Equal(1))
})
If something like this doesn't exist , I was thinking to attempt to build a basic version of this myself. I guess for complex inputs as objects ,may need to create spies for function call. ex -
sum.apply(null, Source.getInputs()).
so now need to mock the Source.getInputs function.
What other complications I may need to take into account in that case ?

What is a real unit test?

So for a while now I've been pondering what a real unit test should consist of. It's best to demonstrate this with an example, here's my angular service I want to test:
function stringUtils() {
return {
splitFilterString: splitFilterString
}
function splitFilterString (filterString) {
return filterString.split(':');
}
}
I've been thinking which of my 2 approaches best describes a "real" unit test for splitFilterString. (The examples are written with jasmine)
1 Test that String.prototype.split has been called.
You don't test any "real" examples with this, you just test that the function actually calls String.prototype.split and returns whatever that function returns. This has been my way of testing so far because you don't test "external" API's for doing what they tell you they (should) be doing.
it('should call split with ":" as an argument and return whatever split returns', function () {
var filterString = 'foo:bar';
spyOn(String.prototype, 'split').and.returnValue('foo');
expect(stringUtils.splitFilterString(filterString)).toBe('foo');
expect(String.prototype.split).toHaveBeenCalledWith(':');
});
2 Test for the actual expected output of the function.
I also like this approach because you test for actual input/output how the function is meant to be used. On the downside you're indirectly testing String.prototype.split here as well, you're testing if it actually does what it says it does.
it('should return the correct output', function () {
expect(stringUtils.splitFilterString('foo:bar')).toEqual(['foo', 'bar']);
expect(stringUtils.splitFilterString('foobar')).toEqual(['foobar']);
});
In the first example you are coupling the test with the implementation, that's the main difference.
This might get in your way later on if you find out that there's a superFastSplit that you want to use, because you need to change your code and your test.
So in this case the test is not providing real value because it might hold you back when you want to refactor: "I want to refactor that portion of code, but those damn tests mean I have to do everything twice!".
In the second example you are testing behaviour, so your code will allow you to use superFastSplit because you are not interested in how you get to your result, you are interested that the result is consistent across implementations.
EDIT After OP comment
In the case of an external API I would still follow the "don't harm my future self / colleague" path, so I would do the easiest thing, which IMHO is to use a module that mocks the external API, something like this:
nock('http://external.api.com')
.get('/end/point')
.reply(200);
Of course you have to be careful and don't try to cover too many scenarios, because you are basically deciding what the external API will return, so I would say I would just test the ok and nok scenarios here, and cover all the details in an integration test.
Under the covers what nock does is:
Nock works by overriding Node's http.request function. Also, it overrides http.ClientRequest too to cover for modules that use it directly.
You can always test for any side effect that the API call has in your code, but I feel that that approach is more difficult to follow when applying TDD.

Mocha tests on focus-related behaviors (Backbone/CoffeeScript app)

I have a Backbone app written in CoffeeScript. I'm trying to use Mocha (with Chai and Sinon) to write tests for DOM-related behaviors, but it seems that hidden fixtures (I'm using js-fixtures now but I've also tried this unsuccessfully with a hidden '#fixtures' div) don't register certain DOM-related behaviors which makes testing certain types of DOM-related behaviors (seemingly) impossible.
For example, my main app view has several subviews which are never rendered at the same time: when the app view renders subview A, it remembers the focused element of the currently active subview B (#_visibleView), saves that information on subview B, closes the subview B, and then renders subview A.
_rememberFocusedElement: ->
focusedElement = $ document.activeElement
if focusedElement
focusedElementId = focusedElement.attr 'id'
if focusedElementId
#_visibleView?.focusedElementId = focusedElementId
This works when I test it manually, but when I try to write unit tests for this behavior they fail because I can't set focus (e.g., via $(selector).focus()) to an element in a hidden div/iframe. (I have the same issue with functionality which listens for window resize events.)
I thought that if I changed $ document.activeElement to #$ ':focus" I might get different results, but that doesn't fix the issue.
Here is what the relevant parts of my Mocha (BDD) tests look like. This spec will print TEXTAREA to the console and then undefined, indicating that there is a textarea with id='transcription' but I can't set focus to it.
beforeEach (done) ->
fixtures.path = 'fixtures'
callback = =>
#$fixture = fixtures.window().$ "<div id='js-fixtures-fixture'></div>"
#appView = new AppView el: #$fixture
done()
describe 'GUI stuff', ->
it 'remembers the currently focused element of a subview', (done) ->
#appView.mainMenuView.once 'request:formAdd', =>
#appView._visibleView.$('#transcription').focus()
console.log #appView._visibleView.$('#transcription').prop 'tagName'
console.log #appView._visibleView.$(':focus').prop 'tagName'
done()
#appView.mainMenuView.trigger 'request:formAdd'
Is there any way that I can write unit tests for these types of behaviors?
Ok, first off let me clarify something: the term "unit test" means man different things to many people. Often times it becomes synonymous with "any test written using a unit test framework (like Mocha)". When I use the term "unit test" that's not what I mean: what I mean is a test that tests only a single unit of work (which, in a JS environment, will usually be a single function, but might be a whole class).
Ok, with that out of the way, if you really are trying to unit test your code, you're sort of taking the wrong approach. A unit test really shouldn't rely on anything outside the context of the function being tested, and so relying on the (external) DOM is where your problem lies.
Let's assume your focus-handling code is in a function called handleFocus (I don't know the actual method name). Consider the following test, which I'll write using JavaScript since my CoffeScript is rusty:
describe('#handleFocus', function() {
it('remembers the currently focused element of a subview', function() {
var setFocusStub = sinon.stub($.fn, 'focus');
appView._visibleView.handleFocus();
expect(setFocusStub.calledOnce).to.be(true);
});
});
The above is a bit of an over-simplification, but hopefully it illustrates the point. What you're really trying to check isn't whether the DOM (fake or real) does X; what you're trying check is whether your function does X. By focusing on that in your test, and relying on a stub that checks whether "X" happened or not, you completely eliminate the need for the DOM to be involved.
Now of course you might wonder: "well great, that helps me in test-land, but how do I know it will work in a real environment?" My answer to that would be that your (probably Selenium-based) acceptance tests should cover that sort of thing. Acceptance tests should check whether your overall code works in the real world, while unit tests should ensure that individual pieces of that code work in a fake environment.
The former is great for ensuring your customers don't see bugs, while the latter is great for figuring out exactly where those bugs come from, and for making it possible for you to refactor safely.

Using jasmine the correct way or creating a testAll-spec

I have to say I'm kinda stuck with using jasmine(-node) in (most probably) a slightly wrong way. Currently I have jasmine tests so, that they need to be run in a correct order. I would at the moment need to have a file that can collect and initiate the different jasmine-files in the correct order.
Now I appreciate advice, which show me other ways of making the testing work well and not necessarily just fix this immediate problem, my testing skills are fairly limited, mostly because as a long time solo-coder I haven't had that much use for them.
So the actual problem is that I have test-specs:
mapGenerator-spec.js // Initializes / generates a clean map.
orders-spec.js // Simulates orders given by players (turn based)
map-spec.js // tests the part which is used front-end and backend, creating map from components
moveOrders-spec.js // Generates a part of the turn by resolving orders -> moving units.
So simply the logic in a game is that first generates a map, order generate orders given by players
These need to be executed in the precise order, because they create database-entries that are dependant on the previous test. I would like to keep the tests as product-ready / real as possible and not try to skip the database-inserts / fetches. There is a separate test-database, where the tests are generated.
So can you advice me, what you think is the correct way to do this (if this is not a good way) and / or advice me, if needed, how can I sum up these tests to one collection test "testAll-spec.js", which would run the tests synchronously.
If you need something to happen before you run a test, then you should use beforeEach().
You can also nest jasmine tests, and run a beforeEach() within each test, as below:
describe('testInitialiser', () => {
var firstVariable;
beforeEach(() => {
firstVariable = 1;
});
it('should set firstVariable to 1', () => {
expect(firstVariable).toBe(1);
});
// this is a nested test - these tests will run after the above beforeEach.
describe('nested test ', () => {
// all tests within this describe will have access to firstVariable.
var secondVariable;
beforeEach(() => {
secondVariable = firstVariable + 1;
});
it('should set secondVariable to firstVariable + 1 ', () => {
expect(secondVariable).toBe(2);
});
});
});
Hope this helps.

Categories

Resources