【问题标题】:Trying to load a yaml file, iterate through the hash and execute some logic尝试加载 yaml 文件,遍历哈希并执行一些逻辑
【发布时间】:2015-04-03 02:14:58
【问题描述】:

尝试加载一个 yaml 文件,遍历哈希并执行一些逻辑。我正在使用 Watir-Webdriver/Ruby 来回答随机选择的问题,这些问题/答案是已知的并存储在 YAML 文件 (kba.yml) 中。

我正在使用 Ruby/页面对象/YAML 文件/Watir-Webdriver。

我的 YAML 文件 (kba.yml):

1:
  question: "Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'."
  answer: "Google"

2:  
  question: "According to our records, you graduated from which of the following High Schools?"
  answer: "NONE OF THE ABOVE/DOES NOT APPLY"

3:  
  question: "I was born within a year or on the year of the date below."
  answer_1: "1942"
  answer_2: "1941"
  answer_3: "1943"

我在哪里加载我的 YAML 文件(在我的 env.rb 中):

require 'yaml'
KBA = YAML.load_file('config/data/kba.yml')

我的代码从 yaml 文件中迭代哈希并执行一些逻辑:

循环第一个随机问题:

KBA.each do |key, value| 
  value.each do |question, answer|
    puts "blah question: #{question}"
      if (@browser.h2s[0].text.sub (/^\d.\s/), '') == question
        puts "Question matched and selected: #{question}"
        case answer
        when @browser.labels[0].text
          select_first_q_first_radio
          puts "Answer matched and selected #{answer}"
        when @browser.labels[1].text
          select_first_q_second_radio
          puts "Answer matched and selected #{answer}"
        when @browser.labels[2].text
          select_first_q_third_radio
          puts "Answer matched and selected #{answer}"
        when @browser.labels[3].text
          select_first_q_fourth_radio
          puts "Answer matched and selected #{answer}"
        when @browser.labels[4].text
          select_first_q_fifth_radio 
          puts "Answer matched and selected #{answer}"
        else 
          puts "The answer is not present for this question!"
        end
      else
        puts "This question is not stored in the dataset: #{@browser.h2s[0].text}"
      end
    end
end

循环第二个随机问题:

KBA.each do |question, answer| 
    if (@browser.h2s[1].text.sub (/^\d.\s/), '') == question
      puts "Question matched and selected: #{question}"
      case answer
      when @browser.labels[0].text
        select_second_q_first_radio
        puts "Answer matched and selected #{answer}"
      when @browser.labels[1].text
        select_second_q_second_radio
        puts "Answer matched and selected #{answer}"
      when @browser.labels[2].text
        select_second_q_third_radio
        puts "Answer matched and selected #{answer}"
      when @browser.labels[3].text
        select_second_q_fourth_radio
        puts "Answer matched and selected #{answer}"
      when @browser.labels[4].text
        select_second_q_fifth_radio 
        puts "Answer matched and selected #{answer}"
      else 
        puts "The answer is not present for this question!"
      end
    else
      puts "This question is not stored in the dataset: #{@browser.h2s[1].text}"
    end  
  end

循环第三个随机问题:

  KBA.each do |question, answer| 
      if (@browser.h2s[2].text.sub (/^\d.\s/), '') == question
        puts "Question matched and selected: #{question}"
        case answer
        when @browser.labels[0].text
          select_third_q_first_radio
          puts "Answer matched and selected #{answer}"
        when @browser.labels[1].text
          select_third_q_second_radio
          puts "Answer matched and selected #{answer}"
        when @browser.labels[2].text
          select_third_q_third_radio
          puts "Answer matched and selected #{answer}"
        when @browser.labels[3].text
          select_third_q_fourth_radio
          puts "Answer matched and selected #{answer}"
        when @browser.labels[4].text
          select_third_q_fifth_radio 
          puts "Answer matched and selected #{answer}"
        else 
          puts "The answer is not present for this question!"
        end
      else
        puts "This question is not stored in the dataset: #{@browser.h2s[2].text}"
      end 
    end
end

从输出看来,我的代码实际上并没有检查问题和答案的正确值,我该怎么做?

这是输出:

