I'm wondering if there is a way to get mocha to list all the tests that it will execute. I don't see any reasonable options when I list them using mocha --help; There are several reporters, but none appear designed to list the files that will be processed (or name the tests that will be run).
The way reporters work is by listening for events dispatched by mocha, these events are only dispatched when running a real test.
A suite contains a list of tests, so there is the info that you need. However, the suite is usually only initialized on run().
If you are ok with running mocha from nodejs instead of from the command line you can create this diy solution based on the code from Using-mocha-programmatically:
var Mocha = require('mocha'),
fs = require('fs'),
path = require('path');
// First, you need to instantiate a Mocha instance.
var mocha = new Mocha(),
testdir = 'test';
// Then, you need to use the method "addFile" on the mocha
// object for each file.
// Here is an example:
fs.readdirSync(testdir).filter(function(file){
// Only keep the .js files
return file.substr(-3) === '.js';
}).forEach(function(file){
// Use the method "addFile" to add the file to mocha
mocha.addFile(
path.join(testdir, file)
);
});
// Here is the code to list tests without running:
// call mocha to load the files (and scan them for tests)
mocha.loadFiles(function () {
// upon completion list the tests found
var count = 0;
mocha.suite.eachTest(function (t) {
count += 1;
console.log('found test (' + count + ') ' + t.title);
})
console.log('done');
});
Related
I have a google doc script that executes a function in a google script library I created (Call - calls Lib1.lib1function() ). I'm wondering if I set a breakpoint in the IDE debugger in the google doc script where I'm making a call to a function in the library script and get the debugger to expose the execution of the library function. ie. keep tracking execution in the called library. Or is my only debugging technique in the script library, Logger.log() and writing info to the console?
The only other debugging solution I can think of is to copy the actual library script (Lib1) to a new Google Doc script file and test and execute the code there. Once I'm done creating and testing the code, I would then copy it back to the library script for other docs to use.
Unfortunately, you cannot debug a library on another project. The optimal way to debug a library is to create another function in your library script that will call the library method or create unit tests.
Here I used QUnit to create unit test for my library method sumArray.
QUnit.helpers(this);
function sumArray(arr) {
var sum = 0;
for ( var i = 0; i < arr.length; i++ ){
if(isNaN(arr[i])){
return "Non-numerical data detected";
}else{
sum = sum + arr[i];
}
}
return sum;
}
function testFunction(){
testingSumArray();
}
function testingSumArray(){
QUnit.test( "sumArray testing", function() {
expect(2);
equal( sumArray([1,2,3,4,5]), 15 , "Test for Array [1,2,3,4,5], Output is 15" );
equal( sumArray([1,'a','b','c',4]), "Non-numerical data detected", "Test for Array [1,'a','b','c',4]: Output is Non-numerical data detected" );
});
}
function doGet( e ) {
QUnit.urlParams( e.parameter );
QUnit.config({ title: "sumArray Unit tests" });
QUnit.load( testFunction );
return QUnit.getHtml();
};
Output:
To learn how to use QUnit in Apps Script, you can check the documentation here.
Every time a Protractor element locator fails, it prints an error and continues down a horrible path of endless cascading failures in my spec and suite. Every test that follows depends on the element locator finding its element, and depends on the current spec passing.
I would like to keep the web page under test open while I use the console. The goal is to debug the current state of the page and investigate why the element locator may have failed to find its target.
I'm not too concerned about failing the entire suite and exiting on the first spec failure (I've seen other answers on --fail-fast and stopping on first spec failure.) This is not the approach I would like to take. I want to set a breakpoint, and inspect the environment while the page is running.
Maybe there's something like a Jasmine option for doThisOnFailure: () => { debugger }, which would work for me I think.
I really do not like the solution of using a spec reporter to execute during afterEach and check the failed spec count on the Jasmine environment for the entire spec function. I want to immediately know when an element locator has failed and immediately break as soon as it has failed.
Maybe something really gross would work $('element').click().catch(() => { debugger }).
EDIT: Please, note that I am asking about breaking in a spec, not breaking at the end of the spec.
it('should execute deadly code', function () {
p.navigation.openStorageConfigTab()
$$('.bad-selector').get(0).click() /* IMPORTANT: I want to break here */
p.volume.navigateTo()
})
it('should not execute this spec', function () {
$$('.bad-selector').get(0).click()
})
And the output
✗ should execute deadly code
- Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(css selector, .bad-selector)
✗ should not execute this spec
- Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(css selector, .bad-selector)
I can recommend you the approach I use, and I hope you can take it from here
Overall approach is to wait until until you type close/ command in browser url:
await browser.waitForAngularEnabled(false);
await browser.wait(
async () => {
let url = await browser.getCurrentUrl();
return url.includes('close/');
},
5 * 60 * 1000,
'Keep-alive timeout reached, closing the session...'
);
The question is when you want to call it. I use the advantage of onComplete callback function in config file. When it's called, the browser is still available. So once all tests are completed, it doesn't exit for 5 minutes unless I submit close/ to the url field. Obviously that can be conditional, by adding something like if (DEBUG === true)
A downside of this setup is it's called when all tests are completed, and it's possible your spec has navigated away from the page where there was error. So what you can also do is to use advantage of jasmine reporter (if you use jasmine). Roughly, you just need to add this to your onPrepare func:
jasmine.getEnv().addReporter({
jasmineStarted: function(suiteInfo) {},
suiteStarted: function(result) {},
specStarted: function(result) {},
specDone: async function(spec) {
if (spec.status === 'failed') {
await browser.waitForAngularEnabled(false);
await browser.wait(
async () => {
let url = await browser.getCurrentUrl();
return url.includes('close/');
},
5 * 60 * 1000,
'Keep-alive timeout reached, closing the session...'
);
await browser.close();
process.exit(35);
}
},
suiteDone: function(result) {},
jasmineDone: function(result) {},
});
So if any it block has failed status, then it'll stop. BUT, I have not tested it, I'll leave it up to you. And second, I didn't think about what will happen to the rest of queued specs since you're redirected to non existing url close/, but I believe it'll still work for you. Worst case scenario, you can play around and make it continue or close the browser instance, as long as you understood the concept
P.S.
I modified the code to close the browser when you type close/, by adding
await browser.close();
process.exit(35);
I tested this code with the following scenarios:
happy path: all 5 it are successful
first element finder of second it block fails
second element finder of second it block fails
All passed. The code works as expected
i tried to write a cake script for my ci. I'm new to cake.
As part of this script I wanted to execute MSpec tests.
Task("Run-Tests")
.IsDependentOn("Build")
.Does(() => {
var configurationIntoTests = configuration + "/*.Tests.dll";
MSpec("../src/ERP.BusniessLogic.Tests/bin" + configurationIntoTests);
MSpec("../src/ERP.DapperDataAccess.Tests/bin" + configurationIntoTests);
MSpec("../src/ERP.DomainModel.Tests/bin" + configurationIntoTests);
MSpec("../src/ERP.Shared.Tests/bin" + configurationIntoTests);
MSpec("../src/ERP.Web.Tests/bin" + configurationIntoTests);
});
I assumed that it would give a console output as MSBuild does, since it has no return value. See API
As you may expect there is no console output, which means I don't know what the result of the tests is.
How can i get this result to report it to my ci?
Using the MSpec(string, MSpecSettings) overload will let you set what kind of report, it's name and where to put it using the MSpecSettings class.
MSpec("../src/Progresso.ERP.BusniessLogic.Tests/bin/" + configurationIntoTests,
new MSpecSettings {
ReportName = "Progresso.ERP.BusniessLogic.Tests",
HtmlReport = true,
OutputDirectory = "./build"
});
Update
Studying your example code I notice a / is missing before configuration
var configurationIntoTests = configuration + "/*.Tests.dll";
should be
var configurationIntoTests = "/" + configuration + "/*.Tests.dll";
Otherwise i.e. bin/Debug/ becomes binDebug and the test globber will not find any assemblies and MSPec won't even be executed.
I'd like to be able to extend the mocha test results and listen to them from the available mocha object. First, I'm looking at getting the "passes" results.
It looks like they might be subscribed to from suite but I'm not sure how...
I've tried the following which I thought would listen to the end of all of my tests:
var suite = mocha.suite.suites[0];
suite.on("end", function(e){ console.log(e, "mocha - heard the end of my test suite"); } );
My simple hack which works but isn't elegant at all - sad really:
setTimeout(function(){
var passes = $(".passes").find("em").text();
console.log("ui - heard the end of my test suite - passes: " + passes);
}, 500);
I did some more digging in mocha.js and finally discovered that mocha.run() actually returns the runner which emits all the events I was looking.
The original example I was using only had: mocha.run()
So if Mocha.run() returns a runner, then I realized that I could subscribe to it:
var runner = mocha.run();
var testsPassed = 0;
var onTestPassedHandler = function(e){
testsPassed++;
console.log("onTestPassedHandler - title: " + e.title + " - total:" + testsPassed);
};
runner.on("pass", onTestPassedHandler);
/**
* These are all the events you can subscribe to:
* - `start` execution started
* - `end` execution complete
* - `suite` (suite) test suite execution started
* - `suite end` (suite) all tests (and sub-suites) have finished
* - `test` (test) test execution started
* - `test end` (test) test completed
* - `hook` (hook) hook execution started
* - `hook end` (hook) hook complete
* - `pass` (test) test passed
* - `fail` (test, err) test failed
*/
much better!
You can also get similar events at
mocha.suite.beforeEach(function() {} )
mocha.suite.afterEach(function() {} )
mocha.suite.afterAll( function() {} )
I'm having a problem getting casperjs test to exit after execution, I have to hit CTL-C to exit execution. I'm on OSX 10.7 with casperjs 1.1 devel.
To test this wasn't my code I simply copied this sample from the docs:
var casper = require("casper").create();
function Cow() {
this.mowed = false;
this.moo = function moo() {
this.mowed = true; // mootable state: don't do that at home
return 'moo!';
};
}
casper.test.begin('Cow can moo', 2, function suite(test) {
var cow = new Cow();
test.assertEquals(cow.moo(), 'moo!');
test.assert(cow.mowed);
test.done();
});
And I get the following output
casperjs test cow-test.js
Test file: cow-test.js
# Cow can moo
PASS Subject equals the expected value
PASS Subject is strictly true
I then have to hit CTL-C to stop execution. Am I missing something to stop execution?
Per https://github.com/n1k0/casperjs/issues/593#issuecomment-23062361, the problem was that I had created a casper instance at the top of the file, which the documentation warns you not to do.
The solution was to remove the var casper = require("casper").create(); line.