【问题标题】:Integration Tests for WebAPI and transactionsWebAPI 和事务的集成测试
【发布时间】:2017-02-14 20:58:29
【问题描述】:

我有一个面向客户端的 ASP.NET Web API,它既可以直接调用 SQL 服务器,也可以调用 其他 ASP.NET Web API 来执行数据操作。我想做一个客户端REST API的端到端集成测试,测试其他调用的REST API的路由以及各种数据操作是否成功。

我要做的测试是 (1) 不同 REST API 的路由是否正确,以及 (2) 通过 REST API 添加和更新客户是否成功。只需添加一个客户进行测试,就可以确保路由正确,数据操作成功。

我想在完成测试后回滚事务。例如,在测试期间,通过http://localhost/Customer/POST 之类的 REST API 创建了一个新客户,并在测试结束时删除了该用户。

REST API 是否可以进行事务操作,欢迎对集成测试提出任何建议。我在 Visual Studio 2013 环境中使用 NUNIT。

【问题讨论】:

    标签: rest asp.net-web-api transactions


    【解决方案1】:

    不幸的是,目前的选项并不理想,这是我在一个相对较大的项目上设置的——与here 上的官方测试指南相距不远。这一切都依赖于您的构建/测试/部署过程的自动化(即 ALM-应用程序生命周期管理,我们使用 Visual Studio Release Manager 2013)

    1)。在 CI 服务器上,我们在每个 checkin 上运行一系列单元测试,通过直接实例化控制器类并调用 get/put/post/delete 方法来执行一些基本测试,就像我们在任何其他单元测试中所做的那样。这些使用模拟后端(无数据库连接)层,因此我可以独立测试 API、数据、业务层。

    2)。在夜间自动部署到“集成”环境中,我们在项目的每一层单独运行上述检查,然后将所有资产部署到集成服务器。部署后,我们会运行一些构建一致性检查,使用“ASP.net Web API 客户端库”(在 nuget 和 asp.net 网站上查找它们)从“客户端”一路执行真正的端到端测试通过每一层到数据库,在单元测试结束时,在一些断言之后,我们运行一个简单的删除查询来回滚数据。不幸的是,目前 webapi 中没有“事务”的概念,您必须创建自己的。为了将单元测试与构建一致性/验收测试分开,我们对单元测试有一个自定义操作过滤器,允许我们排除给定的测试。所以我们的构象测试看起来像这样:

    [Test, ConformationTest]
    Public void TestGetCustomer(){
       //build get request here
    }
    

    3)。然后构建在部署到 LIVE 之前通过正式测试阶段(跨分支手动合并),因为我们使用发布管道(“Visual Studio Release manager 2013”​​),我们知道环境之间的构建是相同的,因此我们只做一个实时部署中的少量 GET 请求,以确保 API 在重新启用负载均衡器上的服务器之前正在运行。

    我们这样做的原因是 Web API 需要托管在某个地方以进行端到端测试,单元测试会在签入时立即捕获大多数错误 - 以及每晚与在每次签入时启动 VM 相关的任何路由如果您有多个开发人员全天定期检查,则成本很高。这确实涵盖了大多数方面,但正如我所说,不是 100% 理想的。

    【讨论】:

      【解决方案2】:

      这是您可以做到的一种方式。

      通过将当前事务添加到 TestServer。当一个请求被发送到 TestServer 时。您可以将事务设置为当前事务以启用 UnitTest 和 TestServer 之间的事务流。

      using (var server = TestServer.Create(app =>
              {
      
                  app.Properties.Add(new KeyValuePair<string, object>("Transaction", Transaction.Current));
      
                  app.Use((context, next) =>
                  {
                    if (app.Properties.ContainsKey("Transaction"))
                      {
                          Transaction.Current = (Transaction)app.Properties["Transaction"];
                      }
      
                      var invoke = next.Invoke();
      
                      if (app.Properties.ContainsKey("Transaction"))
                      {
                          Transaction.Current = null;
                      }
      
                      return invoke;
                  });
      
              }))
              {
                //Your test code
              });
      

      【讨论】:

      • 以上更新。您需要清理 Transaction.Current。否则线程会变脏。
      猜你喜欢
      • 2021-12-08
      • 2011-05-07
      • 2014-09-27
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 2013-09-26
      • 2023-03-06
      • 2022-01-24
      相关资源
      最近更新 更多