【问题标题】:TypeError while testing answer checker测试答案检查器时出现 TypeError
【发布时间】:2022-01-24 06:39:18
【问题描述】:

我正在为我的“答案检查器”编写一个测试,所以我做了一个测试问题,我想通过给出正确答案来测试结果检查器是否工作(所以测试应该通过)。

我遇到了返回的错误。我知道代码不是很好,但我是这个领域的新手。我想我在逻辑上误解了一些东西。有人可以帮忙吗? :)

错误是:

correct = QuestionMultipleChoice.correct_answer()
      TypeError: 'property' object is not callable

测试(我知道最后几行是错误的):

@when(u'I give an answer to a Multiple choice question')
def save_object(context):
    lab1 = Lab.objects.create(lab_name="testlab", pub_date=datetime.now(), lab_theory="test theory")
    question1 = QuestionMultipleChoice.objects.create(lab=lab1, question='This is a test question', option1='1', option2='2', option3='3', option4='4', answer=1)        

@then(u'I should get true if answer is correct')
def should_have_only_one_object(self):
    given = 1
    correct = QuestionMultipleChoice.correct_answer()
    QuestionMultipleChoice.check_answer(correct, given)
    assert 1 == Lab.objects.count()

模型.py

class QuestionMultipleChoice(models.Model):
    lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
    type = QuestionType.multiplechoice
    question = models.CharField(max_length=200,null=True)
    option1 = models.CharField(max_length=200,null=True)
    option2 = models.CharField(max_length=200,null=True)
    option3 = models.CharField(max_length=200,null=True)
    option4 = models.CharField(max_length=200,null=True)
    answer = models.IntegerField(max_length=200,null=True)
    
    def __str__(self):
        return self.question

    @property
    def html_name(self):
        return "q_mc_{}".format(self.pk)

    @property
    def correct_answer(self):
        correct_answer_number = int(self.answer)
        correct_answer = getattr(self, "option{}".format(correct_answer_number))
        return correct_answer

    def check_answer(self, given):
        return self.correct_answer == given

更新:

我做了一些更改,现在代码如下所示:

def test_check_wrong_answer(self):
        given=2
        lab1= Lab.objects.create(lab_name="testlab", pub_date=datetime.now(), lab_theory="test theory")
        question1 = QuestionMultipleChoice.objects.create(lab=lab1, question='This is a test question', option1='1', option2='2', option3='3', option4='4', answer=1)
        answer = question1.correct_answer
        self.assertTrue(question1.check_answer(given))
        self.assertEqual(Lab.objects.count(), 1)

但是,测试仍然失败:

AssertionError: False is not true

【问题讨论】:

  • correct_answerproperty 类型为QuestionMultipleChoice 的对象,如果您想直接从类中访问correct_answer,您必须通过以下方式将correct_answer 定义为静态方法使用 @staticmethod 装饰器。
  • 查看 Messaoud Zahi 的评论,并且 - 在访问 QuestionMultipleChoice 的属性和方法之前创建一个对象。

标签: python django unit-testing django-models python-behave


【解决方案1】:

您只需删除correct_answer 后面的括号,因为它是属性,而不是方法。

试试:

@then(u'I should get true if answer is correct')
def should_have_only_one_object(self):
    given = 1
    correct = QuestionMultipleChoice().correct_answer
    QuestionMultipleChoice.check_answer(correct, given)
    assert 1 == Lab.objects.count()

更新

这是一个使用 django 的 TestCase 的简单实现。 See more in the docs

from django.tests import TestCase


class QuestionTestCase(TestCase):

    @classmethod
    def setUpTestData(cls):
        cls.lab = Lab.objects.create(lab_name="testlab", pub_date=datetime.now(), lab_theory="test theory")
        cls.question = QuestionMultipleChoice.objects.create(lab=lab1, question='This is a test question', option1='1', option2='2', option3='3', option4='4', answer=1)
        cls.answer = cls.question.correct_answer
    
    def test_check_answer(given=1):
        self.assertTrue(self.question.check_answer(self.answer, given))
    
    def test_lab_count():
        self.assertEqual(Lab.objects.count(), 1)

【讨论】:

  • 他还需要创建一个 QuestionMultipleChoice 的对象,而不是直接从类访问。
  • 感谢大家的宝贵时间! Unfurtunatelly 我仍然有一些错误(同样)。我认为@Som-1 是对的,但是我怎样才能在这里创建一个对象呢?我的意思是我知道如何,但我的测试中有一个方法,我已经创建了对象,那么我如何从这里访问它?
  • 将其存储为一些常见对象的属性。对于单元测试,它通常是一个 TestCase 类,它为测试创建和存储通用数据,并为此提供设置和拆卸方法。在您的情况下,它可能正在测试包含您的测试步骤的客户端、上下文或其他类。
  • 非常感谢您的帮助,谢谢大家:)
  • 嗨,丹,我正在检查测试结果。执行正确,但测试失败:“AssertionError: False is not true”。
最近更新 更多