【问题标题】:Protractor E2E - How Do You Manage Database?Protractor E2E - 您如何管理数据库?
【发布时间】:2014-10-06 04:50:39
【问题描述】:

我目前依靠 Node + Angular 堆栈并利用 Karma 和 Protractor 进行测试。

我目前很难弄清楚如何处理创建和编辑数据的 E2E 测试,以及加载预期数据的需要。

搜索 google 会发现很多不同的自定义方法。我经常读到“你应该设置你的数据”或“只是创建一个模拟”,而没有深入了解常见过程的更多细节。其他人在从头开始创建一个全新的模拟模块时投入了太多开销。

我只是想知道人们目前是怎么做的,这有标准吗?还是人们倾向于只是嘲笑后端?模拟后端似乎并不像在 Karma 中那样简单,因为您在浏览器范围内。

正如预期的那样,我使用 MongoDB,因此很高兴了解在这种情况下其他操作的一些方向。特别是通过 Protractor 自动加载夹具和数据库清理会很好。

【问题讨论】:

    标签: node.js angularjs unit-testing protractor angularjs-e2e


    【解决方案1】:

    您通常会创建一个单独的环境来测试端到端测试。

    每次执行文本后,您需要使用数据库重置脚本重置数据库

    【讨论】:

      【解决方案2】:

      我们使用 oracledb npm 库来执行数据创建和测试数据设置。

      下面的代码用于做同样的事情

      import * as oracledb from 'oracledb';
      
      connectDb(username: string, password: string, SID: string, setting_name: string, value: string) {
          return browser.driver.sleep(1000).then(() => {
            oracledb.getConnection(
              {
                user: username,
                password: password,
                connectString: SID
              },
              function (err, connection) {
                if (err) {
                  console.error(err.message);
                  return;
                }
                connection.execute(
                  // The statement to execute
                  
                  //<Place the Query that needs to be executed>,
                 UPDATE <table name> SET VALUE=:value WHERE NAME=:setting_name
                  {
                  //The paramaters to be substituted in the query.
                    value: value,
                    setting_name: setting_name
                  },
                  { autoCommit: true },
      
                  // Optional execute options argument, such as the query result format
                  // or whether to get extra metadata
                  // { outFormat: oracledb.OBJECT, extendedMetaData: true },
      
                  // The callback function handles the SQL execution results
                  function (error, result) {
                    if (error) {
                      console.error(error.message);
                      doRelease(connection);
                      return;
                    }
                    doRelease(connection);
                  });
      
              });
          });
          function doRelease(connection) {
            connection.close(
              function (err) {
                if (err) {
                  console.error(err.message);
                }
              });
          }
        }
      

      【讨论】:

        【解决方案3】:

        您可以通过三种方式实现这一目标:

        1) 第一种方法是编写简单的自定义 API 用于测试,您可以在量角器测试开始之前使用它们(量角器配置文件 onPrepare)。在 onPrepare 上,您可以运行一个脚本,该脚本在您的数据库中创建数据,您稍后将使用这些数据进行测试。该脚本应该包含将您需要的数据库条目推送到数据库的逻辑。 您还可以在量角器测试 CI 阶段开始之前使此脚本在 CI 上运行。这样,您将在测试开始之前将所需的所有数据库条目加载到数据库中。这样做的缺点是您的测试将需要更长的时间才能开始。另一个缺点是,如果在测试之间进行了设置,则必须在测试之间运行设置。

        2) 第二种方法是使用 npm 包 ng-apimock。我建议不要使用它,因为模拟对于 e2e 测试来说不是一个好主意。即便如此,使用 ng-apimock 将允许您定义要模拟的 API 值并将它们推送到模拟服务器。然后,您可以稍后在使用 selectScenario 的测试中使用该值。有一个量角器 ngapimock 插件可用于实现此目的。此外,称为传递的功能将允许您的 API 响应不使用模拟,而是使用实际的 API 后端。如果后端尚未准备好,此工具用于更快的前端开发。如果您使用的是 ngapimock,请确保定期维护您的模拟,否则测试将失败。

        3) 第三种方法是初始化一个仅用于测试的数据库。这意味着当您初始化数据库时,只需确保只存在您测试所需的数据。运行测试,然后销毁数据库。这样,您将需要维护数据库启动脚本以将不同的值添加到不同的表中。

        希望这会有所帮助。

        【讨论】:

          【解决方案4】:

          您可以通过 REST API(网络服务)管理您的数据库。

          我想展示一个示例,如何使用带有量角器的 Web 服务从数据库中删除用户。 在我的示例中,我使用 Oracle 作为数据库。

          class OracleDatabaseAccess {
              private readonly BASE_API_URL: string = browser.params.someUrlToYourRest;
          
              public request<T>(query: string): promise.Promise<T[]> {
                  return this.get<T[]>(this.BASE_API_URL, 'sql?query=' + this.fixQuery(query));
              }
              public update<T>(query: string): promise.Promise<T[]> {
                  return this.get<T[]>(this.BASE_API_URL, 'update?query=' + this.fixQuery(query));
              }
              public get<T>(url: string, path: string): promise.Promise<T>  {
                  const http = new HttpClient(url);
                  http.failOnHttpError = true;
                  const responsePromise: ResponsePromise = http.get(path);
                  return responsePromise.body.then(body => {
                      return JSON.parse(body.toString());
                  })  as promise.Promise<T>;
              }
              private fixQuery(query: string): string {
                  if (query.includes('%')) {
                      query = query.split('%').join('%25');
                  }
                  if (query.includes(';')) {
                      query = query.replace(';', '');
                  }
                  return query;
              }
          }
          
          class Queries {
              private oracleDataBaseAccess: OracleDatabaseAccess = new OracleDatabaseAccess();
          
              deleteUser(userId: string): promise.Promise<{}> {
                  return this.oracleDataBaseAccess.update(`delete from users where userId='${userId}'`);
              }
          }
          

          通过使用request 方法,您可以从数据库中选择记录。另外,使用update 方法可以插入数据。

          您可以在 describe 中的 beforeAllafterAll 中使用 Queries。 例如,在beforeAll 上创建一些用户,在afterAll 上删除它们。

          【讨论】:

            【解决方案5】:

            Protractor 仅用于 e2e 测试。这意味着,它与您的数据库无关。您可以使用任务运行程序(如 grunt 或 gulp)来清理和填充您的数据库,然后让任务运行程序开始您的量角器测试(我从未做过最后一个,但我认为这是可能的)。好吧,我知道这不是您想要的答案,但也许我可以为您指出正确的方向。

            【讨论】:

            • 我想使用 Grunt 可能是一种选择,即使它在 Protractor 的外部。我理解您的意思,它与 DB 无关,但是由于您 E2E 通常测试“整个”堆栈,这自然包括 DB,尤其是当您的站点是状态和数据驱动的时候。所以我们需要确保“可重复性”,这意味着我必须考虑数据库,因此我的问题就在这里。
            猜你喜欢
            • 2015-04-11
            • 2010-09-11
            • 1970-01-01
            • 2010-09-10
            • 2013-08-01
            • 2017-09-09
            • 2018-01-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多