2

我正在尝试解决单元测试问题。

我曾经有一个大部分工作的 Maven -> PhantomJS -> Qunit 设置,但它是不可预测的,所以我把它拆开来尝试修复它。

我升级了软件:

Qunit: 1.11.0
PhantomJS: 1.8
Phantom Qunit Runner Latest: https://github.com/jquery/qunit/tree/master/addons/phantomjs

我看到 Web GUI 工作正常。它运行并通过了所有 102 项测试。控制台打印这个:

$ phantomjs --disk-cache=false runner.js http://localhost/ui/dcx/test.html
$ Took 16ms to run 0 tests. 0 passed, 0 failed.

如果我在运行程序中注释掉 exit 命令,它会多次打印 QUnit.done 的控制台输出。

$ phantomjs --disk-cache=false runner.js http://localhost/ui/dcx/test.html
$ PhantomJS successfully loaded a page
$ QUnit.done callback fired
$ Took 15ms to run 0 tests. 0 passed, 0 failed.
$ QUnit.done callback fired
$ Took 1840ms to run 102 tests. 102 passed, 0 failed.
$ QUnit.done callback fired
$ Took 1841ms to run 102 tests. 102 passed, 0 failed.
$ QUnit.done callback fired
$ Took 1842ms to run 102 tests. 102 passed, 0 failed.
$ QUnit.done callback fired
$ Took 1848ms to run 102 tests. 102 passed, 0 failed.
$ ^C
$

在我看来,Qunit.done 回调执行得太快了,然后执行了多次。

有人知道为什么回调会触发吗?

我的测试内容和登录延迟可能是相关的。我使用 AMD 模块来定义测试并使用 curl.js 来引入它们。在安全登录之前什么都不会发生:

curl(['dolla'], function($){
        $.ajax({
        type: 'POST',
        url: '/svc/j_spring_security_check',
        data: {
            j_username: '7',
            j_password: '7'
        },
        success: function() {
            loadTests()
        }
    });
})
var loadTests = function () {
    curl([
        // Unit tests
         'dcx/dataControls/activity.test'
        , 'dcx/dataControls/eventList.test'
        , 'dcx/dataControls/mapViewer.view.test'
        , 'dcx/pages/deviceDetails.view.test'
        , 'dcx/pages/login.test'
        , 'dcx/pages/nodeProfiles.test'
        , 'dcx/pages/settings.view.test'
    ], function() {},  function(ex) { throw new Error(ex) })
})

编辑:我认为,我认为这是根本原因。如果您在空白页上包含 QUnit,它会立即调用 QUnit.begin 和 QUnit.done。我需要延迟 Qunit 的执行,直到安全登录成功并且 curl 引入了我的单元测试。有没有办法延迟 QUnit 的启动,但仍然保持 Qunit 对象可用?我不能使用 stop(),因为有很多异步测试会调用 start()。

4

3 回答 3

2

找到了答案。您可以将 QUnit 配置为不启动,然后在加载所有测试时手动启动它。这可以防止 Qunit.done 的重复调用,这是此问题的根本原因。

http://forum.jquery.com/topic/are-qunit-and-requirejs-compatible#14737000001967123

于 2013-02-28T21:46:46.777 回答
0

这是一种方法——如果没有测试结果,则修改运行器以不退出。 https://gist.github.com/SimpleAsCouldBe/5059623

但这不起作用——只要清除测试堆栈,就会触发 Qunit.done。在像 Curl/Require.js 这样的异步加载环境中,这可能随时发生。

于 2013-02-28T20:03:51.117 回答
0

这是如果您不想使用require. 例如,可能在浏览器上下文中。

花了很长时间找到一种方法将脚本(和样式表)的加载转换为Promises(见这里),然后我发现 QUnit 测试套件在所有这些加载之前就开始运行的大问题。通常,在开始时,少数测试会抱怨某个变量或类未定义,尽管后来的测试没有那么困难。

您可以通过以下方式停止自动启动:

QUnit.config.autostart = false;

...似乎只需将其放在几个文件之一中就足够了。

那么,要开始 QUnit 测试,你必须去QUnit.start();. 但是,也许可以理解,您不能从 QUnit 测试运行的任何代码中执行此操作。这变得复杂了。最后,我在我的应用程序启动代码中做到了这一点:

await this.loadInjectedFile( GLOBAL_SCRIPT );
await this.loadInjectedFile( DBFORM_SCRIPT );
await this.loadInjectedFile( UDV_SCRIPT );
await this.loadInjectedFile( REACTIVITY_SCRIPT );
console.log( '... injected files loaded' );
// to allow QUnit to start testing
window.QUnitGreenLight = true;

...严格来说是一件很淘气的事情(允许与测试相关的代码潜入您的应用程序代码中)。可能会找到一种更细分的方法。

然后,在您启动测试的 HTML 文件中内联:

<script>
    const tryToStartTesting = function(){
        setTimeout( function(){
            if( window.QUnitGreenLight ){
                QUnit.start();
            }
            else {
                console.log( 'QUnit green light not yet given!' );
                tryToStartTesting();
            };
        }, 10 );
    };
    tryToStartTesting();
</script>

...实际上,在发出绿灯之前似乎需要百分之几秒。

也许有点斗志昂扬,但它似乎有效。

于 2020-07-19T17:15:04.023 回答