CSC/ECE 517 Fall 2016/E1681.Refactor and test the quizzing feature

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

Expertiza is an online system that is used by students to view/submit assignments and review others' work. Expertiza also provides tools to visualize the scores and gauge the improvements made during the course semester. It also facilitates and monitors team projects. It is targeted at educational and non-profit organizations. The project is funded by the National Software Foundation (NSF), NCSU Learning in a Technology-Rich Environment (LITRE) program, the NCSU Faculty Center for Teaching and Learning, the NCSU STEM Initiative, and the Center for Advanced Computing and Communication. Expertiza is an open-source project with the source code available as a public repository on GitHub. It is developed using Ruby on Rails and is increasingly becoming robust thanks to the innumerable bugs being fixed by the community. The project has a micro-blog on SourceForge where the developer community report bugs and document updates.


Task description

Student-generated quizzes is the feature that students use for writing quizzes for the Wikipedia contribution assignment. In this project, we need to do refactoring and create functional tests for this feature. We need to refactor questionnaires_controller.rb and write the Rspec tests file in /specs/ folder.


Workflow

Methodology

Refactoring:

There is some problems in valid_quiz method which is in questionnaires_controller. For now, this method checks the questions one by one. We will refactor it to make it able to create the quiz_question objects and quiz_choice objects. Then we need to call “quiz_question.valid?” to check whether the question is valid.

The code below is how we do refactoring: def valid_quiz

   num_quiz_questions = Assignment.find(params[:aid]).num_quiz_questions
   valid = "valid"
   (1..num_quiz_questions).each do |i|    
     if params[:questionnaire][:name] == ""
       # questionnaire name is not specified
       valid = "Please specify quiz name (please do not use your name or id)."
       break
     elsif !params.key?(:question_type) || !params[:question_type].key?(i.to_s) || params[:question_type][i.to_s][:type].nil?
       # A type isnt selected for a question
       valid = "Please select a type for each question"
       break
     else
       @new_question = Object.const_get(params[:question_type][i.to_s][:type]).create(txt: , type: params[:question_type][i.to_s][:type], break_before: true)
       @new_question.update_attributes(txt: params[:new_question][i.to_s])
       type = params[:question_type][i.to_s][:type]
       choice_info = params[:new_choices][i.to_s][type]    #choice info for one question of its type 
       if choice_info == nil
         valid = "Please select a correct answer for all questions"
         break
       else
         valid = @new_question.isvalid(choice_info)
         if(valid != "valid")
           break
         end
       end
     end
   end
   valid
 end

The code above is what we changed in questionnaire_controller. And then we created a new method in 3 types question model.

  def isvalid(choice_info)
    valid = "valid"
    if(self.txt == '')
      valid = "Please make sure all questions have text"
    end
    correct_count = 0
    choice_info.each do |idx, value|
      if value[:txt] == ''
        valid = "Please make sure every question has text for all options"
        break
      end
      if value[:iscorrect] == 1.to_s
        correct_count+=1
      end
    end
    if correct_count == 0
      valid = "Please select a correct answer for all questions"
    end
    valid
  end

Testing

We will test the following functionalities:

  • The instructor can set up an assignment which supports quizzing feature by
    • Checking the “has quiz” box
    • Setting the # of question for each set of quiz
    • Setting in which deadline can student reviewers take the quizzes
  • Student authors can create quizzes and edit them:
    • They can create quizzes on the “Your work” page
    • They can edit the quiz questions.
    • They can view the quiz questions.
    • If the quiz question has something missing, the system will flash an error message, either:
      • The name of quiz is missing.
      • The question text is missing for one or more questions.
      • The choices are missing for one or more questions.
      • The correct answer(s) have not been provided.
  • Student reviewers can take the quizzes on the work they have reviewed/they need to review
    • They need to request the artifact to review first. If this artifact has a quiz associated, they can take the quiz in the round which quiz-taking is allowed.
    • They can click “take quiz” then request quizzes to take.
    • They can fill in their choices on the quizzes.
    • After taking the quizzes, and submitting, they will see their grade on the “Take quizzes” page
    • On the “take quizzes” page, they can see their question-by-question scores for finished quizzes by clicking “view”
  • Instructor can view the quiz questions and quiz scores on the tree display by clicking “view quiz questions” icon.

Let's see an example of how we wrote functional tests:

#instructor can set in which deadline can student reviewers take the quizzes
   describe "deadlines", js: true do
    before(:each) do
      @assignment = create(:assignment, name: 'public assignment for test')
      login_as("instructor6")
      visit "/assignments/#{@assignment.id}/edit"
      click_link 'Due date'
    end
    #instructor can set deadline for review and taking quiz
    it "set the deadline for an assignment review" do

      fill_in 'assignment_form_assignment_rounds_of_reviews', with: '1'
      fill_in 'datetimepicker_submission_round_1', with: '2017/11/01 12:00'
      fill_in 'datetimepicker_review_round_1', with: '2017/11/10 12:00'
      click_button 'submit_btn'

      submission_type_id = DeadlineType.where(name: 'submission')[0].id
      review_type_id = DeadlineType.where(name: 'review')[0].id

      submission_due_date = DueDate.find(1)
      review_due_date = DueDate.find(2)
      expect(submission_due_date).to have_attributes(
        deadline_type_id: submission_type_id,
        type: 'AssignmentDueDate'
      )

      expect(review_due_date).to have_attributes(
        deadline_type_id: review_type_id,
        type: 'AssignmentDueDate'
      )
    end
  end 

Schedule

11/07 - 11/15 Design work

11/14 Discuss with instructor

11/14 - 11/20 Write first version

11/20 - 11/25 Debug and test

11/25 - 12/02 Final deployment


Workload Assignment

Refactor: Yi Wei

Test: JunYi Liu(Last 2 bullets), Zhongzhi Qi(First 2 bullets)

Deployment: Lei Zhang

Document Writing: Everyone