Protractor E2E - 您如何管理数据库?

Posted

技术标签:

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

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

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

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

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

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

【问题讨论】:

【参考方案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,尤其是当您的站点是状态和数据驱动的时候。所以我们需要确保“可重复性”,这意味着我必须考虑数据库,因此我的问题就在这里。

以上是关于Protractor E2E - 您如何管理数据库?的主要内容,如果未能解决你的问题,请参考以下文章

Angularjs E2E test Report/CoverageReport - 使用Gulp

angular 调试 js (分 karms protractor / test e2e unit )

未为自定义protractor.conf文件创建Webdriver实例

Protractor 和 Karma 可以一起使用吗?

使用带有 Angular2 和 Socket.io 的量角器运行 e2e 测试

使用Microsoft Edge设置Protractor