CSC/ECE 517 Fall 2016/E1671. Unit Tests for participants.rb Hierarchy

From Expertiza_Wiki
Jump to navigation Jump to search

This wiki page is for the description of changes made under E1671 OSS assignment for Fall 2016, CSC/ECE 517.


Background

Expertiza is an open source web based peer review system developed and maintained by students and faculty members at North Carolina State University. It enables students enrolled in a particular course to form online teams and complete assignments.

Problem

The participant, course_participant and assignment_pariticipant models does not have any unit tests.

Work to be Done

  • Create a Factory for assignment participant and course participant model.
  • Test the relationships and validations
  • Write model spec for major instances

Files Modified/Created

  • spec/factories/factories.rb
  • spec/models/participant_spec.rb
  • spec/models/assignment_participant_spec.rb
  • spec/models/course_participant_spec.rb

Unit Test Description

Unit tests are used to test the functionality of methods in the model. These tests can be based on either test-driven development (TDD) or behavior-driven development (BDD). BDD is preferred for testing because it easy to understand compared to the more specialized TDD.<ref>https://www.toptal.com/freelance/your-boss-won-t-appreciate-tdd-try-bdd</ref> In this project, BDD is used to test the functionality using RSpec. RSpec is a testing tool for ruby using the BDD approach.<ref>https://semaphoreci.com/community/tutorials/getting-started-with-rspec</ref> Factories are used to populate the database before the tests are run.

Factories for the Given Classes

The factory for the Participant class is already present. The factories for the other two classes will be very similar. The only differentiating value will be type which can either equal AssignmentParticipant or CourseParticipant depending on the class. Below the factories for AssignmenmentParticipant and CourseParticipant are given.

 factory :assignment_participant, class: AssignmentParticipant do
    can_submit true
    can_review true
    assignment { Assignment.first || association(:assignment) }
    association :user, factory: :student
    submitted_at nil
    permission_granted nil
    penalty_accumulated 0
    grade nil
    type "AssignmentParticipant"
    handle "handle"
    time_stamp nil
    digital_signature nil
    duty nil
    can_take_quiz true
  end

factory :course_participant, class: CourseParticipant do
    course { Course.first || association(:course) }
    can_submit true
    can_review true
    assignment { Assignment.first || association(:assignment) }
    association :user, factory: :student
    submitted_at nil
    permission_granted nil
    penalty_accumulated 0
    grade nil
    type "CourseParticipant"
    handle "handle"
    time_stamp nil
    digital_signature nil
    duty nil
    can_take_quiz true
  end

Participant Unit Test

The Participant class is the base class for both the AssignmentParticipant class and the CourseParticipant class. We have used the rspec framework to test each of these three classes. The factory library used is Factory Girl and the factories themselves are located in factories.rb. Tests are usually centered around conditional statements, for example if there is a statement following a condition that evaluates to be true. Here it can be tested that the statement is always executed correctly when the condition evaluates to true.

The participant class is used to describe the participants of a university class. Unit tests for this class is written in the participant_spec.rb file. The first few unit tests defined are used to test the value of data members. There are also three unit tests to test the functionality of the fullname, topicname and name methods.

require 'rails_helper'


describe Participant do

  before(:each) do
    @student = create(:student, name: "Student", fullname: "Student Test", email: "student1@gmail.com" , password: "123456", password_confirmation: "123456")
    @assignment = create(:assignment, name: "Assignment1", course: nil)
    @participant = create(:participant, parent_id: @assignment.id, user_id: @student.id)
    @assignment_questionnaire1 =create(:assignment_questionnaire, user_id: @student.id, assignment: @assignment)
  end
  it "is valid" do
    expect(@participant).to be_valid
  end

  it "can review" do
    expect(@participant.able_to_review).to be true
  end
  it "can submit" do
    expect(@participant.can_submit).to be true
  end
  it "can take quiz" do
    expect(@participant.can_take_quiz).to be true
  end
  it "has 0 penalty accumulated" do
    expect(@participant.penalty_accumulated).to be_zero
  end
 it "is type of assignment participant" do
   expect(@participant.type).to eql "AssignmentParticipant"
 end
  describe "#topicname" do
 it "returns the topic name" do
   expect(@participant.topic_name).to eql "<center>—</center>"
 end
 end

  describe "#name" do
    it "returns the name of the user" do
      expect(@participant.name).to eql "Student"
    end
  end
  describe "#fullname" do
  it "returns the full name of the user" do
    expect(@participant.fullname).to eql "Student Test"
  end
  end

end

Assignment Participant Unit Test

The AssignmentParticipant class inherits from the Participant class. This first test is to validate whenever an object of AssignmentParticipant is created. Then there are three tests for the methods type, average_scores and copy. Lastly there are four unit tests defined to test the functionality of the method import. These tests can be found in assignment_participant_spec.rb.