blah question: question
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: question
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: question
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: question
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: question
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: question
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: question
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: question
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer_1
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer_2
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
blah question: answer_3
This question is not stored in the dataset: 1. Which of the following is a current or previous employer? If there is not a matched employer name, please select 'NONE OF THE ABOVE'.
This question is not stored in the dataset: 2. I was born within a year or on the year of the date below.
This question is not stored in the dataset: 2. I was born within a year or on the year of the date below.
This question is not stored in the dataset: 2. I was born within a year or on the year of the date below.
This question is not stored in the dataset: 2. I was born within a year or on the year of the date below.
This question is not stored in the dataset: 2. I was born within a year or on the year of the date below.
This question is not stored in the dataset: 2. I was born within a year or on the year of the date below.
This question is not stored in the dataset: 2. I was born within a year or on the year of the date below.
This question is not stored in the dataset: 2. I was born within a year or on the year of the date below.
This question is not stored in the dataset: 3. Which of the following represents the last four digits of your primary checking account number?
This question is not stored in the dataset: 3. Which of the following represents the last four digits of your primary checking account number?
This question is not stored in the dataset: 3. Which of the following represents the last four digits of your primary checking account number?
This question is not stored in the dataset: 3. Which of the following represents the last four digits of your primary checking account number?
This question is not stored in the dataset: 3. Which of the following represents the last four digits of your primary checking account number?
This question is not stored in the dataset: 3. Which of the following represents the last four digits of your primary checking account number?
This question is not stored in the dataset: 3. Which of the following represents the last four digits of your primary checking account number?
This question is not stored in the dataset: 3. Which of the following represents the last four digits of your primary checking account number?

更新:带有 3 个问题的页面的页面对象:

class LOA2KBAQuestions

  include PageObject
  include ErrorMessages
  include DataMagic

  h2(:question, :class => "question")

  #radio buttons for the answers for the first question
  radio_button(:first_q_first_radio, :id => "answers_question_0_1")
  radio_button(:first_q_second_radio, :id => "answers_question_0_2")
  radio_button(:first_q_third_radio, :id => "answers_question_0_3")
  radio_button(:first_q_fourth_radio, :id => "answers_question_0_4")
  radio_button(:first_q_fifth_radio, :id => "answers_question_0_5")

  #radio buttons for the answers for the second question
  radio_button(:second_q_first_radio, :id => "answers_question_1_1")
  radio_button(:second_q_second_radio, :id => "answers_question_1_2")
  radio_button(:second_q_third_radio, :id => "answers_question_1_3")
  radio_button(:second_q_fourth_radio, :id => "answers_question_1_4")
  radio_button(:second_q_fifth_radio, :id => "answers_question_1_5")

  #radio buttons for the answers for the third question
  radio_button(:third_q_first_radio, :id => "answers_question_2_1")
  radio_button(:third_q_second_radio, :id => "answers_question_2_2")
  radio_button(:third_q_third_radio, :id => "answers_question_2_3")
  radio_button(:third_q_fourth_radio, :id => "answers_question_2_4")
  radio_button(:third_q_fifth_radio, :id => "answers_question_2_5")

  button(:submit, :text => "Submit Answers")
end

