CSC/ECE 517 Spring 2013/OSS E605B

From Expertiza_Wiki
Jump to navigation Jump to search

Testing - questionnaire

Project Description

Project Github Repository

Expertiza Wiki

QuestionnaireController Functional Tests

The majority of the tests implemented in this project are functional tests of the questionnaire controller. The test cases were written using the ActionController::TestCase framework provided by Rails.

Modifications to Existing QuestionnaireController Test

There were a few tests already written for the Questionnaire controller, but they were not passing initially. We had to modify several things in the test and questionnaire fixture in order to get things up and running. The setup method contained login code that was outdated, and thus each test would result in a redirect due to the invalid login credential. So we looked through other more up to date functional test files and found the correct way to login as a particular user. We also put this code in a helper method so we can call it more easily in different tests if we so choose (more on this in the "Helper Methods" section).

In addition, we added new fixtures to help with our testing. Through debugging the test error messages, we saw that an additional required column called "section" has been added to the "Questionnaire" model, which was contributing to the failures. We added the additional column accordingly in our new fixures.

Helper Methods

There are two methods that assist in setting up and running the tests:

  • The setup method
  • The login_user method

The setup method assigns three special instance variables that are associated with the ActionController::TestCase (@controller, @request, and @response). In addition to setting these, the @Questionnaire variable is assigned to id of the :questionnaire5 fixture. This is the default questionnaire fixture that is used in a lot of the test cases. You will also notice that the fixture :admin is being logged in as the default user. This is done so that you don't have explicitly log into a user account for each test case. The only time you would need to call the method to log in for a particular test case is if you needed to test something specifically in another user type's account (for example a student account as is done in test_create_questionnaire_with_student.

 def setup
   @controller = QuestionnaireController.new
   @request = ActionController::TestRequest.new
   @response = ActionController::TestResponse.new
   @Questionnaire = questionnaires(:questionnaire5).id
   login_user(:admin)
 end

The login_user method was created to "DRY out" the code associated with logging a user in. The method signature is:

  def login_user(userType)

If you pass a symbol of the user type you would like to use for a test, it will log in as that user type for the particular test. The parameter name is userType and assumes that there is a fixture with the name of the user type. There seem to be sufficient fixtures for all of the different user types currently, but additional fixtures may need to be created in the future if new user types are added to the system.

Test Coverage

There are three main types of tests that we created.

  • Happy path tests of the controller's public methods. There is a test for every method. (ex: test_new)
  • Sad path tests that passed invalid parameters. (ex: test_edit_questionnaire_with_lower_max_score_than_min)
  • Sad path tests that tried to do things with insufficient access level. (ex: test_create_questionnaire_with_student)

We tried to cover as many types of useful cases as possible according to the project requirements. We used assertions that checked counts after create and delete, as well as asserted redirects. We also tested against invalid inputs that could cause errors. All of the tests are self-explanatory based on their method names, and there really is no need to further provide explanations here.

We also attempted to test the private methods of the controller as well at the beginning of the project. However, we couldn't find a way to test many of them due to the fact that they reference the params[] hash in the methods, and we can't isolate the testing of those methods without calling some controller action. Since these private methods are only used by the public controller action methods, we did the next best thing by creating tests for the action methods that would use these private methods to test them indirectly.

How to Run Controller Test

All of the QuestionnaireController tests are in the questionnaire_controller_test.rb file and can be run as a standard functional test. In Rubymine, this can be done by right clicking the test file and selecting "Run <filename>". Individual tests inside each test file can also be run by right clicking on the test method name and selecting "Run <method_name>". If the command line is preferred, the following command can be used:

ruby -Itest test/functional/questionnaire_controller_test.rb

Questionnaire Subclass Unit Tests

The original assignment was to write unit tests for the Questionnaire subclasses:

  • author_feedback_questionnaire.rb
  • metareview_questionnaire.rb
  • review_questionnaire.rb
  • teammate_review_questionnaire.rb

As we reviewed the tests, it was found that most of the methods were trivial (ex: the method "symbol" only returns a hardcoded symbol). The only method that was found to be worth testing was the get_weighted_score method. Upon further review, however, we found that testing this method in each of the four subclasses violated the DRY principle. Therefore, we moved the test to the superclass (questionnaire.rb) to test the "get_weighted_score" method.

Modifications to Existing Questionnaire Subclass Tests

There was only one test in the existing unit test for AuthorFeedbackQuestionnaire for testing the "get_weighted_score" method. Even though the test could be run, we found that it was not making assertions as it should. The files for the other 3 questionnaire subclasses were created to complete the testing on them. As stated earlier, we then found that testing the "get_weighted_score" method was redundant, violating the DRY principle, so it was moved to the superclass (Questionnaire). The tests in the subclasses were deleted (since they were redundant) but the test files were kept for future testing of the subclass if/when needed.

Test Coverage

The method "compute_weighted_score" from the the base class was the only thing that needed to be tested (due to the above reason). Based on an average, it was asserted that the value was not nil and that the value was computed correctly.

How to Run Unit Tests

The "compute_weighted_score" test can be found in the Questionnaire Unit Test file. Same as directions for the functional test, this can be run in either Rubymine or the command line. In Rubymine, this can be done by right clicking the test file and selecting "Run <filename>". Individual tests inside each test file can also be run by right clicking on the test method name and selecting "Run <method_name>". If the command line is preferred, the following command can be used:

ruby -Itest test/unit/questionnaire_test.rb

VNC Server Information

IP: 152.46.16.122:2 Password: project517

General Information

Members

  • Jonathan Wills - jrwills2
  • Chun Sing Tsui - ctsui
  • Travis Folsom - twfolsom

Highlights of Project

  • Added unit test for questionnaire class
  • Added functional tests for questionnaire controller
  • 24 total tests
  • The test that uses the "delete" action in the controller was failing due to a potential bug in the questionnaire.rb model class (refer to Potential Bug section)

List of files changed

  • test/fixtures/assignment_questionnaires.yml
  • test/fixtures/question_types.yml
  • test/fixtures/questionnaires.yml
  • test/fixtures/questions.yml
  • test/functional/questionnaire_controller_test.rb
  • test/unit/questionnaire_test.rb
  • test/unit/author_feedback_questionnaire_test.rb
  • test/unit/metareview_questionnaire_test.rb
  • test/unit/review_questionnaire_test.rb
  • test/unit/teammate_review_questionnaire_test.rb

Potential Bug

The Questionnaire model class contains a has_many :assignment_questionnaire that should be has_many :assignment_questionnaires according to convention. Because of this, our "delete" action test fails since it doesn't match the convention. If it is indeed incorrect, then in the "compute_weighted_score" method, the self.assignemnt_questionnaire... call also needs to be changed to self.assignment_questionnaires.... This most likely needs to be refactored, but we did not want to do a refactor without testing its effects on the system thoroughly.