【问题标题】:Continuous third party APIs monitoring & testing on Rails在 Rails 上持续的第三方 API 监控和测试
【发布时间】:2012-12-26 21:08:06
【问题描述】:

我们希望设置自动化作业(通过Jenkins),以便在第三方 API 已关闭或他们部署了不兼容的 API 时发出警报。

我说的是针对真实的 HTTP APIs 进行测试,而不是模拟,但由于我们已经使用 rspec 编写了模拟,我不确定我们是否应该通过编写两个独立的测试来重复这项工作。

以前有人有过这种经验吗? (如果其他工具可以提供帮助,我不限于Ruby/Rspec

【问题讨论】:

    标签: ruby-on-rails ruby rspec tdd bdd


    【解决方案1】:

    Mocks 用于测试您自己的代码,无需接触真实的 API。并且您想测试真正的 API。

    所以我认为您必须在 RSpec 中编写一组测试,例如用于 3rd 方 API 的 unobtrusive 测试。
    我所说的“不引人注目”是指跟踪您不会发出意外的“DELETE”API 请求,或者通过单个测试套件运行使用所有每日请求 API 限制。

    不知道有没有指定的API测试工具。
    至于我,我使用 RSpec 成功地测试了我自己的远程 API/服务器。

    【讨论】:

      【解决方案2】:

      你看过VCR吗?使用它,您可以“记录测试套件的 HTTP 交互并在未来的测试运行期间重放它们,以实现快速、确定、准确的测试”。在测试来自外部 API 的预期响应时,我已经将它与 RSpec 一起使用,并且认为它很棒。如果您认为这对您有用,我建议您查看带有 标记的 StackOverflow 问题。

      不确定它的 Jenkins 集成,但是当我使用 VCR 时,我自动化了一些常规任务,我需要使用 Whenever(“Ruby 中的 Cron 作业”)来访问 API。不是真正连续的,但有点自动化。

      【讨论】:

      • 我同意,VCR 非常适合这个。本质上是记录某种“合同”。然后您可以重新录制并检查差异。
      【解决方案3】:

      几个月前我遇到这种情况时,我做了以下事情:

      1. 模拟 API 并针对模拟数据编写测试(您已经拥有)
      2. 再编写一个测试,从真实 API 获取数据并断言它(仍然)采用相同的形式并包含我们期望的相同类型的数据

      我这样做是因为我无法猜测/知道实时 API 将提供哪些内容。

      【讨论】:

      • 这就是我们过去所做的。您可以安排 Jenkins 作业,检查您是否仍然可以每晚或每周与第 3 方 API 交互,它会通知您相关 API 的更改。
      • 还有一件事...作为其他人所依赖的服务,我们甚至鼓励这样做,并设置了一个电子邮件帐户,当客户的构建由于我们的API 更改,他们可以通过他们的自动化测试通知我们。这样我们就可以知道我们何时对客户产生了负面影响。
      • 我最近发现了 Weary gem github.com/mwunsch/weary,这似乎是“包装”您对任何 API 的访问并编写相当简单的测试的好方法(参见 Gilt github.com/mwunsch/gilt
      • @bcarlso 关于来自客户测试的电子邮件的好消息。
      【解决方案4】:

      我会对现有的测试套件做两件事,以便它可以实时使用,第一件事是使用 describeit 块获取元数据 (There's a good blog post on it here) 的功能。第二个使用shared_contexts的能力来阻止。

      首先,使用元数据标记您希望针对真实 API 运行的规范。例如,您想知道这些可以真实运行,例如

      describe "Hitting the API with a call", :can_be_real do
        # …
      end
      

      然后可以从命令行using the tag option 运行这些规范。

      第二件事,是用真实的东西代替模拟物。这取决于您如何定义模拟,是使用before 还是let,以及您模拟了多少。作为一个愚蠢的例子,见下文:

      require 'rspec'
      
      RSpec.configure do |c|
        c.treat_symbols_as_metadata_keys_with_true_values = true
      end
      
      shared_context "all my mocks and stubs" do
        let(:this) { false }
      end
      
      describe "a", :real do
        include_context "all my mocks and stubs" do
          let(:this) { true } if ENV["REAL_API_CALL"] == 'true'
          before do
            stub_const( "URI", Class.new ) unless ENV["REAL_API_CALL"] == 'true'
          end
        end
        it "should be real when it's real" do
          this.should == true
        end
        it "should escape things when it's real" do
          URI.should respond_to :escape
        end
      end
      

      当文件通过bin/rspec example.rb 运行时,输出为:

      a
        should be real when it's real (FAILED - 1)
        should escape things when it's real (FAILED - 2)
      
      Failures:
      
        1) a should be real when it's real
           Failure/Error: this.should == true
             expected: true
                  got: false (using ==)
           # ./example.rb:19:in `block (2 levels) in <top (required)>'
      
        2) a should escape things when it's real
           Failure/Error: URI.should respond_to :escape
             expected URI to respond to :escape
           # ./example.rb:22:in `block (2 levels) in <top (required)>'
      
      Finished in 0.00349 seconds
      2 examples, 2 failures
      

      当通过env REAL_API_CALL=true bin/rspec example.rb运行时:

      a
        should be real when it's real
        should escape things when it's real
      
      Finished in 0.00301 seconds
      2 examples, 0 failures
      

      因此,您可以通过多种方式更改规范的上下文,从而允许您从命令行(以及因此,Jenkins)获得所需的控制级别。您可能希望使用其他元数据来标记规范,例如真实运行是否安全、是否可能需要很长时间等。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多