require 'rails_helper'
describe "AssignmentParticipant" do
  describe "validations" do
    before(:each) do
      @assignment_participant = build(:assignment_participant)
    end

    it "assignment participant is valid" do
      expect(@assignment_participant).to be_valid
    end
  end

  describe "#type" do
    it "checks if type is assignment participant" do
      assignment_participant = build(:assignment_participant)
      expect(assignment_participant.type).to eq("AssignmentParticipant")
    end
  end

  describe "#average_scores" do
    it "returns 0 if self.response_maps is empty" do
      assignment_participant = build(:assignment_participant)
      sum_scores = assignment_participant.average_score
      expect(sum_scores).to be_zero
    end
  end

  describe "#copy" do
    it "creates a copy if part is empty" do
      assignment_participant = build(:assignment_participant)
      course_part = assignment_participant.copy(0)
      expect(course_part).to be_an_instance_of(CourseParticipant)
    end
  end

  describe "#import" do
    it "raise error if record is empty" do
      row = []
      expect {AssignmentParticipant.import(row,nil,nil,nil)}.to raise_error("No user id has been specified.")
    end

    it "raise error if record does not have enough items " do
      row = ["user_name","user_fullname","name@email.com"]
      expect {AssignmentParticipant.import(row,nil,nil,nil)}.to raise_error("The record containing #{row[0]} does not have enough items.")
    end

    it "raise error if assignment with id not found" do
      assignment = build(:assignment)
      session = {}
      row =[]
      allow(Assignment).to receive(:find).and_return(nil)
      allow(session[:user]).to receive(:id).and_return(1)
      row = ["user_name","user_fullname","name@email.com","user_role_name","user_parent_name"]
      expect {AssignmentParticipant.import(row,nil,session,2)}.to raise_error("The assignment with id \"2\" was not found.")
    end

    it "creates assignment participant form record if it does not exist" do
      assignment = build(:assignment)
      session = {}
      row =[]
      allow(Assignment).to receive(:find).and_return(assignment)
      allow(session[:user]).to receive(:id).and_return(1)
      row = ["user_name","user_fullname","name@email.com","user_role_name","user_parent_name"]
      assign_part = AssignmentParticipant.import(row,nil,session,2)
      expect(assign_part).to be_truthy
    end
  end
end

Course Participant Unit Test

The Course Participant class is to show the participation of the student into a particular course. The course participant class is inherited from the participant class associated with the course class through belongs_to relationship. We have tested the four different methods of the class course participant. These tests are found in the course_participant_spec.rb file. The first method to test is the copy method. The copy method checks if an assignment participant exists for the corresponding parent_id. If it exists then a null is returned otherwise a new object for assignment participant is returned. We check both the functionality of the methods using two different tests for the method class. The next important method is the import method. The import method consists of four different scenarios and thus we have written test for testing four different scenarios for the import method. The import method takes a record field and input and checks for various condition on the record field and creates the course participant object. Below is a short snipped of the various tests written for the copy and import method

 describe "#copy" do

    it "create a copy of participant" do
      assignment = build(:assignment)
      course_participant = build(:course_participant)
      assign_part = build(:assignment_participant)

      allow(AssignmentParticipant).to receive(:create).and_return(assign_part)
      allow(assign_part).to receive(:set_handle).and_return(true)

      expect(course_participant.copy(assignment.id)).to be_an_instance_of(AssignmentParticipant)

    end

    it "returns nil if copy exist" do
      assignment = build(:assignment)
      course_participant = build(:course_participant)
      assign_part = build(:assignment_participant)

      allow(AssignmentParticipant).to receive(:where).and_return(AssignmentParticipant)
      allow(AssignmentParticipant).to receive(:first).and_return(assign_part)
      allow(assign_part).to receive(:set_handle).and_return(true)

      expect(course_participant.copy(assignment.id)).to be_nil
    end
  end
  describe "#import" do

    it "raise error if record is empty" do
      row = []
      expect {CourseParticipant.import(row,nil,nil,nil)}.to raise_error("No user id has been specified.")
    end

    it "raise error if record does not have enough items " do
      row = ["user_name","user_fullname","name@email.com"]
      expect {CourseParticipant.import(row,nil,nil,nil)}.to raise_error("The record containing #{row[0]} does not have enough items.")
    end

    it "raise error if course with id not found" do
      course = build(:course)
      session = {}
      row =[]
      allow(Course).to receive(:find).and_return(nil)
      allow(session[:user]).to receive(:id).and_return(1)
      row = ["user_name","user_fullname","name@email.com","user_role_name","user_parent_name"]
      expect {CourseParticipant.import(row,nil,session,2)}.to raise_error("The course with the id \"2\" was not found.")
    end

    it "creates course participant form record" do
      course = build(:course)
      session = {}
      row =[]
      allow(Course).to receive(:find).and_return(course)
      allow(session[:user]).to receive(:id).and_return(1)
      row = ["user_name","user_fullname","name@email.com","user_role_name","user_parent_name"]
      course_part = CourseParticipant.import(row,nil,session,2)
      expect(course_part).to be_an_instance_of(CourseParticipant)
    end

  end

Run the Test

The tests can be run on the terminal from inside the expertiza folder using following commands:

For participant:

 rspec spec/models/participant_spec.rb

For assignment_participant:

 rspec spec/models/assignment_participant_spec.rb

For participant:

 rspec spec/models/assignment_participant_spec.rb

External Links

https://github.com/hsy12321/expertiza

References

<references />