CSC/ECE 517 Spring 2017/E1724: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
mNo edit summary
Line 54: Line 54:
The code below is a sample of the refactored code where instead of having redundant code, handle_questionaire is called with a few parameters and all of the redundant code in the test cases is replaced.
The code below is a sample of the refactored code where instead of having redundant code, handle_questionaire is called with a few parameters and all of the redundant code in the test cases is replaced.


def validate_attributes(questionaire_name)
  def validate_attributes(questionaire_name)
  questionnaire = get_questionnaire(questionaire_name).first
    questionnaire = get_questionnaire(questionaire_name).first
  expect(questionnaire).to have_attributes(
    expect(questionnaire).to have_attributes(
    questionnaire_weight: 50,
      questionnaire_weight: 50,
    notification_limit: 50
      notification_limit: 50
  )
    )
end
  end


def validate_dropdown
  def validate_dropdown
  questionnaire = Questionnaire.where(name: "ReviewQuestionnaire2").first
    questionnaire = Questionnaire.where(name: "ReviewQuestionnaire2").first
  assignment_questionnaire = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first
    assignment_questionnaire = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first
  expect(assignment_questionnaire.dropdown).to eq(false)
    expect(assignment_questionnaire.dropdown).to eq(false)
end
  end


def fill_in_questionaire(questionaire_css, questionaire_name)
  def fill_in_questionaire(questionaire_css, questionaire_name)
  within(:css, questionaire_css) do
    within(:css, questionaire_css) do
    select questionaire_name, from: 'assignment_form[assignment_questionnaire][][questionnaire_id]'
      select questionaire_name, from: 'assignment_form[assignment_questionnaire][][questionnaire_id]'
    uncheck('dropdown')
      uncheck('dropdown')
    select "Scale", from: 'assignment_form[assignment_questionnaire][][dropdown]'
      select "Scale", from: 'assignment_form[assignment_questionnaire][][dropdown]'
    fill_in 'assignment_form[assignment_questionnaire][][questionnaire_weight]', with: '50'
      fill_in 'assignment_form[assignment_questionnaire][][questionnaire_weight]', with: '50'
    fill_in 'assignment_form[assignment_questionnaire][][notification_limit]', with: '50'
      fill_in 'assignment_form[assignment_questionnaire][][notification_limit]', with: '50'
    end
    click_button 'Save'
    sleep 1
   end
   end
  click_button 'Save'
  sleep 1
end


def handle_questionaire(questionaire_css, questionaire_name, test_attributes)
  def handle_questionaire(questionaire_css, questionaire_name, test_attributes)
  fill_in_questionaire(questionaire_css, questionaire_name)
    fill_in_questionaire(questionaire_css, questionaire_name)
  if test_attributes
    if test_attributes
    validate_attributes(questionaire_name)
      validate_attributes(questionaire_name)
  else
    else
     validate_dropdown
      validate_dropdown
     end
   end
   end
end





Revision as of 23:33, 23 March 2017

E1724 - Refactoring Feature Tests

About Expertiza

Expertiza is an open source web application project based on Ruby on Rails framework. It provides an online interactive platform for instructors to post and grade assignments, and for students to contribute to team-based projects as well as individual assignments.

Problem Statement

Remove duplicated code in feature tests and improve the overall Code Climate.

Refactoring Delayed_mailer Method

Delayed_mailer_spec method covers testing scenarios with the email reminder feature targeting various users and tasks. This method took time stamps using time_parse function, which would create issues when users change their time zones. Calling time_zone_parse instead of time_parse solves the issue. This method also had massive duplicate code for different test scenarios. A helper method enqueue_delayed_job(stage) is used to encapsulate the task being performed.

After refactoring in delayed_mailer_spec.rb:

   def enqueue_delayed_job(stage)
      #enqueue a delayed job using current stage’s timestamp
   end
   describe '<stage> deadline reminder email' do
      it 'is able to send reminder email for <stage> deadline to <stage_users> ' do
        enqueue_delayed_job(stage)
        expect(Delayed::Job.count).to eq(1)
        expect(Delayed::Job.last.handler).to include("deadline_type: <stage>")
      end
   end

Refactoring Scheduled_task_spec Method

Scheduled_task_spec method covers testing scenarios with scheduling for the deadline reminder feature targeting various users and tasks. This method took time stamps using time_parse function, which would create issues when users change their time zones. Calling time_zone_parse instead of time_parse solves the issue. This method also had massive duplicate code for different test scenarios. A helper method enqueue_scheduled_tasks(stage) is used to encapsulate the task being performed.

After refactoring in scheduled_spec.rb:

   def enqueue_scheduled_tasks(stage)
     #enqueue a delayed job using current stage’s timestamp
   end
   describe '<stage> deadline reminder email' do
     it 'is able to send reminder email for <stage> deadline to <stage_users> ' do
       enqueue_scheduled_tasks(stage)
       expect(Delayed::Job.count).to eq(1)
       expect(Delayed::Job.last.handler).to include("deadline_type: <stage>")
     end
   end

Refactoring Assignment_creation_spec

Assignment_creation_spec covers testing scenarios that create public and private assignments as well as the various options in this assignment creation. This using CodeClimate it was identified that a large portion of the code was duplicated across multiple test cases which violates the DRY principle. The redundant code was generalized and placed in methods instead of being written in each of the test cases and redundant methods that were never called were removed from class.

The code below is a sample of the refactored code where instead of having redundant code, handle_questionaire is called with a few parameters and all of the redundant code in the test cases is replaced.

 def validate_attributes(questionaire_name)
   questionnaire = get_questionnaire(questionaire_name).first
   expect(questionnaire).to have_attributes(
     questionnaire_weight: 50,
     notification_limit: 50
   )
 end
 def validate_dropdown
   questionnaire = Questionnaire.where(name: "ReviewQuestionnaire2").first
   assignment_questionnaire = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first
   expect(assignment_questionnaire.dropdown).to eq(false)
 end
 def fill_in_questionaire(questionaire_css, questionaire_name)
   within(:css, questionaire_css) do
     select questionaire_name, from: 'assignment_form[assignment_questionnaire][][questionnaire_id]'
     uncheck('dropdown')
     select "Scale", from: 'assignment_form[assignment_questionnaire][][dropdown]'
     fill_in 'assignment_form[assignment_questionnaire][][questionnaire_weight]', with: '50'
     fill_in 'assignment_form[assignment_questionnaire][][notification_limit]', with: '50'
   end
   click_button 'Save'
   sleep 1
 end
 def handle_questionaire(questionaire_css, questionaire_name, test_attributes)
   fill_in_questionaire(questionaire_css, questionaire_name)
   if test_attributes
     validate_attributes(questionaire_name)
   else
     validate_dropdown
   end
 end


Refactoring Instructor_interface_spec

Instructor_interface_spec covers testing scenarios like creating a course, importing tests, and viewing publishing rights. Unlike assignment_creation_spec, the largest violation (as determined by CodeClimate) of the DRY principle was functionality that was duplicated in questionnaire_spec. In order to fix this /spec/helpers/instructor_interface_helper_spec was created as a module and then included in both of the other Ruby files as a mixin.