将多个布尔检查简化为一个检查

Simplifying multiple boolean checks into a single one

在我们的一项测试中,我们有以下一组期望:

expect(headerPage.dashboard.isDisplayed()).toBe(true);
expect(headerPage.queue.isDisplayed()).toBe(true);
expect(headerPage.claimSearch.isDisplayed()).toBe(true);
expect(headerPage.claim.isDisplayed()).toBe(true);
expect(headerPage.case.isDisplayed()).toBe(true);
expect(headerPage.calendar.isDisplayed()).toBe(true);

一方面,多个简单的期望提供了更精确和易于理解的反馈,但另一方面,这看起来违反了 DRY 原则"one expectation per test" 普遍接受的准则。

有没有办法convert/simplify它到一个期望值?


headerPage是一个页面对象,dashboard等页面对象字段是导航链接。

如何使用辅助函数 returns 所有测试的结果,比如

expect(headerDisplayTests()).toBe(true);

function headerDisplayTests() {
    return headerPage.dashboard.isDisplayed() && 
            headerPage.queue.isDisplayed() &&
            headerPage.claimSearch.isDisplayed() && 
            headerPage.claim.isDisplayed() &&
            headerPage.case.isDisplayed() && 
            headerPage.calendar.isDisplayed();
}

我认为您误解了 "one expectation per test" 指南的目的。重点不是将一堆期望组合成一个单一的期望,而是将您的期望拆分成单独的测试。

要遵循该准则的精神,您可以像这样编写测试:

describe("The header page", function () {
    var headerPage;
    beforeEach(function () {
        //Common logic here
    });

    it("displays the dashboard", function () {
        expect(headerPage.dashboard.isDisplayed()).toBe(true);
    });

    it("displays the queue", function () {
        expect(headerPage.queue.isDisplayed()).toBe(true);
    });

    it("displays the claimSearch", function () {
        expect(headerPage.claimSearch.isDisplayed()).toBe(true);
    });

    //etc.
});

这比你所拥有的要冗长一点;但这就是为什么这些是指南而不是规则。这是您进行测试的冗长程度与以后调试它们的容易程度之间的权衡。 ("The header page displays the dashboard: FAILED") 是一个非常明确和具体的测试失败消息,相比之下无论哪个期望实际失败都得到相同的失败消息。

我绝对不会尝试将所有这些行组合成一行。如果你不想把它分成一堆不同的测试用例,我会保持原样。

替代方法。我最终得到的是添加一个页面对象方法,该方法 returns 当前可见导航链接的 标签 :

this.getVisibleLinks = function () {
    return $$(".ap-header-nav-tabs li a").filter(function (link) {
        return link.isDisplayed();
    }).getText();
};

然后,上面的测试将转换为简洁易读的:

expect(headerPage.getVisibleLinks()).toEqual(["Dashboard", "Queue", "Claim Search", ...]);

如果这是您在多个规范中使用的逻辑,您可以查看 jasmine custom matchers 来封装逻辑。

大概会这样写:

var customMatchers = {
    toDisplayWidgets: function(util, customEqualityTests) {
        return {
            compare: function(actual, expected) {
                  function isDisplayingWidgets(page) {
                      return page.dashboard.isDisplayed() && 
                             page.queue.isDisplayed() &&
                             page.claimSearch.isDisplayed() && 
                             page.claim.isDisplayed() &&
                             page.case.isDisplayed() && 
                             page.calendar.isDisplayed();
                  }

                  var result = {};
                  result.pass = isDisplayingWidgets(actual);

                  if (!result.pass) {
                      result.message = 'dashboard is not displayed';
                  }

                  return result;
          }
    }
}

将匹配器添加到您当前的测试中

jasmine.addMatchers(customMatchers);

然后在你的测试中你可以用

断言
expect(headerPage).toDisplayWidgets();