当前位置: 首页 > 知识库问答 >
问题:

不可靠/片状水豚/AngularJS集成测试与时间问题

吴宝
2023-03-14


有时它们会通过。
下面是演示这个问题的设置、代码和输出。
克服这个问题的建议将非常感谢,我相信这将帮助许多其他人,所以请评论!

  1. Rails 3.2
  2. RSpec 2。x
  3. 水豚
  4. 恶鬼
  5. 幻影
  6. AngularJS
  7. 谷歌浏览器47.0.2526.106版(64位)
capybara (2.1.0)
database_cleaner (0.7.1)
debug_inspector (0.0.2)
guard-bundler (0.1.3)
guard-livereload (1.2.0)
guard-rspec (2.1.2)
jasminerice (0.0.10)
pg (0.17.1)
phantomjs (2.1.1.0)
poltergeist (1.4.1)
protractor-rails (0.0.17)
pry (0.9.12)
rack (1.4.7)
rack-test (0.6.3)
rails (3.2.21)
rails-assets-angular (1.3.20)
rspec-rails (2.11.4)
simplecov (0.8.2)
sprockets (2.2.3)
zeus (0.13.3)
zeus-parallel_tests (0.2.1)

>

  • 确保我使用水豚的等待DSL匹配器
  • 确保正确设置了“我的数据库清理器”
  • 测试每个页面项目,假设它可能不在页面上并且仍在加载
  • 缩小不一致测试的范围
  • 单独运行不一致的测试
  • 识别触发不一致测试结果的代码Capybara DSL。

    • 即创建一个新记录,并假设页面已经重定向,并且记录在页面上click_on

    • 。单击不一致的“工作”

    [1] 水豚:DSL
    [2]水豚、幻影、恶灵和Rspec提示
    以及更多。。。

    show_costing_spec.rb格式留档

    require "spec_helper"
    
    RSpec.describe "Show a new costing in the listing," do
    
      before :each do
        admin_sign_in
        create_costing("test1")
      end
    
      it "shows the costing after creation" do
        within "#costings_table" do
          expect(page).to have_css("#name", text: "test1")
        end
      end
    
      it "shows the details of the new costing after creation" do
        expect(page).to have_content("Costings")
        within "#costings_table" do
          expect(page).to have_content("test1")
          all("#show").last.click
        end
    
        expect(page).to have_content("Costing Details")
        expect(page).to have_css("#name", text: "test1")
      end
    end  
    
    # This file is copied to spec/ when you run 'rails generate r spec:install'  
    ENV["RAILS_ENV"] ||= 'test'
    require File.expand_path("../../config/environment", __FILE__)
    # Add library functions here so we can test them.
    require File.expand_path(File.dirname(__FILE__) + "/../lib/general")
    require 'rspec/rails'
    require 'rspec/autorun'
    
    # Integration Testing
    require 'capybara/poltergeist'
    Capybara.register_driver :poltergeist_debug do |app|
     Capybara::Poltergeist::Driver.new(app, :inspector => true)  
    end
    Capybara.javascript_driver = :poltergeist_debug
    Capybara.default_driver = :poltergeist_debug
    
    # Capybara Integration Test Helpers
    def admin_sign_in
      visit "/login"
      #Create staff member in database
      Staff.make!(:admin)
      #Log In
      fill_in "staff_username", with: "adminstaff"
      fill_in "staff_password", with: "password"
      click_button "login"
    end
    
    def create_costing(item)
      visit "/api#/costings"
      click_on "new_btn"
      within "#form_costing" do
        find("#name", match: :first).set("#{item}")
        find("#description", match: :first).set("test description")    
        find("#from_date", match: :first).set("15/02/2016")
        find("#cost_hourly_cents", match: :first).set("1.00")
        click_on "create_btn"
      end
    end
    
    RSpec.configure do |config|
      config.before(:suite) do
        # Requires supporting ruby files with custom matchers and macros, etc,
        # in spec/support/ and its subdirectories.
        require File.expand_path(File.dirname(__FILE__) + "/support/blueprints")
        Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
      end
    
      # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
      config.fixture_path = "#{::Rails.root}/spec/fixtures"
    
      # Allow a 'focus' tag so that we can run just a few tests which we are currently working on
      config.treat_symbols_as_metadata_keys_with_true_values = true
      config.filter_run focus: true
      config.run_all_when_everything_filtered = true
      config.filter_run_excluding :slow unless ENV["SLOW_SPECS"]
    
      # Defer Garbage Collection
      config.before(:all) { DeferredGarbageCollection.start }
      config.after(:all)  { DeferredGarbageCollection.reconsider }
    
      # If you're not using ActiveRecord, or you'd prefer not to run each of your
      # examples within a transaction, remove the following line or assign false
      # instead of true.
      config.use_transactional_fixtures = false
      # config.infer_spec_type_from_file_location!
    
      # Configure Database Cleaner
      config.include Capybara::DSL
      config.before(:suite) do
        DatabaseCleaner.clean_with(:truncation)
      end
    
      config.before(:each) do
        DatabaseCleaner.strategy = :transaction
      end
    
      config.before(:each, :js => true) do
        DatabaseCleaner.strategy = :truncation
      end
    
      config.before(:each) do
        DatabaseCleaner.start
      end
    
      config.after(:each) do
        DatabaseCleaner.clean
      end
    end
    

    测试运行1:失败

    运行选项:包括{:焦点=

    所有的例子都被过滤掉了;忽略{:焦点=

    在列表中显示新成本计算,显示创建后的成本计算显示创建后新成本计算的详细信息(失败-1)

    失败:

    1)在列表中显示新成本,
    显示创建后新成本的详细信息
    失败/错误:期望(页面)。have_content(测试1)
    预期#has_content?(test1")返回true,得到false
    #。/spec/集成/成本/show_costing_spec.rb:20:在块(3个级别)中
    #。/spec/集成/成本/show_costing_spec.rb:19:在块(2个级别)中

    在5.46秒内完成2个示例,1个失败

    测试运行2:通过

    运行选项:包括{:焦点=

    所有的例子都被过滤掉了;忽略{:焦点=

    在列表中显示新成本,
    显示创建后的成本
    显示创建后新成本的详细信息

    以3.57秒完成2个示例,0次失败

    将测试宝石升级到以下版本:
    水豚(2.6.2)从(2.1.0)
    database_cleaner(1.5.1)从(0.7.1)
    debug_inspector(0.0.2)
    后卫-活体负载(1.2.0)
    后卫-规格(2.1.2)
    茉莉花(0.0.10)
    pg(0.17.1)
    phantomjs(2.1.1.0)
    poltergeist(1.9.0)from(1.4.1)
    量角器-轨道(0.0.17)
    pry(0.10.3)from(0.9.12)
    机架(1.4.7)
    机架-测试(0.6.3)
    轨道(3.2.21)
    轨道-资产-角(1.4.9)从(1.3.20)
    rspec-rails(3.4.2)从(2.11.4)
    simecov(0.8.2)
    链轮(2.2.3)
    zeus-parallel_tests(0.2.1)

    结果1

    不幸的是,升级这些宝石似乎并没有带来什么不同,我的测试仍然很糟糕。

    我执行了汤姆·沃尔波尔的建议。确保我的管理员登录等待登录完成。

    还按照Tom的建议更新了我的数据库设置。

    结果2

    对我的堆栈来说,这些更改似乎没有效果。

    注意:如果一个人不使用AngularJS,我觉得这些变化会有所不同。所以谢谢汤姆你的建议。

    我需要获得更多关于测试运行期间发生的事情的信息。有人建议在网上登录,使用屏幕截图保存宝石等,但我不觉得这些将是最有效的时间。我想指定测试暂停的位置,并查看变量和表单字段的内容。在浏览器中是理想的。

    我使用的是“保存和打开页面”和“print page.html”进行调试。

    当我运行RSpec 3.4.2时,我添加了一个调试助手方法:

    rails_helper.rb

    def debugit
      puts current_url
      require 'pry'
      binding.pry
    end
    

    结果3

    控制台中将打印一个URL,测试将暂停。在这个阶段,我将能够导航到URL、登录、导航到测试页面并查看Capybara测试所做的工作。

    这使我能够识别出问题的根源是当测试使用水豚的fill_inDSL时出现的。在一些测试运行中,字段将被正确填充,表单将被提交。在另一种情况下,表单会正确填写,但提交按钮会被击得太快。这里的结果是创建了一个记录,但是没有保留名称和描述的输入字段。

    我发现因为我使用的是AngularJS输入表单和表,所以AngularJS需要一点时间来绑定到输入字段。如果这次不允许,则不会保存输入数据。

    水豚提供了诸如“内”和“查找”等等待方法。我使用了这些,但它们对AngularJS绑定时间问题没有帮助。我发现可以使用ng if创建一个if语句来等待特定项,该项表示表单字段的AngularJS绑定已完成。

    所以我使用水豚等待方法来等待我想要填充的字段,我使用AngularJS'ng-if来显示字段,直到它们准备好。

    实现
    index.html.erb

    <div  ng-if="tableParams.data">
      <table id="costings_table ng-table="tableParams" class="table">
        <td id="field1">{{table.field1}}</td>
        <td id="field2">{{table.field2}}</td>
      </table>
    </div>
    

    结果4

    测试终于通过了!然而,我有所有这些与xpath的查找方法,确保特定和困难的目标项目等待...

    即使在我的gem文件中,我运行的是gem phantomJS版本2.1.1,我的命令行版本只有1。十.这证明是重要的。

    我更新了我的命令行phantomJS版本到2.1.1。与此同时,我确保我所有的输入框、按钮、表格、标题都有唯一的标识。然后,我就可以在不破坏测试的情况下删除所有查找(: xpath)事件。

    结果5

    这套测试现在一直可靠地通过!正是我想要的!对

  • 共有2个答案

    邬宏扬
    2023-03-14

    当测试使用水豚的fill_inDSL时出现了问题。在一些测试运行中,字段将被正确填充,表单将被提交。在另一种情况下,表单会正确填写,但提交按钮会被击得太快。这里的结果是创建了一个记录,但是没有保留名称和描述的输入字段。

    AngularJS’ng如果需要使用if语句,则在表单字段准备就绪之前,不会显示表单字段
    这需要结合使用水豚等待方法来完成,以确保填写字段仅在表单加载完成后提交。

    指数html。雇员再培训局或同等机构:

    <div  ng-if="tableParams.data">
      <table id="costings_table ng-table="tableParams" class="table">
        <td id="field1">{{table.field1}}</td>
        <td id="field2">{{table.field2}}</td>
       </table>
    </div>
    

    为了实现可靠的测试,这似乎使测试能够在没有水豚等待方法的情况下运行。

    更新的测试代码
    显示成本核算规格rb

    require "rails_helper"
    
    RSpec.describe "Show a new costing in the listing,", :type => :feature do
    
      before :each do
        admin_sign_in
        create_costing("test1")
      end
    
      it "shows the costing after creation" do
        within "#costings_table" do
          expect(page.find("#code2")).to have_content("2")
          expect(page.find("#name2")).to have_content("test1")
        end
      end
    
      it "shows the details of the new costing after creation" do
        within "#costings_table" do
          click_on "show2"
        end
    
        expect(page.find("#page_title")).to have_content("Costing Details")
        expect(page.find("#code")).to have_content("2")
        expect(page.find("#name")).to have_content("test1") 
        expect(page.find("#description")).to have_content("test description")
      end
    end
    

    rails_helper.rb

    # This file is copied to spec/ when you run 'rails generate rspec:install'
    ENV["RAILS_ENV"] ||= 'test'
    require File.expand_path("../../config/environment", __FILE__)
    
    # Add library functions here so we can test them.
    require File.expand_path(File.dirname(__FILE__) + "/../lib/general")
    
    require 'rspec/rails'
    require 'devise'
    
    RSpec.configure do |config|
      config.before(:suite) do
        # Requires supporting ruby files with custom matchers and macros, etc,
        # in spec/support/ and its subdirectories.
        require File.expand_path(File.dirname(__FILE__) + "/support/blueprints")
        Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
    
        # Setup Devise before it is used in rails_helper
        config.include Devise::TestHelpers, :type => :controller
        Devise.stretches = 1 # Improves speed.
    end
    
    config.include Capybara::DSL, :type => :feature
      config.mock_with :rspec
    
    # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
    config.fixture_path = "#{::Rails.root}/spec/fixtures"
    
    # Allow a 'focus' tag so that we can run just a few tests which we are currently working on
    config.filter_run focus: true
    config.run_all_when_everything_filtered = true
    config.filter_run_excluding :slow unless ENV["SLOW_SPECS"]
    
    # Defer Garbage Collection
    config.before(:all) { DeferredGarbageCollection.start }
    config.after(:all)  { DeferredGarbageCollection.reconsider }
    
    # Integration Testing
    require 'capybara/rspec'
    require 'capybara/poltergeist'
    
    Capybara.register_driver :poltergeist_debug do |app|
      Capybara::Poltergeist::Driver.new(app, {:inspector => true, js_errors: false })  
    end
    
    Capybara.javascript_driver = :poltergeist_debug
    Capybara.default_driver = :poltergeist_debug
    
    # Debugging tools
    def debugit
      puts current_url
      require 'pry'
      binding.pry
    end
    
    # If you're not using ActiveRecord, or you'd prefer not to run each of your
    # examples within a transaction, remove the following line or assign false
    # instead of true.
    config.use_transactional_fixtures = false
    
    #Show Deprications As Errors with full backtracing
    config.raise_errors_for_deprecations!
    
    #rest of the file....
    # Final part of Configure Database Cleaner
    
    Capybara.default_max_wait_time = 5
    config.use_transactional_fixtures = false
    
    config.before(:suite) do
      if config.use_transactional_fixtures?
        raise(<<-MSG)
          Delete line `config.use_transactional_fixtures = true` from
          rails_helper.rb (or set it to false) to prevent uncommitted
          transactions being used in JavaScript-dependent specs. During 
          testing, the app-under-test that the browser driver connects to 
          uses a different database connection to the database connection 
          used by the spec. The app's database connection would not be 
          able to access uncommitted transaction data setup over the 
          spec's database connection.
         MSG
      end
      DatabaseCleaner.clean_with(:truncation)
    end  
    
    config.before(:each) do
      DatabaseCleaner.strategy = :transaction
    end
    
    config.before(:each, type: :feature) do
      # :rack_test driver's Rack app under test shares database connection
      # with the specs, so continue to use transaction strategy for speed.
      driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test
    
        if !driver_shares_db_connection_with_specs
          # Driver is probably for an external browser with an app
          # under test that does *not* share a database connection with the
          # specs, so use truncation strategy.
          DatabaseCleaner.strategy = :truncation
        end
      end
    
      config.before(:each) do
        DatabaseCleaner.start
      end
    
      config.append_after(:each) do
        DatabaseCleaner.clean
      end
    end
    
    
    def admin_sign_in
      visit "/login"
    
      #Create staff member in database
      Staff.make!(:admin)
    
      #Log In
      fill_in "staff_username", with: "adminstaff"
      fill_in "staff_password", with: "password"
      click_button "login"
    
      expect(page).to have_text('Logout')
    end
    
    def create_costing(item)
      @item = item
      visit "/api#/costings"
    
      expect(page).to have_selector("#new_btn")
      click_on "new_btn"
    
      expect(page).to have_text("New Costing")
      within "#form_costing" do
        fill_in "name", with: "#{@item}"
        fill_in "description", with: "test description"
        fill_in "from_date1", with: "15/02/2015" 
        fill_in "cost_hourly_cents1", with: "12.00"
    
        expect(page).to have_selector("#create_btn")
        click_on "create_btn"
      end
      expect(page.find("#page_title")).to have_content("Costings")
    end
    
    姜育
    2023-03-14

    立即跳出的事情是您的管理员登录实际上并不等待登录完成。这意味着您可以在浏览器中未设置会话cookie的情况下调用create\uadmin\u sign\u in方法中的最后一行应该是

    expect(page).to have_text('You are signed in') # whatever message is shown upon sign in
    

    或者

    expect(page).to have_current_path('/') # whatever path an admin is redirected to upon signing in
    

    这将确保登录实际上已经完成,因此会话cookie已经在您的浏览器中设置。

    另外,数据库清理器配置应该在块之后使用append_,而不是在块之后使用append_-请参阅https://github.com/DatabaseCleaner/database_cleaner#rspec-以水豚为例

     类似资料:
    • 我是写集成测试的新手,所以如果这个问题看起来很初级,请原谅(尽管我花了几个小时在网上寻找答案)。 我与Rails 4、RSpec和Capybara合作。 这是我的代码: 错误: 链接在浏览器中工作正常。我试着保存并打开这个页面,它确实显示了一个空白页面。我的所有RSpec单元测试都使用当前配置。控制器不能呈现我的页面吗?如果是,我如何修复它?我现在没有任何控制器测试。 谢谢你的建议! 我的等级库助

    • 我是cucumber和水豚的新手,我对以下错误感到困惑: 在我的功能中,我有: 我的步骤如下所示: 我尝试了“click(button\u text)和click\u link”方法。我想这可能是我没有看到的明显的东西。我试图找到按钮元素的css定位器,然后单击该元素。我认为regex不需要更改,因为我正在更改“button\u text”局部变量的内容。还是我?

    • 我正在使用factory girl和capybara的minitest进行集成测试。当我不使用factory girl创建用户对象时,Capybara工作正常,如下所示: 但是一旦我尝试用工厂女孩创建一个用户,奇怪的事情就开始发生,比如访问方法和click_button方法停止工作。例如,这个测试似乎没有任何问题: 这是我的factories.rb: 下面是我得到的实际错误: 但是,如果我删除了u

    • 当我运行命令gradle war integrationTest时,集成测试失败,因为它在服务项目中找不到上下文侦听器。错误消息的片段如下: 对此我们非常感谢您的帮助。提前致谢

    • 问题内容: 我用Java对外观做一些事情的集成测试进行了测试,其中包括对elasticsearch数据库的索引操作。这个弹性的搜索数据库已经非常幼稚地建立了(实际上是开箱即用的东西,我在学习中)。也非常幼稚地在该立面内使用Java api插入了该示例,该示例几乎完全复制了从elasticsearch中粘贴的示例,如此处所述:http : //www.elasticsearch.org/guide/

    • 我有一个用selenium进行单元测试和集成测试的项目。 当我用IntelliJ执行cucumber集成测试时,它工作得很好,您可以看到: 用Intellij执行cucumber集成测试 但是,当我执行mvn集成测试时,似乎没有发现任何联调: 故障保护输出 我定义了以下POM: > 文件夹结构是文件夹结构 mvn集成-测试输出https://drive . Google . com/file/d/