【问题标题】:PhantomJS QUnitTeamCityDriver QUnit test runPhantomJS QUnitTeamCityDriver QUnit 测试运行
【发布时间】:2012-10-10 12:21:40
【问题描述】:

我想在 TeamCity 中对 JavaScript 使用单元测试。

我正在使用 QUnit,并且我看到一些建议使用 phantomjs 和 QUnitTeamCityDriver 的地方。我只是无法让它工作......

我在这方面没有太多经验,似乎甚至无法让 phantomjs 在命令行中运行单元测试。

我确实从 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 有一些简单的测试是否有效,如果我用 simple_test.html 试试的话。

html 中的其他引用文件当然在各自的文件夹中。

phantomjs.exe、tests.js 和 simple_test.html 位于我调用的目录的根目录中。

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

(这不起作用,所以我想在将命令行放入 TeamCity 之前先在实际命令行上进行测试)

我尝试过的一些事情:

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

结果:解析错误或找不到变量:测试

请有人指出我正确的方向,给我一个例子,告诉我我做错了什么?非常感谢。

【问题讨论】:

    标签: javascript unit-testing qunit phantomjs


    【解决方案1】:

    如果您的技术堆栈是匹配的,我已经成功使用 Chutzpah

    除其他外,它还通过处理 kabaros 描述的 phantomjs 调用以及提供 TeamCity 和 Visual Studio 集成来为您完成繁重的工作。

    【讨论】:

    • nice one woodysan .. 似乎比一年前最后一次更新的 qunitTeamCityDriver 活跃得多,从现在开始我肯定会使用它。
    • 这正是我想要的 :-) 谢谢 Woodysan!
    【解决方案2】:

    简短的回答是,您需要运行:

    phantomjs.exe script-runner.js simple_test.html
    

    长答案:

    您将需要一个 javascript 文件来调用您的测试,我为此编写了许多变体,但我发现最好的一个是带有 QUnitTeamCityDriver https://github.com/redbadger/QUnitTeamCityDriver 的那个。即使我不与 TeamCity 合作,我也使用了一些小改动。

    这里是文件的内容,可能有一些变化(我在最近的一个项目中使用过它),但你应该在 github 上找到原始文件(称之为 script-runner.js 并放入相同的为方便起见,将文件夹命名为 phantom.exe):

    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's 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 (i.e. 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);
        }
    });
    

    这基本上会打开您的 html 页面并对其进行解析。这对我来说是一个令人困惑的部分,phantomjs 最终是一个浏览器,你应该将这个脚本传递给它,最终将打开一个 HTML 页面而不是 Javascript 文件。所以你这样调用phantomjs:

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

    所以你的情况是:

    phantomjs.exe script-runner.js simple_test.html
    

    难题的最后一点是,在包含测试的 html 页面中,您应该添加对 javascript 文件的引用,即引用中名为 QUnitTeamCityDriver.js 的文件。这将连接到 qUnit 事件并将它们引导到幻象,以决定什么是通过的测试,什么是失败的测试。文件内容(同样你可以在 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));
        };
    }
    

    这基本上与 QUnit 定义的回调挂钩,并将消息发送到由 phantomjs 显示的控制台。 QUnit 回调文档可在此处找到:http://api.qunitjs.com/category/callbacks/

    至于与 TeamCity 挂钩,它可能只是构建步骤定义中的一个设置,用于检查输出中的某个字符串(例如,输出中存在“[testFailed]”表示失败),我已经使用 CruiseControl 完成了它,并围绕它创建了一个 Nunit 包装器。最后,同样的概念适用,您只需解析 phatomjs 输出以检查是否存在 [testFailed] 或任何指示失败的字符串。

    【讨论】:

    • 我喜欢这个解释,因为它可以让我准确地理解发生了什么......不过,使用这些文件(我承认,我之前下载的脚本文件有一些错误),并完全按照您(或文档)的建议使用它们,我仍然收到错误“找不到变量 QUnit” - 即使它是在 qunit-1.10.0.js 中定义的,它在 QUnitTeamCityDriver 之前的 html 文件中引用.phantom.js。我显然错过了一些东西......
    • 我记得必须直接从 jquery 站点获取 QUnit,因为 Github 上的版本已经过时.. 你可以尝试在以下位置获取最新版本:code.jquery.com/qunit/qunit-1.10.0.js
    • 还可以试试他们的 Github 示例附带的版本:github.com/redbadger/QUnitTeamCityDriver/blob/master/…,我认为它稍旧
    • 我都试过了,我更喜欢使用 1.10.0。在浏览器中完美运行。
    • 奇怪.. 是否将这些消息中的任何一条记录到控制台输出:console.log("[testSuiteStarted etc...
    【解决方案3】:

    除了上面提供的建议,我建议使用 qunit 提供的新 phantomjs qunit runner:

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

    如果您有错误的异步测试,请查看我的拉取请求:

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

    【讨论】:

    • 该拉取请求已合并,但我仍然遇到一些测试未正确报告失败的问题。我不再积极关注它,但当我回到它时会发布任何更新。
    • 可以将此运行器与此 qunit.teamcity.js 适配器结合使用,并使用以下命令运行测试:phantomjs qunit/addons/phantomjs/runner.js &lt;yourtestfile&gt;.html
    猜你喜欢
    • 1970-01-01
    • 2012-10-13
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多