【问题标题】:Angular 2 for TypeScript app testing - specs appear multiple times in jasmine用于 TypeScript 应用程序测试的 Angular 2 - 规范在 jasmine 中出现多次
【发布时间】:2016-08-13 20:53:04
【问题描述】:

我已按照本教程测试 Angular 2 应用程序:https://angular.io/docs/ts/latest/guide/testing.html

在完成First app test 部分并转到unit-tests.html 后,我看到我的规范报告多次出现:


虽然我没有对教程代码进行任何更改,但这里是我的 unit-tests.html 的快速参考:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>Ng App Unit Tests</title>

    <link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">

    <script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
    <script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
    <script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
</head>
<body>
<!-- #1. add the system.js library -->
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>

<script>
    // #2. Configure systemjs to use the .js extension
    //     for imports from the app folder
    System.config({
        packages: {
            'app': {defaultExtension: 'js'}
        }
    });

    // #3. Import the spec file explicitly
    System.import('app/hero.spec')

    // #4. wait for all imports to load ...
    //     then re-execute `window.onload` which
    //     triggers the Jasmine test-runner start
    //     or explain what went wrong.
            .then(window.onload)
            .catch(console.error.bind(console));
</script>
</body>

</html>

hero.spec.ts

import {Hero} from './hero';

describe('Hero', () => {
    it('has name', () => {
        let hero:Hero = {id: 1, name: 'Super Cat'};
        expect(hero.name).toEqual('Super Cat');
    });
    it('has id', () => {
        let hero:Hero = {id: 1, name: 'Super Cat'};
        expect(hero.id).toEqual(1);
    });
});

知道可能出了什么问题吗?

【问题讨论】:

  • 对于 Angular2.0.0-rc.5 的教程,这个问题仍然存在,即 hero.ts 的简单测试的结果增加了三倍。请注意,教程中的下一组测试,即 my-uppercase.pipe.ts,没有三倍的结果。所以不仅仅是所有的结果都增加了两倍,只是一些。我猜这与事情的挑剔时间有关,例如简单测试完成的时间与需要其他内容(其他下载?)的更复杂的测试完成的时间,例如,浏览器窗口完成加载和 jasmine 重新启动的时间。

标签: typescript jasmine angular systemjs


【解决方案1】:

由于我之前的评论被标记为已删除,因此我写下我的最终解决方案以消除该问题。此解决方案有效,唯一的问题是它第一次显示带有文本“未找到规范”的 HTML 页面,但是当所有模块加载时,它会显示所有规范及其结果。

这个方案被Manning Early Access Program的《Angular 2 Development with TypeScript v7 MEAP》一书采用:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <title>Unit Tests</title>
    <link rel="stylesheet" href="node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
    <!-- #1. Polyfills -->
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <!-- #2. Zone.js dependencies -->
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/zone.js/dist/async-test.js"></script>
    <script src="node_modules/zone.js/dist/fake-async-test.js"></script>
    <!-- #3. Add specs dependencies -->
    <script src="app/treeNode.spec.ts"></script>
    <script src="app/template.spec.ts"></script>
    <script src="app/services/tree.side.service.spec.ts"></script>
    <script src="app/services/tree.service.spec.ts"></script>
    <!-- #4. Add Jasmine dependencies -->
    <script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
    <script src="node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
    <script src="node_modules/jasmine-core/lib/jasmine-core/boot.js"></script>
    <script src="node_modules/jasmine-expect/dist/jasmine-matchers.js"></script>
    <!-- #5. Add the system.js library -->
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script>System.packageWithIndex = true;</script>
    <script src="systemjs.config.js"></script>

    <script>
        // #6. Configure SystemJS to use the .js extension for imports from the app folder
        System.config({
            packages: {
                'app': {defaultExtension: 'js'}
            }
        });

        var SPEC_MODULES = [
            'app/treeNode.spec',
            'app/template.spec',
            'app/services/tree.side.service.spec',
            'app/services/tree.service.spec'
        ];

        /**
         * #7. Import the spec files explicitly
         */
        Promise.all([
            System.import('@angular/core/testing'),
            System.import('@angular/platform-browser-dynamic/testing')
        ])
        .then(function (modules) {
            var testing = modules[0];
            var testingBrowser = modules[1];
            testing.TestBed.initTestEnvironment(testingBrowser.BrowserDynamicTestingModule, testingBrowser.platformBrowserDynamicTesting());
            return Promise.all(SPEC_MODULES.map(function (module) {
                return System.import(module);
            }));
        })
        .then(window.onload)
        .catch(console.error.bind(console));
    </script>
