CSC/ECE 517 Fall 2016/E1670. Unit tests for answers.rb: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
Line 39: Line 39:
</pre>
</pre>
This is to eliminate tight coupling between compute_scores and get_total_scores. Failure in get_total_scores would'nt break the compute_scores test cases.
This is to eliminate tight coupling between compute_scores and get_total_scores. Failure in get_total_scores would'nt break the compute_scores test cases.


'''Function Name : Get_total_scores'''
'''Function Name : Get_total_scores'''

Revision as of 05:00, 28 October 2016

E1670 . Unit tests for answers.rb

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



Background

Expertiza is an Open Source web application developed on Ruby On Rails platform. It is a platform which allows students to take assignments posted by the course instructors. Expertiza allows students to select assignment topics, form teams and submit their work. It also allows them to review other students' submissions and improve their work based on this feedback.

Project Description

In Expertiza, each questionnaire contains many questions, those question may have different types (e.g. checkbox, criterion, etc). When a user fills in a rubric, the responses for each question will become an answer record. The responses of rubrics are stored in answers table in DB. The answer.rb is the model for the answers table in DB. Answer.rb model does not have any test cases and the aim of the project is to write fast, effective and flexible unit test cases that offer maximum code coverage.


Functions in answers.rb

Function Name : Compute_scores

Compute_scores is a function in model answer.rb which gives the average, maximum and minimum scores obtained in a series a responses/assessments. It has two input parameters: List of assessments and questions. The function iterates over each assessment to get the total score of that assessment. If the response or review is invalid, that assessment won’t be considered in the calculation of the score average. After iterating over all assessments, Max score, and Min scores are calculated along with the average score based on the number of valid assessments. Their scores are returned by the function.


Rspec Unit Test : Compute_scores

Following scenarios are tested:

  • To return scores as nil if the input list of assessments is nil. This is to make sure no Null Pointer exceptions are thrown by the code
  • To return a particular score when a single valid assessment is given as an input.
  • To return a particular score when multiple valid assessments are given as an input. This is to test the looping functionality of the method.
  • To return a particular score when invalid assessments are given as an input. The validity and total scores are returned by a mock and not by the actual functions. This is to make the test cases less rigid so that failure of dependent functions do not disrupt the functionality of interface level tests.
  • To return a particular score when invalid flag is nil. Invalid flag can either be 0,1 or nil. Nil situation is tested to prevent NullPointer Exceptions
  • To check if the method get_total_score is called with the right parameters.

This unit tes uses a stub and returns a mock value.

Answer.stub(:get_total_score)

This is to eliminate tight coupling between compute_scores and get_total_scores. Failure in get_total_scores would'nt break the compute_scores test cases.


Function Name : Get_total_scores

This function is called by the Compute_scores method of the answer.rb model to compute the total score of an assessment. The input consists of assessment for which the total score is being calculated and the list of questions being evaluated in the assessment. The method uses questionnaire id from the questions and response id to obtain a score view questionnaire data. This score view is a read-only record. The questionnaire data mainly consists of q1_max_question_score, sum_of_weights and wieghted_score. Before calculating the score, the function performs two crucial tasks.

  • Checks if the answer for a scored question is nil. If it is nil or unanswered, the question will be ignored and not counted towards the score of this response.
  • Calls the subsission_valid function by passing the response record to set the @invalid flag based on the validity of the response.

The total score is calculated using the below formula

(weighted_score / (sum_of_weights * max_question_score)) * 100

Any edge cases would return -1 indicating no score


Rspec Unit Test : Get_total_scores

Following scenarios are tested:

  • To return an anticipated total score of a single response without any edge cases. Since this function will be called only on one response at a time, there is no need to test for multiple responses at the same time.
  • To return an anticipated total score of a response where nil answer is for a scored question. This is to check if its weight gets removed from the sum_of_weights.
  • To return -1 when the sum of weights becomes 0. This can happen when all the scored questions are unanswered. Return value of -1 is checked at the calling function to ensure if a score is returned or not.
  • To return -1 when weighted_score of questionnaireData is nil
  • To check if submission_valid is called. This method is called to set invalid flag to indicate whether the response entered is valid or not. The validity criteria is explained in the submission_valid? Function.


This unit test uses two stubs and returns mock results

ScoreView.stub(:find_by_sql)
Answer.stub(:where)

This is to reduce the outcome of the test to depend on DB calls. For example, in case the connection to DB fails, this unit test would still pass making it less rigid.