CSC/ECE 517 Spring 2019 - Project E1921. Write tests for popup controller.rb: Difference between revisions
(2 intermediate revisions by the same user not shown) | |||
Line 95: | Line 95: | ||
== Test Outline == | == Test Outline == | ||
The following section shows the Rspec outline of the tests we created. The full test code can be found | The following section shows the Rspec outline of the tests we created. The full test code can be found [https://github.com/YChen239/expertiza/blob/master/spec/controllers/popup_controller_spec.rb here] | ||
'''PopupController''' | '''PopupController''' | ||
Line 113: | Line 113: | ||
</pre> | </pre> | ||
Get feedback when feedback exists. | |||
<pre> | <pre> | ||
Line 182: | Line 182: | ||
== Results == | == Results == | ||
The total coverage of the test is 96.41% | The total coverage of the test is 96.41%, meeting our coverage requirement. | ||
=== Related Links=== | === Related Links=== | ||
Line 194: | Line 194: | ||
===Conclusion=== | ===Conclusion=== | ||
The testing framework in the assignment_team_spec.rb used integration tests to test the methods in the controller. The mock instances are created at the beginning and the method logic is tested | The testing framework in the assignment_team_spec.rb used integration tests to test the methods in the controller. The mock instances are created at the beginning and the method logic is tested in each 'describe'. In addition, we used the Byebug gem to debug our test code. | ||
The key to building successful tests is to understand the logic in the method and understand the input and output value for the method. |
Latest revision as of 14:53, 31 March 2019
The goal of this project was to add testing for the PopupController to raise statement coverage above 90%. See the Test Outline section for specifics of our work.
Project Introduction
The PopupController is responsible for preparing data that will be displayed in popup views. To render the data, which mostly concerns assignments, the controller makes many accesses to database tables such as Response, ResponseMap, Question, Questionnaire, Answer, and Participant. Before our project, there were only two tests implemented that together only achieved a statement coverage of 7%. Our changes have brought the statement coverage to 96%.
Team
Zhewei Hu, zhu6 (mentor)
- Yuhan Chen, ychen239
- Hao Lu, hlu6
- Drew Marshburn, rdmarshb
Files Involved
popup_controller.rb
popup_controller_spec.rb
Running Tests
What we need to do is to set up the environment and complete the 'popup_controller_spec.rb' to finish the integration tests for popup controller. This rspec test file can be run by calling the following code:
rspec spec/controllers/popup_controller_spec.rb
What needs to be done
1.Write RSpec integration tests to make the statement coverage above 90%.
2.Cover as many edge cases as you can.
3.Achieve as high branch coverage as you can. Teaching staff will use the mutant-rspec gem to measure test thoroughness and fault-finding capability of tests.
Test Plan
In total, we wrote tests to cover all 10 methods in the popup controller. We mocked many different objects involved in the controller.
Popup Controller Methods
The code of the controller can be found here. The methods are:
- action_allowed?
- author_feedback_popup
- team_users_popup
- participants_popup
- tone_analysis_chart_popup
- view_review_scores_popup
- build_tone_analysis_report
- build_tone_analysis_heatmap
- reviewer_details_popup
- self_review_popup
Mock Models
Based on the controller, we mocked models to test different conditions. Models have complex and interdependent relationships, but the Expertiza project already includes a factory to build many of the models. This factory can be seen here. Additional database information can be accessed here. As you can see from our setup below, most of the objects we created relied on the factory with the exception of the final_versions array, which is not used in enough tests to warrant its own factory statement. Other objects are just built with additional/overwritten attributes, such as the student object.
let(:assignment_team) { build(:assignment_team, id: 1, name: "team1", assignment: assignment) } let(:team) {build(:team)} let(:team_user) {build(:team_user)} let(:student) { build(:student, id: 1, name: "student") } let(:student2) { build(:student, id: 2, name: "student2") } let(:admin) { build(:admin) } let(:instructor) { build(:instructor) } let(:ta) { build(:teaching_assistant) } let(:participant) { build(:participant, id: 1, user_id: 1, user: student, assignment: assignment) } let(:participant2) { build(:participant, id: 2, user: student2, assignment: assignment) } let(:response) { build(:response, id: 1) } let(:questionnaire) { build(:questionnaire, id: 1, max_question_score: 15)} let(:question) { build(:question, id: 1, questionnaire_id: questionnaire.id)} let(:answer) { build(:answer, id: 1, question_id: question.id, response_id: response.id, answer: 10) } let(:assignment) { build(:assignment, id: 1) } let(:response_map) { build(:review_response_map, id: 1, reviewee_id: assignment_team.id, reviewer_id: participant2.id, response: [response], assignment: assignment) } let(:final_versions) {{ review_round_one: {questionnaire_id: 1, response_ids: [1]}, review_round_two: {questionnaire_id: 2, response_ids: [2]}, review_round_three: {questionnaire_id: 3, response_ids: [3], } }} test_url = "http://peerlogic.csc.ncsu.edu/reviewsentiment/viz/478-5hf542" mocked_comments_one = OpenStruct.new(comments: "test comment")
We made one change to the factory.rb file to build an instance of Team. We assume that the Team class may be used in other tests globally, so this should be added to the factory file and thus can be built more easily in future tests. Our addition to the factory.rb file is:
factory :team, class: Team do id 1 parent_id 1 end
Test Frame
Since it's integration test, we need to test basic logic and return value in both methods in the controller and related methods in the controller. However, some of the methods have been tested in other rspec, all we need to do is to test the methods that haven't been tested. For 'action_allowed?', 'author_feedback_popup', 'team_users_popup', 'participants_popup', 'reviewer_details_popup', 'self_review_popup' methods, we test it separately. With 'tone_analysis_chart_popup', 'view_review_scores_popup', 'build_tone_analysis_report', 'build_tone_analysis_heatmap', we test them together since they both need to get each assignment'answer. Also 'tone_analysis_chart_popup' and 'view_review_scores_popup' all get 'build_tone_analysis_report' and 'build_tone_analysis_heatmap' in their method.
Test Outline
The following section shows the Rspec outline of the tests we created. The full test code can be found here
PopupController
Check action permission with four different roles.
#action_allowed? when the role current user is student does not allow certain action when the role current user is ta allows certain action when the role name of current user is super admin or admin allows certain action when the role current user is super instructor allows certain action
Get feedback when feedback exists.
#author_feedback_popup when response_id exists get the result
Get response stats when the response map exists, otherwise only find the team and users.
#team_users_popup when a response map exists calculates response stats for one response when a response map does not exist finds team and users
Calculate scores depending on the existence of the response. If a review questionnaire is present, calculate scores with a max.
#participants_popup called with no response does not calculate scores called with a response assignment has a review questionnaire calculates the scores with a max assignment has no review questionnaire calculates the scores without a max
All tone analysis tests are run together. Both popup_* methods set instance variables before calling a build_* method. build_* methods are responsible for actually creating tone analysis tests and returning JSON information/graphics.
tone analysis tests #tone_analysis_chart_popup review tone analysis is calculated prepares tone analysis report for building #view_review_scores_popup review tone analysis is calculated prepares tone analysis report for building #build_tone_analysis_report answer is provided build tone analysis report answer is not provided build tone analysis report #build_tone_analysis_heatmap sentiment is empty build tone analysis heatmap
Test showing details about the reviewer.
#reviewer_details_popup it will show the reviewer details it will show the reviewer details
Get reviews done by self.
#self_review_popup when response_id exists get the result
Results
The total coverage of the test is 96.41%, meeting our coverage requirement.
Related Links
A video of all tests running can be seen here.
The main repository can be found here
The forked git repository for this project can be found here
Conclusion
The testing framework in the assignment_team_spec.rb used integration tests to test the methods in the controller. The mock instances are created at the beginning and the method logic is tested in each 'describe'. In addition, we used the Byebug gem to debug our test code. The key to building successful tests is to understand the logic in the method and understand the input and output value for the method.