我还访问了这样的实际问题(它们都在 h2 标签中,我使用正则表达式删除问题前的 #。我通过在 h2 标签后添加 [x] 来访问问题):

@browser.h2s[0].text.sub (/^\d.\s/), ''

所以我最终没有将声明的页面对象用于 h2 标记,因为我不确定如何使用它来访问 3 个问题。

更新 - 3 个问题页面的示例 HTML:

  <div class="question">

    <h2>


        1.
        Which of the following is a current or previou…

    </h2>
    <div class="answers">
        <p>
            <label>
                <input id="answers_question_0_1" type="radio" value="1" name="answers[question_0]" checked="checked"></input>


                RITEWAY

            </label>
        </p>
        <p>
            <label>
                <input id="answers_question_0_2" type="radio" value="2" name="answers[question_0]"></input>


                NEW ALTERNATIVES

            </label>
        </p>
        <p></p>
        <p></p>
        <p></p>
    </div>

</div>
<div class="question">

    <h2>


        2.
        I was born within a year or on the year of the…

    </h2>
    <div class="answers">
        <p>
            <label>
                <input id="answers_question_1_1" type="radio" value="1" name="answers[question_1]" checked="checked"></input>


                1936

            </label>
        </p>
        <p>
            <label>
                <input id="answers_question_1_2" type="radio" value="2" name="answers[question_1]"></input>


                1939

            </label>
        </p>
        <p>
            <label>
                <input id="answers_question_1_3" type="radio" value="3" name="answers[question_1]"></input>


                1942

            </label>
        </p>
        <p></p>
        <p></p>
    </div>

</div>

【问题讨论】:

  • 如果您能解释您的代码试图实现的逻辑,这可能会有所帮助。例如,不清楚第一个、第二个和第三个问题的循环之间需要有什么区别。最终,我认为您正在寻找如何从哈希中获取特定值。例如,第一个循环中的question 将是一个哈希键——即“问题”。如果你想要真正的问题,它应该是value['question']
  • 应用程序中生成了 3 个随机问题,我有一个数据 yaml 文件 (kba.yml),其中包含这些随机潜在问题和答案。所以我对每个问题都有一个循环(因此有 3 个循环)。每个循环都会将随机生成的问题与我的 yaml 文件进行比较。
  • 我明白了。循环似乎是一种更复杂的方法。得到问题然后在 YAML 文件中查找具体答案不是更容易吗?无论哪种方式,您能否提供页面(即 3 个问题的 HTML)?
  • 是的,这可能是一种更好的方法,对这种方法的任何见解都会很棒! :) 我将使用包含 3 个问题的页面的页面对象更新问题。感谢您的帮助贾斯汀!
  • 你能提供HTML吗?我很难看到检查标签当前是如何工作的,以及第三个问题有 3 个答案意味着什么。拥有 HTML 将更容易查看其他方法是否可行。

标签: ruby selenium-webdriver watir-webdriver page-object-gem pageobjects


【解决方案1】:

问题在于 YAML 文件的循环方式。例如,在:

KBA.each do |key, value|
  value.each do |question, answer|
  end
end

value 是一个散列,所以questionanswer 不是预期值。它们实际上是键/值对。应该是:

KBA.each do |key, value|
  question = value['question']
  answer = value['answer']
end

我不会尝试对 YAML 文件中的每个问题/答案进行交互,而是查找特定的问题和答案。在以下页面对象中,answer_questions 将:

  1. 根据 h2 元素确定问题的内容。
  2. 查看 YAML 文件以找到问题的所有有效答案。
  3. 查找并选择与其中一个有效答案匹配的单选按钮。

示例页面对象:

class MyPage
  include PageObject

  divs(:question, :class => 'question')

  def answer_questions
    question_elements.each do |question|
      # Determine what the question is
      question_text = question.h2_element.text.sub(/^\d.\s/, '')

      # Get the valid answers for the question
      question_data = KBA.find { |_, value| value['question'] == question_text }
      unless question_data
        puts "Question not found: #{question_text}"
        next
      end
      valid_answers = question_data[1].select { |k, _| k =~ /answer/ }.values

      # Set the radio buttons if they match one of the answers
      answer = question.radio_button_elements.find do |radio|
        label = radio.parent.text
        valid_answers.include?(label)
      end
      unless answer
        puts "Unable to answer question: #{question_text}"
        next
      end
      answer.select
    end
  end
end

【讨论】:

  • 谢谢贾斯汀,您的解决方案是否考虑到所有 3 个问题的答案可能是相同的答案:“以上都不是/不适用”和出生日期/年份问题?跨度>
  • valid_answers 数组用于解释出生日期/年份问题(或任何具有多个可能答案的问题)。单选按钮的定位仅限于特定的问题 div,因此它应该处理具有相同答案的多个问题。
  • 是的,末尾的select 用于选择单选按钮。 question.radio_button_elements.find 返回一个单选按钮元素,然后调用 select 方法。
  • KBA.find 将返回一个类似于[1, {"question" =&gt; "the question", "answer" =&gt; "the answer"}] 的数组。所以需要[1] 来获取第二个元素中的哈希值。
  • 重构代码以输出未知或无法回答的问题。找到问题后,该方法将转到下一个问题。
猜你喜欢
  • 1970-01-01
  • 2012-07-22
  • 2014-06-01
  • 2013-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-25
  • 2016-04-12
相关资源
最近更新 更多