跨Karma单元测试和量角器端到端测试共享测试库

时间:2018-11-27 14:57:30

标签: javascript jquery angularjs protractor karma-runner

我们有一个UI开发库,该库由基于Angular JS构建的小部件组成。让我们以“ header-widget”为例-用Angular JS构建的标头容器,但如果它具有特定的功能,则该标头容器位于顶部。

说这个小部件的HTML代码如下:

<header class="my-header">
    <div ng-if="configuration.hasTitle">
        <h1 class="my-header-title-text">
            <span class="my-header-title-text">This is a main title</span>
            <span class="my-header-subtitle-text">This is a subtitle</span>
        </h1>
    </div>
</header>

我可以使用Karma创建单元/集成测试,即在某一时刻我将具有以下内容:

element = angular.element("<header config=\"config\"></header>");
$compile(element)(myScope);
myScope.$digest();

expect(element.find(".my-header-title-text").text().trim()).toBe("This is a main title");

并且我可以使用量角器创建端到端测试,即在某一时刻,我将具有以下内容:

describe('Some end to end spec', function () {
    it('should have the right title', function () {
        let title = element(by.css(".my-header .my-header-title-text"));
        expect(title.getText()).toMatch("This is a main title");
    });
});

假设开发人员更改了标题,并且标题的新类变为“ my-header-MAIN-title-text”。我必须去单元/集成测试中的所有地方以及端到端测试来解决这个问题。

(就本例而言,更改是微不足道的,理论上可以通过将选择器放在单独的文件中来封装,但实际上,我说的是这些小部件的DOM结构中的较大更改,等等。)

我想在小部件之上构建一个测试库-类似于测试API。一个可以为我提供诸如header.getTitle()和header.getSubtitle()之类的封装层-我可以在单位/集成(Karma)以及端到端世界(量角器)中使用它。这样,如果发生如上所述的更改,我必须放在一个地方,修复“ header.getTitle”的实现,而所有测试都不在乎。

为此,我创建了类似的内容(使用TypeScript):

import $ from "jquery";

export class MyHeaderImpl implements MyHeadear {
    private selector;

    constructor(element) {
        this.selector = $(element);
    }

    getTitle(): string {
        return this.selector.find(".my-header-title-text").text().trim();
    }

    getSubtitle(): string {
        return this.selector.find(".my-header-subtitle-text").text().trim();
    }
}

对于我的单元/集成测试(Karma)来说效果很好:

element = angular.element("<header config=\"config\"></header>");
$compile(element)(myScope);
myScope.$digest();

const header = ComponentFactory.createHeader(element);
expect(header.getTitle()).toBe("This is a main title");

但是,它不适用于量角器:

describe('Some end to end spec', function () {
    it('should have the right title', function () {
        let element = element(by.css(".my-header .my-header-title-text"));
        const header = ComponentFactory.createHeader(element);
        expect(title.getText()).toMatch("This is a main title");
    });
});

它引发以下异常

Failed: jquery_1.default is not a function

我正在测试库以及Protractor测试中使用TypeScript。

我可以在测试库中用Protractor的元素替换jQuery $,但随后我将强制单元/集成测试针对浏览器运行,这将使它们失去快速的目的。

有人知道如何创建这样的测试API库,以供Karma测试以及量角器测试使用吗?

我能找到here on Stack Overflow的最好的描述之一,但不能回答我的问题。

2 个答案:

答案 0 :(得分:0)

您是否尝试过将库注入业力并直接使用而不导入。有很多因果适配器,所以我认为对于jquery。在量角器中,您可以在量角器配置中执行相同的操作。您描述的测试API称为页面对象模式BTW,您不确定将两种类型的测试混合在一个规范中是否是个好主意。

答案 1 :(得分:0)

@factor5,这是我对您的建议的回答,因为评论部分不允许这样做。

首先,让我总结一下我的问题:

有没有一种方法可以编写(TypeScript)接受两种方法的方法:

  1. 角度元素(https://docs.angularjs.org/api/ng/function/angular.element
  2. 量角器元素(https://www.protractortest.org/#/api?view=ElementFinder

,然后在给定的元素内查找,找到一个div,然后返回其文本? 如果我将此元素参数定义为Angular,则无法在量角器端到端项目中重用它。 如果我将此元素参数定义为“从量角器导入{element}”,它将强制我的单元/集成测试通过WebDriver进行端到端测试。

第二,关于页面对象模式:我比页面对象模式低一级。让我们进入评论文本区域,我现在在此处输入答案。

<div class="js-comment-text-input-container">
    <textarea></textarea>
</div>

我可能有一个名为QuestionPage的Page对象,其类型为typeComment(),或者甚至有一个名为CommentSection的单独组件(PageObject),在其中放置了诸如typeComment(),sendComment(),editComment()等方法。

但是可能会在其他许多地方使用,即用户可以在其中 可以添加简短的简介,等等。将有一个名为UserProfile的Page对象,其中具有typeBio(),该对象还可以处理

在这一点上,如果结构发生变化,那么您已经有两个地方需要 去改变。

因此,我需要一个单独的库来隔离与此类元素的交互。