Skip to content

Commit

Permalink
Test: Increase backend code coverage (#697)
Browse files Browse the repository at this point in the history
* test: Add unit tests for the Score class

* test: Add unit tests for Info class

* test: Add script for testing backend coverage

* ci: Update coverage report command in CI workflow and show missing lines

* test: Add unit tests for Playlist class

* test: Add test cases for ExperimentForm, ExportForm, and TemplateForm

* test: Add unit tests for Form class in experiment module

* refactor: Rename unit tests for Info, Playlist, and Score classes

* test: Add more test scenarios for form and its questions

* test: Add test for HTML action initialization
  • Loading branch information
drikusroor authored Jan 5, 2024
1 parent 98d8786 commit 7933da9
Show file tree
Hide file tree
Showing 8 changed files with 535 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: Run Backend Tests
run: sudo docker-compose --env-file .env-github-actions run server bash -c "coverage run manage.py test"
- name: Generate Backend Coverage Report (Inline)
run: sudo docker-compose --env-file .env-github-actions run server bash -c "coverage report"
run: sudo docker-compose --env-file .env-github-actions run server bash -c "coverage report --show-missing"

# Generate coverage badge (only for main and develop branches)
- name: Generate Backend Coverage Report (XML) and Badge
Expand Down
331 changes: 331 additions & 0 deletions backend/experiment/tests/test_actions_form.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
from django.test import TestCase

from experiment.actions.form import BooleanQuestion, ChoiceQuestion, Form, NumberQuestion, TextQuestion, DropdownQuestion, AutoCompleteQuestion, RadiosQuestion, ButtonArrayQuestion, RangeQuestion, LikertQuestion, LikertQuestionIcon

class FormTest(TestCase):
def setUp(self):
self.questions = [NumberQuestion(key='test_key', min_value=1, max_value=10)]
self.form = Form(form=self.questions, submit_label='Submit', skip_label='Skip', is_skippable=True)

def test_initialization(self):
self.assertEqual(len(self.form.form), 1)
self.assertEqual(self.form.submit_label, 'Submit')
self.assertEqual(self.form.skip_label, 'Skip')
self.assertTrue(self.form.is_skippable)

def test_action_method(self):
action_result = self.form.action()
self.assertIn('form', action_result)
self.assertEqual(len(action_result['form']), 1)
self.assertIn('submit_label', action_result)
self.assertIn('skip_label', action_result)
self.assertIn('is_skippable', action_result)

class NumberQuestionTest(TestCase):
def setUp(self):
self.number_question = NumberQuestion(
key='test_key',
min_value=1,
max_value=10,
input_type='number'
)

def test_initialization(self):
self.assertEqual(self.number_question.key, 'test_key')
self.assertEqual(self.number_question.min_value, 1)
self.assertEqual(self.number_question.max_value, 10)
self.assertEqual(self.number_question.input_type, 'number')

def test_action_method(self):
action_result = self.number_question.action()
self.assertIn('key', action_result)
self.assertIn('min_value', action_result)
self.assertIn('max_value', action_result)
self.assertEqual(action_result['min_value'], 1)
self.assertEqual(action_result['max_value'], 10)

class TextQuestionTest(TestCase):
def setUp(self):
self.text_question = TextQuestion(
key='test_key',
max_length=100,
input_type='text'
)

def test_initialization(self):
self.assertEqual(self.text_question.key, 'test_key')
self.assertEqual(self.text_question.max_length, 100)
self.assertEqual(self.text_question.input_type, 'text')

def test_action_method(self):
action_result = self.text_question.action()
self.assertIn('key', action_result)
self.assertIn('max_length', action_result)
self.assertEqual(action_result['max_length'], 100)

class BooleanQuestionTest(TestCase):
def setUp(self):
self.boolean_question = BooleanQuestion(
key='test_key',
choices={
'no': 'No',
'yes': 'Yes'
}
)

def test_initialization(self):
self.assertEqual(self.boolean_question.key, 'test_key')
self.assertEqual(self.boolean_question.choices, {'no': 'No', 'yes': 'Yes'})

def test_action_method(self):
action_result = self.boolean_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {'no': 'No', 'yes': 'Yes'})