</head>
<body>
</body>
</html>

我希望这个解决方案对您有用。

【讨论】:

  • 我认为这应该是正确/可接受的解决方案。我一直在关注官方在线 Angular2(版本 2.0.0-rc.5)教程,hero.ts 测试结果增加了三倍(如这里的原始问题)但不是my-uppercase.pipe.ts 测试结果(未在问题)。我使用了这个解决方案,用教程的...spec(.ts) 文件替换了SPEC_MODULES 数组。与其他一些已发布的答案相比,此解决方案 (A) 将不适当的结果减少了三倍至单个结果,而且 (B) 维护了后续测试的实施和报告。
【解决方案2】:

我无法重现您的问题。看到这个 plunkr:https://plnkr.co/edit/viMSZD?p=preview.

我看到的唯一区别是我在 Jasmine 之前包含了 SystemJS 库文件:

<script src="https://code.angularjs.org/tools/system-polyfills.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine-html.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/boot.js"></script>

【讨论】:

  • 只是猜测,但我想知道原始问题是否在这里没有重现,因为依赖项是从“远方”加载的(即"https...")。在遵循官方在线 Angular2.0.0-rc.5 教程后,我确实得到了三倍的不适当结果,但是,例如,jasmine.js 是在本地加载的,即来自&lt;script src="node_modules/jasmine-core/lib/jasmine-core/jasmine.js"&gt;&lt;/script&gt;。因此,这个答案并不能解决问题,但它确实提供了一些诱人的证据来说明为什么有时会发生问题,但并非总是如此,即可能与相对加载时间有关。
  • 我也在学习本教程,并在 Jasmine 真正为我(本地)工作之前包含 SystemJS 库文件。但我同意这可能只是掩盖了问题。
【解决方案3】:

我有完全相同的问题(测试用例出现 3 次而不是 1 次)。

为了修复它,我删除了对 System.import('app/hero.spec') Promise 的 .then(window.onload) 调用。

似乎 SystemJS 模块能够在浏览器引发窗口加载事件之前加载 hero.spec.js。这将使随后对 window.onload 函数的调用过时。

【讨论】:

  • 此解决方案不适用于浏览器引发窗口加载事件后加载的规范。我发现的一个(丑陋的)解决方法是延迟执行将它们包含在 setTimeout 中的规范。有关详细信息,请参阅here
  • 这确实“解决”了问题,但不是以适当的方式。我一直在关注 Angular2 教程(现在是 rc.5 版),测试结果是原始问题的三倍。然而,这只适用于 Hero 测试,即一些不需要 Angular 的极其简单的测试。教程中的下一组测试,测试管道,没有增加三倍。实施此解决方案将原始的三重结果减少为适当的单个结果,但随后的测试结果将被完全跳过。因此,此解决方案不是合适的完整解决方案。
  • 我同意,这不应该是公认的答案。事实上,正如@AndrewWillems 所指出的,它实际上会导致其他测试失败。
【解决方案4】:

如果我使用lite-server,我可以重现这种奇怪的行为。如果您按照 angular2 站点上的示例进行操作,您会发现他们使用的是 live-server(注意“v”而不是“t”)。使用live-server jasmine 可以正确呈现我的测试。将browser-sync 魔法注入到 html 中可能存在一些问题?

【讨论】:

  • 我不知道当您最初在 2016 年 6 月 22 日发布此答案时,官方在线 Angular2 教程的状态是什么,但当前发布的教程是为与 Angular2 版本 rc.5 一起使用而发布的在谷歌搜索的教程中的任何地方都不会显示“live-server”,而“lite-server”确实会出现在类似的搜索中。因此,我真的不认为这是通往解决方案的正确路径,并且可能会通过例如提供误导性的“正确”结果。 (只是在这里猜测),强制浏览器加载其他“东西”,延迟测试,这使得它们不会在 window.onload 上重复。
【解决方案5】:

我遇到了同样的问题,在导入核心 shim 库后,问题消失了。还要确保将其作为第一个脚本导入。

 <script src="https://unpkg.com/core-js/client/shim.min.js"></script>

【讨论】:

    猜你喜欢
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 2015-03-21
    • 2018-01-22
    • 1970-01-01
    • 2017-08-17
    相关资源
    最近更新 更多