CSC/ECE 517 Spring 2018 E1812: Difference between revisions
Line 102: | Line 102: | ||
cd/expetiza/app/models | cd/expetiza/app/models | ||
The on_the_fly_calc.rb model file is present in this directory | The on_the_fly_calc.rb model file is present in this directory. | ||
=== Functionality of OnTheFlyCalc model === | |||
The OnTheFlyCal model is a module for the Assignment Class to calculate scores. Here are methods provided by this module: | |||
The compute_total_score method is to compute the total score of a given assignment. The method collects all questionnaires of the assignment and calls the get_weighted_score method of Questionnaire Class to calculate the total score. | |||
The get_weighted_score checks the round which the assignment questionnaire has been used and calls the compute_weighted_score method to finish the calculation. As for the symbol, if the questionnaire has never been used, the compute_weight_score just takes the symbol of the questionnaire; if the questionnaire has been used, the symbol is the symbol of the questionnaire plus the round. The compute_weighted_score method takes the symbol and the score to complete the final calculation. The method uses the raw average scores times the weight of the questionnaire and divides by 100.0. If the raw average is nil, it returns zero. The compute_reviews_hash method returns the hash of reviewers. First, the method will check whether the assignment varies rubrics by round and deal with the two cases separately. This procedure is also shared by the compute_avg_and_ranges_hash and scores methods because the difference between those two situations is critical. The class method varying_rubrics_by_round? of the assignment is essential. It searches for assignment_questionnaires which have been used in 2 rounds with for the current assignment. If no assignment questionnaire meets the conditions, it returns false. | |||
For both cases, the hash of reviewers are generated with private methods and the raw score is rounded. If the assignment varies rubrics by round, every round will be included. | |||
The compute_avg_and_ranges_hash method calculates the average scores, the range of scores and their corresponding hashes. Using the built-in method review_questionnaire_id, it collects review questions and finds questions. The compute_scores method of answer model is called to calculate the maximum, minimum and average of scores. Similar to the get_weighted_score method, if the assignment varies rubrics by round, every round is included. | |||
The last method score calculates scores of a question. It calls private methods score_assignment and participant_score to obtain hashes of teams and participants. Like previous methods, it deals with two cases. If varying_rubrics_by_round? is true, it calls another three private methods to calculate the number of rounds, the average, and range of assessments and scores. If it does not vary, assessments and scores are obtained with the built-in method get_assessments_for of ReviewResponseMap and compute_scores of Answer. That is the general function of the OnTheFlyCalc module. | |||
==Conclusions== | ==Conclusions== |
Revision as of 01:52, 3 April 2018
Introduction
Expertiza
Expertiza is an open source web application based on Ruby on Rails framework, supported by the National Science Foundation. It is a place where students can submit and peer-review learning objects (assignments, codes, write ups, websites, etc). For an instructor, expertiza allows to create and customize new or existing assignments. For students, it allows to create and work on various projects and assignments. It provides a platform to peer review other students' submissions across various document types, including the URLs and wiki pages. The project aims to write a unit test for on_the_fly_calc.rb. This model file provides a module for assignments to calculate different kinds of scores when loading the views. However, there was no corresponding unit test and the coverage was only 15.45% after running all test cases.
Test Driven-Development
Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: Requirements are turned into very specific test cases, then the software is improved to pass the new tests, only. This is opposed to software development that allows software to be added that is not proven to meet requirements. Test-driven development is related to the test-first programming concepts of extreme programming, begun in 1999,but more recently has created more general interest in its own right. The TDD sequence can be can be summarized in following steps.
1.Add a Test:
TDD begins by writing succinct test cases to test each of the features. This is opposite to traditional software development paradigm where code is written first and then test cases are later written to test the application.
2.Run all tests and see if the new test fails:
This step validates that the test harness is working correctly, shows that the new test does not pass without requiring new code because the required behavior already exists, and it rules out the possibility that the new test is flawed and will always pass. The new test should fail for the expected reason. This step increases the developer's confidence in the new test.
3.Write the code:
The next step is to write the minimum amount of code that causes the test case to pass.
4.Run tests:
In this steps the test cases are run.If all test cases now pass, the programmer can be confident that the new code meets the test requirements, and does not break or degrade any existing features. If they do not, the new code must be adjusted until they do.
5. Refactor code:
In this step, refactoring of code is performed by following good design principles like removal of duplicate code, improving the readability and maintainability of the code.
6. Repeat:
Starting with another new test,the next step is to repeat the cycle to push the functionality forward.
Advantages of using TDD:
- Narrowing Problem Focus
- Tidier Code
- Not worrying about dependencies
- Easier refactoring
- Better Test coverage and fewer bugs
Unit Testing
Unit Testing is a software testing method by which individual units of source code are tested to catch errors early in the development process. For a model it involves testing the interface and on how it responds to commands and queries from outside. Model testing is bounded to the functionality of only the model under test and doesn't test how its collaborating models get affected based on this query.
Unit Testing provides several benefits which can be summarized in the below points.
1. Finds problems early:
Unit testing finds problems early in the development cycle. This includes both bugs in the programmer's implementation and flaws or missing parts of the specification for the unit. In test-driven development (TDD), which is frequently used in both extreme programming and scrum, unit tests are created before the code itself is written. When the tests pass, that code is considered complete.
2. Facilitates change:
Unit testing allows the programmer to refactor code or upgrade system libraries at a later date, and make sure the module still works correctly (e.g., in regression testing). The procedure is to write test cases for all functions and methods so that whenever a change causes a fault, it can be quickly identified. Unit tests detect changes which may break a design contract.
3. Simplifies Integration:
Unit testing may reduce uncertainty in the units themselves and can be used in a bottom-up testing style approach. By testing the parts of a program first and then testing the sum of its parts, integration testing becomes much easier.
4. Documentation:
Developers looking to learn what functionality is provided by a unit, and how to use it, can look at the unit tests to gain a basic understanding of the unit's interface's API.
5. Design:
When software is developed using a test-driven approach, the combination of writing the unit test to specify the interface plus the refactoring activities performed after the test is passing, may take the place of formal design. Each unit test can be seen as a design element specifying classes, methods, and observable behavior.
Problem Statement
There is no corresponding unit test for on_the_fly_calc.rb. The OnTheFlyCal module provides 4 publish methods for assignments: compute_total_score, compute_reviews_hash, compute_avg_and_ranges_hash and scores. We need to test all those methods. Privately methods are tested when testing public methods instead of tested directly.
Files Involved
The files to be understood and created are:
1. app/models/on_the_fly_calc.rb
2. spec/models/on_the_fly_calc_spec.rb
Team Members
1. Dileep Badveli (dbadvel@ncsu.edu)
2. Minghao Pan (mpan2@ncsu.edu)
Plan of Work
The task is to write test cases for testing the on_the_fly_calc model file. There was no Rspec file for the corresponding model exists so we need to create a new file and build tests from scratch. For this purpose different sub-tasks involved
1. Setting up the Expertiza environment;
2. Understand the functionality of model file in on_the_fly_calc.rb;
3. Understand the linked data attributes and methods being used;
4. Creating stub entries for testing different methods;
5. Writing testing conditions for different methods and compare with the expected outputs. Objects were created using structures left in the factory file when needed. An example of this is let(:questionnaire) { create(:questionnaire, id: 1)}. After developing different objects by this method, the objects get used in test cases to either avoid the implementation of the methods specified in the model or make it return a value which can be used to test if conditions.
Implementation Steps
Expertiza Environment Setup
We used the Ubuntu-Expertiza image to setup the environment. We forked the master from Expertiza, cloned that and then run through the command terminal.
cd/expetiza/app/models
The on_the_fly_calc.rb model file is present in this directory.
Functionality of OnTheFlyCalc model
The OnTheFlyCal model is a module for the Assignment Class to calculate scores. Here are methods provided by this module:
The compute_total_score method is to compute the total score of a given assignment. The method collects all questionnaires of the assignment and calls the get_weighted_score method of Questionnaire Class to calculate the total score.
The get_weighted_score checks the round which the assignment questionnaire has been used and calls the compute_weighted_score method to finish the calculation. As for the symbol, if the questionnaire has never been used, the compute_weight_score just takes the symbol of the questionnaire; if the questionnaire has been used, the symbol is the symbol of the questionnaire plus the round. The compute_weighted_score method takes the symbol and the score to complete the final calculation. The method uses the raw average scores times the weight of the questionnaire and divides by 100.0. If the raw average is nil, it returns zero. The compute_reviews_hash method returns the hash of reviewers. First, the method will check whether the assignment varies rubrics by round and deal with the two cases separately. This procedure is also shared by the compute_avg_and_ranges_hash and scores methods because the difference between those two situations is critical. The class method varying_rubrics_by_round? of the assignment is essential. It searches for assignment_questionnaires which have been used in 2 rounds with for the current assignment. If no assignment questionnaire meets the conditions, it returns false.
For both cases, the hash of reviewers are generated with private methods and the raw score is rounded. If the assignment varies rubrics by round, every round will be included. The compute_avg_and_ranges_hash method calculates the average scores, the range of scores and their corresponding hashes. Using the built-in method review_questionnaire_id, it collects review questions and finds questions. The compute_scores method of answer model is called to calculate the maximum, minimum and average of scores. Similar to the get_weighted_score method, if the assignment varies rubrics by round, every round is included.
The last method score calculates scores of a question. It calls private methods score_assignment and participant_score to obtain hashes of teams and participants. Like previous methods, it deals with two cases. If varying_rubrics_by_round? is true, it calls another three private methods to calculate the number of rounds, the average, and range of assessments and scores. If it does not vary, assessments and scores are obtained with the built-in method get_assessments_for of ReviewResponseMap and compute_scores of Answer. That is the general function of the OnTheFlyCalc module.
Conclusions
Github Page
https://github.com/DileepBadveli/expertiza/blob/master/spec/models/on_the_fly_calc_spec.rb