我该如何在我的Jasmine/Protractor测试中执行TypeScript样式继承?

4
在我的项目中,我正在使用protractor+jasmine+TypeScript进行端到端测试。我已经从TypeScript的继承荣耀中受益,将其应用于页面对象文件中(例如,我有一些BasePageObject类,其中包含通用方法/对象,用于派生其余的PageObjects)。我想在我的测试中引入相同的方法。以下是我现在拥有的示例代码:
测试套件A [ATest.ts]:
import {
     SomePage,
     LoginPage
} from '../pages';


describe('test suite A', () => {
    let loginPage: LoginPage = new LoginPage();
    let somePage: SomePage = new SomePage();

    beforeAll(() => {
        loginPage.login();
        somePage.navigateTo();
    });

    it('my test 1', () => {
        //test body, assertions etc.
    });

    it('my test 2', () => {
        //test body, assertions etc.
    });
});

测试套件B [BTest.ts]:

import {
     AnotherPage,
     LoginPage
} from '../pages';


describe('test suite B', () => {
    let loginPage: LoginPage = new LoginPage();
    let anotherPage: AnotherPage = new AnotherPage();

    beforeAll(() => {
        loginPage.login();
        anotherPage.navigateTo();
    });

    it('my test 1', () => {
        //test body, assertions etc.
    });

    it('my test 2', () => {
        //test body, assertions etc.
    });
});

正如您所看到的,某些代码对于两个套件都是通用的。我想要实现的是在我的测试用例中继承,以更符合Java风格并避免代码重复(例如):

class BaseTestCase {
    beforeAll() {
        loginAction();
    }
}

class TestA extends BaseTestCase {
     beforeAll() {
         specificStuff();
     }
}

class TestB extends BaseTestCase {
     beforeAll() {
         specificStuff();
     }
}

在Jasmine中是否有可能实现这个功能?

1
你可以创建一个服务来同时管理 beforeAll。 - Yoav Schniederman
问题缺少细节。loginPageanotherPage变量在其他地方使用吗?如果它们应该每个规范实例化一次,它们可以移动到一个模块并成为单例实例,不是吗? - Estus Flask
你解决了这个问题吗?我自己也遇到了同样的问题/情况。 - S.Huston
1
describe 是一个函数,不是一个类。因此它没有基于类的 extends。你可以使用原型继承,但我会创建自己的类,然后让这个类调用 describe 函数,就像这个答案所示。 - Liam
2个回答

2

你可以创建一个基类,然后很容易地扩展它,用函数替换回调函数。

export abstract class BaseTest {
  abstract loginAction(): void;
  abstract specificStuff(): void;
}

export class FooTest extends BaseTest {
  loginAction(): void {
    // does stuff to login
  }
  specificStuff(): void {
    // do tests and expectations
  }
}

在你的测试中:

// Do some importing for FooTest.

describe('test suite A', () => {
  let fooTest = new FooTest();

  beforeAll(fooTest.loginAction);

  it('should do some specific stuff', fooTest.specificStuff);
});

你应该这样做吗?

虽然可以这样做,但是这是否是你想要做的事情呢?我想你的FooTest类方法将对测试进行一些期望。这(在我看来)不是一个好的模式。你的it块应该包含你的期望,而不是取出它。


0
这个"Jasmine describe override"看起来很有前途,我会试一试: https://ajsblackbelt.wordpress.com/2016/05/06/jasmine-describe-override/ (这段代码还没有经过测试)
global.myDescribe = function (name, arg1, arg2, suite) {
  describe(name, function){
    _myDescribeLogic(name, arg1, arg2, suite);
  }
};

function _myDescribeLogic(name, arg1, arg2, suite) {
  beforeAll(function (done) {
    // code
  });
  beforeEach(function (done) {
    // code
  });

  afterAll(function (done) {
    // code
  });
  afterEach(function (done) {
    // code
  });
}

在你的 Protractor 配置文件中添加以下内容:

onPrepare: 'src/framework/myOnPreapre.js'

然后这个应该可以工作:

myDescribe('a suite', 'foo', 'bar', function(){
  it('should test a business function', function(){
    // code
  })
})

不要忘记扩展x-和fdescribe,就像文章所描述的那样。

为什么我想这样做呢? 因为有些东西对于每个测试来说总是一样的,比如登录(是的,除了登录测试,它们被排除在外)。而且我不想从一个文件复制&粘贴必要的before*()到另一个文件。

应该有一个地方可以定义这样的通用事物,并且我希望它可用性强,不会出现错误(比如忘记某些内容或者在复制&粘贴&修改时出现错误)。

对我来说,反复阅读相同的代码行只是噪音。这使得测试更难以阅读。 我只想阅读与测试相关的内容。其他所有内容都是上下文。如果测试是关于编写和保存文本的,我不关心登录。

出于不同的原因,我不喜欢jasmine/protractor测试基于独立文件。对我来说,一个文件中的测试只是子套件。'真正的'套件是我所有的测试文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接