PhantomJS QUnitTeamCityDriver QUnit Test Test

I would like to use unit testing for JavaScript in TeamCity.

I use QUnit and I saw a couple of places that suggest using phantomjs and QUnitTeamCityDriver. I just couldn't get it to work ...

I don't have much experience with this, and I can't even get phantomjs to run unit tests on the command line.

I literally copied an example from QUnitTeamCityDriver: simple_test.html

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>QUnit Example</title> <link rel="stylesheet" href="test_tools/qunit-1.10.0.css"> <script type="text/javascript" src="resources/jquery-1.8.1.js"></script> <script type="text/javascript" src="test_tools/qunit-1.10.0.js"></script> <script type="text/javascript" src="qunit_teamcity_driver/QUnitTeamCityDriver.js"></script> <script type="text/javascript" src="tests.js"></script> </head> <body> <div id="qunit"></div> <h1 id="qunit-header">QUnit example</h1> <h2 id="qunit-banner"></h2> <div id="qunit-testrunner-toolbar"></div> <h2 id="qunit-userAgent"></h2> <ol id="qunit-tests"></ol> <div id="qunit-fixture">test markup, will be hidden</div> </body> </html> 

tests.js has some simple tests that work or not if I try using simple_test.html.

Other link files in html, of course, are in the corresponding folders.

phantomjs.exe, tests.js and simple_test.html are in the root of the directory from which I am calling.

Directions for building TeamCity:

 Add a "Command Line" Build Step to your build in TeamCity which executes Tests.htm via PhantomJS Command executable: C:\PhamtomJS\phantomjs.exe Command parameters: \Scripts\QUnitTeamCityDriver.phantom.js Tests.htm 

(which does not work, so I want to test the actual command line before embedding it in the command line inside TeamCity)

Some things I tried:

 phantomjs.exe tests.js phantomjs.exe tests.js simple_test.html phantomjs.exe simple_test.html phantomjs.exe test_tools\qunit-1.10.0.js tests.js simple_test.html phantomjs.exe qunit_teamcity_driver/QUnitTeamCityDriver.phantom.js simple_test.html 

result: either a parsing error or a variable not found: test

Please, can someone point me in the right direction, give me an example, tell me what I'm doing wrong? Thank you very much.

+4
source share
3 answers

If your technology stack is a coincidence, I have had success using Chutzpah .

Among other things, it does the hard work for you, dealing with calls to and from phantomjs described by kabaros, and also provides TeamCity and Visual Studio integration.

+6
source

short answer: you need to run:

 phantomjs.exe script-runner.js simple_test.html 

Long answer:

You will need a javascript file that will call your tests, I wrote many variations of this, but the best one I found is with QUnitTeamCityDriver https://github.com/redbadger/QUnitTeamCityDriver . I used with minor changes, although I do not work with TeamCity.

Below is the contents of the file with some changes (I used it in one of my recent projects), but you should find the original on github (name it script -runner.js and enter the same folder as phantom.exe for convenience):

 function waitFor(testFx, onReady, timeOutMillis) { var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timout is 3s start = new Date().getTime(), condition = false, interval = setInterval(function () { if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) { // If not time-out yet and condition not yet fulfilled condition = (typeof (testFx) === "string" ? eval(testFx) : testFx()); //< defensive code } else { if (!condition) { // If condition still not fulfilled (timeout but condition is 'false') console.log("'waitFor()' timeout"); phantom.exit(1); } else { // Condition fulfilled (timeout and/or condition is 'true') typeof (onReady) === "string" ? eval(onReady) : onReady(); //< Do what it supposed to do once the condition is fulfilled clearInterval(interval); //< Stop this interval } } }, 100); //< repeat check every 250ms }; var page = new WebPage(); // Route "console.log()" calls from within the Page context to the main Phantom context (ie current "this") page.onConsoleMessage = function (msg) { console.log(msg); }; page.open(phantom.args[0], function (status) { if (status !== "success") { console.log("Unable to access network"); phantom.exit(1); } else { waitFor(function () { return page.evaluate(function () { var el = document.getElementById('qunit-testresult'); if (el && el.innerText.match('completed')) { return true; } return false; }); }, function () { phantom.exit(); }, 10000); } }); 

This will open your html page and parse it. That was one of the confusing things for me, phantomjs is the browser at the end, you have to pass this script to it, which will eventually open the HTML page, not the Javascript file. Therefore you call phantomjs as follows:

 phantomjs.exe script-runner.js [path to file containing tests] 

so in your case it will be:

 phantomjs.exe script-runner.js simple_test.html 

The last bit of the puzzle is that on your html page containing the test, you must add a link to the javascript file, this is a file called QUnitTeamCityDriver.js in your links. This is what will connect to qUnit events and send them to phantom to decide if the test passed and which failed. The contents of the file (again, you can probably find the best updated version on the project page on github):

 /* Reference this file in the html files of the QUnit tests Based on the work on this team city driver: https://github.com/redbadger/QUnitTeamCityDriver/ */ if (navigator.userAgent.indexOf("PhantomJS") !== -1) { String.prototype.format = function () { var args = arguments; return this.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : '{' + number + '}'; }); }; var suiteName = "QUnit Tests"; var currentTestName = ""; var hasBegun = false; qunitBegin = function () { console.log("[testSuiteStarted name='{0}']".format(suiteName)); }; /* QUnit.testStart({ name }) */ QUnit.testStart = function (args) { if (!hasBegun) { qunitBegin(); hasBegun = true; } currentTestName = args.name; }; QUnit.moduleStart = function (args) { console.log("Module started: {0}".format(args.name)); }; /* QUnit.log({ result, actual, expected, message }) */ QUnit.log = function (args) { var currentAssertion = "{0} > {1}".format(currentTestName, args.message); //console.log("[testStarted name='{0}']".format(currentAssertion)); if (!args.result) { console.log("**[testFailed] type='comparisonFailure' name='{0}' details='expected={1}, actual={2}' expected='{1}' actual='{2}'".format(currentAssertion, args.expected, args.actual)); } console.log("[testFinished] name='{0}'".format(currentAssertion)); }; /* QUnit.done({ failed, passed, total, runtime }) */ QUnit.done = function (args) { console.log("[testSuiteFinished name='{0}']".format(suiteName)); }; } 

This basically intercepts the callbacks defined by QUnit and sends a message to the console, which are shown by phantomjs. The QUnit callback documentation is here: http://api.qunitjs.com/category/callbacks/

As for connecting to TeamCity, perhaps it’s just a parameter to determine the build step for checking a specific line in the output (for example, the presence of β€œ[testFailed]” in the output indicates a failure), I did this with CruiseControl and also created a Nunit wrapper around it. At the end, the same concept is used, you simply parse the output of phatomjs to check for the presence of [testFailed] or any line that indicates a failure.

+2
source

In addition to the tips above, I would suggest using the new phantom qunit runner with qunit:

https://github.com/jquery/qunit/tree/master/addons/phantomjs

And look at my pull request if you have failed asynchronous tests:

https://github.com/jquery/qunit/pull/415

+2
source

Source: https://habr.com/ru/post/1440873/


All Articles