CSC/ECE 517 Spring 2019 - Project E1921. Write tests for popup controller.rb: Difference between revisions
Line 79: | Line 79: | ||
test_url = "http://peerlogic.csc.ncsu.edu/reviewsentiment/viz/478-5hf542" | test_url = "http://peerlogic.csc.ncsu.edu/reviewsentiment/viz/478-5hf542" | ||
mocked_comments_one = OpenStruct.new(comments: "test comment") | mocked_comments_one = OpenStruct.new(comments: "test comment") | ||
</pre> | |||
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: | |||
<pre> | |||
factory :team, class: Team do | |||
id 1 | |||
parent_id 1 | |||
end | |||
</pre> | </pre> | ||
Revision as of 13:27, 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 sections show the Rspec outline of the tests we created. The whole test code can be found in here
PopupController
Use four different roles to go into the method.
#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
Ger feedback when feedback exists.
#author_feedback_popup when response_id exists
Get response when the response map exists.
#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
Show different score when the reponse exists or not.
#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
Test all tone analysis related test together.
tone analysis tests #tone_analysis_chart_popup review tone analysis is calculated prepares tone analysis report for building #build_tone_analysis_report upon selecting summery, the tone analysis for review comments is calculated and applied to the page builds a tone analysis report and returns the heat map URLs #view_review_scores_popup prepares tone analysis report for building #build_tone_analysis_report when answer not exists return answer is none when answer exists return answer #build_tone_analysis_heatmap test some constant value
Test the review details.
#reviewer_details_popup it will show the reviewer details it will show the reviewer details
Get sef review.
#self_review_popup when response_id exists get the result
Results
The total coverage of the test is 96.41% which meets the requirment.
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 the each 'require'. For 'context', it gives the conditions for each test and for 'it'. For it, it excutes the code. For 'get', it goes through the whole method. Besides, we use gem 'byebug' to debug our test code. In building the test framework, the key is to understand the logic in the method and understand the input and output value for the method.