量角器E2E - 您如何管理数据库?

时间:2014-08-12 23:38:31

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

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

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

搜索谷歌会提供大量各种自定义方法。我经常读到“你应该设置你的数据'或者只是创建一个模拟'没有详细介绍一个常见的过程。其他人从头开始创建一个全新的模拟模块需要花费太多的开销。

我只想知道人们目前是如何做到的,并且有一个标准吗?或者人们往往只是嘲笑后端?由于你在浏览器范围内,嘲笑后端似乎并不像Karma那样简单。

我正如预期的那样使用MongoDB,所以很高兴在这个场景中对其他事情做一些指导。特别是通过量角器自动加载灯具和数据库清理工作会很好。

5 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

您可以通过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方法插入数据。

您可以在Queriesdescribe的{​​{1}}中使用beforeAll。 例如,在afterAll上创建一些用户,在beforeAll上删除它们。

答案 2 :(得分:0)

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

每次执行完文本后,您都需要使用数据库重置脚本让数据库休息

答案 3 :(得分:0)

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

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

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

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

希望这会有所帮助。

答案 4 :(得分:-1)

我们使用 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);
          }
        });
    }
  }