在量角器中管理不同配置的最佳方法是什么?

时间:2019-01-30 15:00:22

标签: angular protractor

我们有一个E2E项目,它是用Angular CLI 6和Protractor编写的。 目前,我们在angular.json中管理配置:

 "configurations": {
            "local_chrome": {
              "protractorConfig": "./protractor.local.conf.js"
            },
            "remote_dev_chrome": {
              "protractorConfig": "./protractor.remote.dev.chrome.conf.js"
            },
            "remote_qsa_chrome": {
              "protractorConfig": "./protractor.remote.qsa.chrome.conf.js"
            },

在package.json中,我们定义了脚本:

"e2e:local": "ng e2e --configuration=local_chrome --webdriver-update=false",
"e2e:dev:chrome": "ng e2e --configuration=remote_dev_chrome --webdriver-update=false",
"e2e:qsa:chrome": "ng e2e --configuration=remote_qsa_chrome --webdriver-update=false",

然后从命令行开始测试:

npm run e2e:qsa:chrome -- --base-url=https://aut.com --suite=szenarioTests

我们想在4种浏览器和5种环境下进行测试。这意味着我们需要5 * 4 = 20个配置文件。这些文件是90%相同的。这有点可怕,而且无法维护。

有人知道如何最大程度地减少配置文件和重复项的数量吗?在Angular CLI中是否有最佳的端到端配置最佳实践?也许带有Angular CLI的量角器不适合大型项目?

3 个答案:

答案 0 :(得分:1)

我不确定最小化文件总数的方法。但是,您可以拥有所有其他conf扩展的1个conf_shared文件,这将使更改时更易于维护。

示例 conf.js

import {ConfigShared} from "./conf_shared";
let specs = ["YourSpecsHere"];
let capabilities = {browserName:'chrome',...};

class ConfigLocal extends ConfigShared{
  specs = specs;
  capabilities = capabilities;
}
export const config = new ConfigLocal().exampleFunction(); //can call functions in conf_shared

示例 conf_shared

import {Config} from 'protractor';

export class ConfigShared implements Config{
  specs: ['']; //will get overriden by conf.js
  framework: 'jasmine2';
  //rest of shared config goes here

  //you can also make function that you will call from conf.js
  exampleFunction(){
    //do stuff here
  }
}

您在conf文件之间共享的所有内容都可以放入conf_shared文件中,这将有助于维护。如果仅在某些测试之间共享,则可以将其放入函数中(具有更改conf的函数),然后从conf.js中调用这些函数。

答案 1 :(得分:0)

除了做扩展而不是使用Object.assign()来创建配置外,我已经完成了与Ben的示例类似的操作。

创建一个默认配置,其中包含将在配置之间共享的所有内容。然后,在其他每个配置中,仅包含在配置之间会有所不同的内容。任何重复的字段都会被Object.assign()

中的第二个参数覆盖

例如,当我在本地开发环境上运行测试时,这就是我的本地配置:

// local.conf.js
module.exports = {
  baseUrl: 'http://localhost:8082',
  directConnect: true
}

我们的环境都是容器化的,因此当我要在构建中运行冒烟测试时,配置如下所示:

// build.conf.js
module.exports = {
  baseUrl: 'https://app:7443',
  seleniumAddress: 'http://hub:4444/wd/hub',
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000,
    print: function() {}
  }
}

我的默认(共享)配置不包含directConnectseleniumAddress,因为它们不能在同一配置中在一起。这些值来自其他配置文件。使用以上示例作为参考,您的基本配置将如下所示:

const defaultConf = require('/path/to/dafault.conf');
const localConf = require('/path/to/local.conf');
const remoteDevChrome = require('/path/to/remote_dev_chrome.conf');
const remoteQsaChrome = require('/path/to/remote_qsa_chrome.conf');

const configuration = process.argv.filter(arg => {
  return arg.includes('--configuration');
})[0];

let protractorConf = {};

switch (configuration.split('=')[1]) {
    case 'local_chrome':
        protractorConf = Object.assign(defaultConf, localConf);
    case 'remote_dev_chrome':
        protractorConf = Object.assign(defaultConf, remoteDevChrome);
    case 'remote_gsa_chrome':
        // ... and so on ...
    default:
       // whatever default config you use
}

exports.config = protractorConf;

通过这种方式,您不再需要在package.json中包含多个脚本。您只可以使用一个脚本,配置将基于您为--configuration传递的内容进行构建

答案 2 :(得分:0)

我们决定不在E2E测试中使用角度cli。结果,我们可以从命令行配置测试,并且配置文件中没有任何复制项(易于维护)。 在我们的解决方案中,我们为每个命令行设置了许多参数(浏览器,环境,日志记录级别,远程或本地)。我们的实现类似于tehbeardedone解决方案。我们有一个基本的配置文件和一个读取命令行参数并设置相应配置的脚本。
为此,我们使用

request_media_types = @order.media_order_requests.map { |r| r.media_type_id }  #hopefully this is a list of media_type_id's 
@media_types = MediaType.select { |mt| !request_media_types.include? mt.id } #select thos MediaType object whose id is not in the request_media_types list

,然后使用简单的if设置配置。对于每个参数,我们都有默认值。