class ChoiceQuestionTest(TestCase):
def setUp(self):
self.choice_question = ChoiceQuestion(
key='test_key',
choices={
'no': 'No',
'yes': 'Yes'
},
min_values=1
)

def test_initialization(self):
self.assertEqual(self.choice_question.key, 'test_key')
self.assertEqual(self.choice_question.choices, {'no': 'No', 'yes': 'Yes'})
self.assertEqual(self.choice_question.min_values, 1)

def test_action_method(self):
action_result = self.choice_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {'no': 'No', 'yes': 'Yes'})
self.assertIn('min_values', action_result)
self.assertEqual(action_result['min_values'], 1)

class DropdownQuestionTest(TestCase):
def setUp(self):
self.dropdown_question = DropdownQuestion(
key='test_key',
choices={
'no': 'No',
'yes': 'Yes'
},
)

def test_initialization(self):
self.assertEqual(self.dropdown_question.key, 'test_key')
self.assertEqual(self.dropdown_question.choices, {'no': 'No', 'yes': 'Yes'})

def test_action_method(self):
action_result = self.dropdown_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {'no': 'No', 'yes': 'Yes'})

class AutoCompleteQuestionTest(TestCase):
def setUp(self):
self.autocomplete_question = AutoCompleteQuestion(
key='test_key',
choices={
'no': 'No',
'yes': 'Yes'
},
)

def test_initialization(self):
self.assertEqual(self.autocomplete_question.key, 'test_key')
self.assertEqual(self.autocomplete_question.choices, {'no': 'No', 'yes': 'Yes'})

def test_action_method(self):
action_result = self.autocomplete_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {'no': 'No', 'yes': 'Yes'})


class RadiosQuestionTest(TestCase):
def setUp(self):
self.radios_question = RadiosQuestion(
key='test_key',
choices={
'no': 'No',
'yes': 'Yes'
},
)

def test_initialization(self):
self.assertEqual(self.radios_question.key, 'test_key')
self.assertEqual(self.radios_question.choices, {'no': 'No', 'yes': 'Yes'})

def test_action_method(self):
action_result = self.radios_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {'no': 'No', 'yes': 'Yes'})


class ButtonArrayQuestionTest(TestCase):
def setUp(self):
self.buttonarray_question = ButtonArrayQuestion(
key='test_key',
choices={
'no': 'No',
'yes': 'Yes'
},
)

def test_initialization(self):
self.assertEqual(self.buttonarray_question.key, 'test_key')
self.assertEqual(self.buttonarray_question.choices, {'no': 'No', 'yes': 'Yes'})

def test_action_method(self):
action_result = self.buttonarray_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {'no': 'No', 'yes': 'Yes'})

class RangeQuestionTest(TestCase):
def setUp(self):
self.range_question = RangeQuestion(
key='test_key',
min_value=1,
max_value=10,
)

def test_initialization(self):
self.assertEqual(self.range_question.key, 'test_key')
self.assertEqual(self.range_question.min_value, 1)
self.assertEqual(self.range_question.max_value, 10)

def test_action_method(self):
action_result = self.range_question.action()
self.assertIn('key', action_result)
self.assertIn('min_value', action_result)
self.assertIn('max_value', action_result)
self.assertEqual(action_result['min_value'], 1)
self.assertEqual(action_result['max_value'], 10)

class LikertQuestionCustomChoicesTest(TestCase):
def setUp(self):
self.likert_question = LikertQuestion(
key='test_key',
choices={
'no': 'No',
'yes': 'Yes'
},
)

def test_initialization(self):
self.assertEqual(self.likert_question.key, 'test_key')
self.assertEqual(self.likert_question.choices, {'no': 'No', 'yes': 'Yes'})

def test_action_method(self):
action_result = self.likert_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {'no': 'No', 'yes': 'Yes'})

class LikertQuestionSevenScaleStepsTest(TestCase):
def setUp(self):
self.likert_question = LikertQuestion(
key='test_key',
scale_steps=7,
)

