我的 Rails 应用程序外部端点集成测试的良好实践?

发布于 2024-09-16 02:27:37 字数 369 浏览 7 评论 0原文

我会长话短说,我有一个 Rails 应用程序,它可以与其他应用程序通信,其中一些使用 SOAP(当然是非 Rails 应用程序......),而其他应用程序则使用 REST。我正在进行集成测试,以确保我的端点包装器类具有正确的映射和设置。然而,它们默认由 rake test 执行,这使得它缓慢且脆弱。我希望经常运行单元测试,并且仅“按需”运行集成测试。你怎么做到的?

您对此类集成测试有何偏好?

  • 您的单元测试和/或模拟有多深?
  • 您是否在存根中复制整个 SOAP 或 REST xml 响应?
  • 您是否创建了“外部端点”集成测试?

更新问题:如何在运行 rake test 时排除测试目录?

I'll keep it short, I've got a rails app which communicate with other apps, some using SOAP (non-rails apps of course...) and others with REST. I'm making integration tests to ensure that my endpoint wrapper classes have correct mappings and setup. However, they are executed by default by rake test which makes it slow and fragile. I wish to run unit tests frequently and integration tests "on-demand" only. How do you do that?

What're your preferences wrt such integration testing?

  • How deep do you unit test and/or mock?
  • Do you replicate whole SOAP or REST xml responses in stubs?
  • Do you create "external endpoint" integration tests at all?

Update Q: How to exclude a test-dir while running rake test ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

金橙橙 2024-09-23 02:27:37

如果您遵循 Rspec/Cucumber 人员的建议,那么集成测试级别不适合模拟您的数据,因为在某些方面,它违背了集成/验收测试的目的。但是,您必须模拟贝宝交易之类的东西,对吗?在我当前的项目中,我面临很多这样的问题,以下是我正在实施的一些解决方案:

  1. 标记在某些情况下不起作用的测试。在我的示例中,许多服务器位于防火墙后面,因此如果我在家并且不使用 VPN,我的测试就不会通过。因此,在 Cucumber 中,我可以将它们标记为 @firewall 并告诉它运行未标记为防火墙的测试。我很确定 Rspec 2.0 也支持此功能。
  2. 模拟服务请求。是的,这可能是一个坏主意,但我不知道如何以任何可预测的方式做到这一点。我有一个单独的测试套件来确认服务正在运行,并且从我的 Rails 应用程序中,我假设它们工作正常。 LDAP 就是一个例子。是的,在这种情况下,我倾向于使用真实的回应并做类似的事情。 response = double('response') ; response.expects(:data).and_returns('my xml here')

  3. 我确实认为无论系统的复杂性如何,端点测试都非常重要。我真的很喜欢 Cucumber,它为我提供了 95% 的功能测试所需的内容,因此我最终编写了更少的这些测试和更多的整个工作流程测试。

If you go by what the Rspec/Cucumber folks suggest, then the integration test level is an inappropriate place to mock your data, because in some respects, it defeats the purpose of the integration/acceptance test. However, you have to mock stuff like paypal transactions, right? In my current project, I am facing a lot of this, and here are some of the solutions I am implementing:

  1. Tagging tests that wont work in certain contexts. In my example, lots of servers live behind firewalls and so my tests dont pass if I am at home and not using vpn. So, in cucumber I can tag these as @firewall and tell it to run tests that are not tagged firewall. I'm pretty sure Rspec 2.0 supports this feature as well.
  2. Mocking service requests. Yah, its probably a bad idea, but I am at a loss on how to do it otherwise with any kind of predictability. I have a separate test suite to affirm that the services are running, and from my rails app, i am assuming they are working properly. An example of this would be LDAP. And yes, in these circumstances, I tend to use a real response and do something like. response = double('response') ; response.expects(:data).and_returns('my xml here')

  3. I do think regardless of the complexity of the system that end point tests are really important. I am really enjoying cucumber, it provides me 95% of what I need to do in functional tests, and so I end up writing fewer of these tests and more of the entire workflow tests.

眼角的笑意。 2024-09-23 02:27:37

解决方案是VCR

The solution is VCR.

携余温的黄昏 2024-09-23 02:27:37

只需几行代码即可解决从 rake test 中排除端点集成测试并使用 rake test:endpoints 隔离和运行它们的问题。但我不得不承认,我花了很多时间咒骂。 Railties 源中应该有更多文档和解释。在我看来,像这样的 Ruby 代码往往不是很容易解释。

好吧,事情是这样的:
创建您的任务:lib/tasks/slow_tests.rake

require 'rails/test_unit/railtie'
desc "Runs all endpoint integration tests."
namespace :test do

  #hooks on to the test task through the 'test:prepare'
  #For details, check the railties gem (v3.0+) lib/rails/test_unit/testing.rake,
  #look for "task :test" and "namespace :test"
  TestTaskWithoutDescription.new(:endpoints => 'test:prepare') do |t|
    t.libs << 'test'
    t.pattern = 'test/endpoints/**/*_test.rb'
  end
end

现在我可以将脆弱的端点集成测试放在 test/enpoints 目录中,随时运行它们(不经常)

注意:这假设是 test/unit 或应该。< /em>

Excluding endpoint integration tests from rake test and being able to isolate and run them with rake test:endpoints was solved with only a few lines of code. I have to admit though, I spent a whole lot of hours swearing and cursing. There should be more documentation and explanations in the railties source. Ruby code like that tend not to be very self-explanatory, IMO.

Well, here it goes:
create your task: lib/tasks/slow_tests.rake

require 'rails/test_unit/railtie'
desc "Runs all endpoint integration tests."
namespace :test do

  #hooks on to the test task through the 'test:prepare'
  #For details, check the railties gem (v3.0+) lib/rails/test_unit/testing.rake,
  #look for "task :test" and "namespace :test"
  TestTaskWithoutDescription.new(:endpoints => 'test:prepare') do |t|
    t.libs << 'test'
    t.pattern = 'test/endpoints/**/*_test.rb'
  end
end

Now I may put my fragile endpoint integration tests in the test/enpoints directory, running them whenever I want (not often)

Note: this supposes test/unit or shoulda.

请你别敷衍 2024-09-23 02:27:37

您应该在外部 API(Facade/Wrapper)周围编写一个薄层,并使用 vcr-gem 来“存根” ” 网络通话。
您可以从我关于 rails 测试架构

You should write a thin layer around external APIs (Facade/Wrapper) and use the vcr-gem to "stub" network calls.
You can get more information from my article on rails test architecture.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文