def test_initialization(self):
self.assertEqual(self.likert_question.key, 'test_key')
self.assertEqual(self.likert_question.choices, {
1: "Completely Disagree",
2: "Strongly Disagree",
3: "Disagree",
4: "Neither Agree nor Disagree",
5: "Agree",
6: "Strongly Agree",
7: "Completely Agree",
})

def test_action_method(self):
action_result = self.likert_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {
1: "Completely Disagree",
2: "Strongly Disagree",
3: "Disagree",
4: "Neither Agree nor Disagree",
5: "Agree",
6: "Strongly Agree",
7: "Completely Agree",
})

class LikertQuestionFiveScaleStepsTest(TestCase):
def setUp(self):
self.likert_question = LikertQuestion(
key='test_key',
scale_steps=5,
)

def test_initialization(self):
self.assertEqual(self.likert_question.key, 'test_key')
self.assertEqual(self.likert_question.choices, {
1: "Strongly Disagree",
2: "Disagree",
3: "Neither Agree nor Disagree",
4: "Agree",
5: "Strongly Agree",
})

def test_action_method(self):
action_result = self.likert_question.action()
self.assertIn('key', action_result)
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {
1: "Strongly Disagree",
2: "Disagree",
3: "Neither Agree nor Disagree",
4: "Agree",
5: "Strongly Agree",
})


class LikertQuestionIconTest(TestCase):
def setUp(self):
self.likert_question_icon = LikertQuestionIcon(
key='test_key',
scale_steps=7,
likert_view="ICON_RANGE",
)

def test_initialization(self):
self.assertEqual(self.likert_question_icon.key, 'test_key')
self.assertEqual(self.likert_question_icon.view, 'ICON_RANGE')
self.assertEqual(self.likert_question_icon.choices, {
1: 'fa-face-grin-hearts',
2: 'fa-face-grin',
3: 'fa-face-smile',
4: 'fa-face-meh',
5: 'fa-face-frown',
6: 'fa-face-frown-open',
7: 'fa-face-angry',
})

def test_action_method(self):
action_result = self.likert_question_icon.action()
self.assertIn('key', action_result)
self.assertIn('view', action_result)
self.assertEqual(action_result['view'], 'ICON_RANGE')
self.assertIn('choices', action_result)
self.assertEqual(action_result['choices'], {
1: 'fa-face-grin-hearts',
2: 'fa-face-grin',
3: 'fa-face-smile',
4: 'fa-face-meh',
5: 'fa-face-frown',
6: 'fa-face-frown-open',
7: 'fa-face-angry',
})
10 changes: 10 additions & 0 deletions backend/experiment/tests/test_actions_html.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.test import TestCase

from experiment.actions.html import HTML

class HTMLTest(TestCase):

def test_initialization(self):
test_html_body = "<div>Test HTML Content</div>"
html_action = HTML(body=test_html_body)
self.assertEqual(html_action.body, test_html_body)
34 changes: 34 additions & 0 deletions backend/experiment/tests/test_actions_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import unittest

from experiment.actions.info import Info

class TestInfo(unittest.TestCase):

def test_initialization_all_parameters(self):
info = Info(
body="<p>Test Body</p>",
heading="Test Heading",
button_label="Test Label",
button_link="http://example.com"
)
self.assertEqual(info.body, "<p>Test Body</p>")
self.assertEqual(info.heading, "Test Heading")
self.assertEqual(info.button_label, "Test Label")
self.assertEqual(info.button_link, "http://example.com")

def test_initialization_only_body(self):
info = Info(body="<p>Only Body</p>")
self.assertEqual(info.body, "<p>Only Body</p>")
self.assertEqual(info.heading, "")
self.assertIsNone(info.button_label)
self.assertIsNone(info.button_link)

def test_initialization_default_values(self):
info = Info(body="<p>Body</p>", heading="Heading")
self.assertEqual(info.body, "<p>Body</p>")
self.assertEqual(info.heading, "Heading")
self.assertIsNone(info.button_label)
self.assertIsNone(info.button_link)

if __name__ == '__main__':
unittest.main()
Loading

0 comments on commit 7933da9

Please sign in to comment.