我应该在每次测试中都声明相同的值吗?

时间:2019-01-15 09:35:34

标签: python unit-testing testing python-unittest

我有一个简单的类,要测试的公共build方法。目前,我断言它在每次测试中返回的所有值。这是一个好习惯还是我应该为静态值编写一个测试,而在其他测试中仅检查根据输入而变化的值?

实施

class FiltersAttachment:
    TYPE_OPTIONS = [
        {"text": "All types", "value": "all"},
        {"text": ":link: Webpages", "value": "web_pages"}
    ]

    STATUS_OPTIONS = [
        {"text": "Available / Unavailable", "value": "all"},
        {"text": ":white_circle: Available", "value": "available"},
        {"text": ":red_circle: Unavailable", "value": "unavailable"}
    ]

    @classmethod
    def _filter_options(cls, options, selected):
        return list(filter(lambda t: t['value'] == selected, options))

    @classmethod
    def build(cls, check_type='', status=''):
        return {
            'fallback': 'Filters',
            'callback_id': 'resource_filters',
            'color': '#d2dde1',
            'mrkdwn_in': ['text'],
            'actions': [
                {
                    'name': 'resource_type',
                    'text': 'Type',
                    'type': 'select',
                    'options': cls.TYPE_OPTIONS,
                    'selected_options': cls._filter_options(
                        cls.TYPE_OPTIONS, check_type)
                },
                {

                    'name': 'resource_status',
                    'text': 'Status',
                    'type': 'select',
                    'options': cls.STATUS_OPTIONS,
                    'selected_options': cls._filter_options(
                        cls.STATUS_OPTIONS, status)
                }
            ]
        }

测试

class TestFiltersAttachment(TestCase):
    def assert_attachment(self, attachment):
        self.assertEqual(attachment['fallback'], 'Filters')
        self.assertEqual(attachment['callback_id'], 'resource_filters')
        self.assertEqual(attachment['color'], '#d2dde1')
        self.assertEqual(attachment['mrkdwn_in'], ['text'])

        type_action = attachment['actions'][0]
        self.assertEqual(type_action['name'], 'resource_type')
        self.assertEqual(type_action['text'], 'Type')
        self.assertEqual(type_action['type'], 'select')
        self.assertEqual(type_action['options'][0]['text'], 'All types')
        self.assertEqual(type_action['options'][0]['value'], 'all')
        self.assertEqual(type_action['options'][1]['text'], ':link: Webpages')
        self.assertEqual(type_action['options'][1]['value'], 'web_pages')

        status_action = attachment['actions'][1]
        self.assertEqual(status_action['name'], 'resource_status')
        self.assertEqual(status_action['text'], 'Status')
        self.assertEqual(status_action['type'], 'select')
        self.assertEqual(status_action['options'][0]['text'], 'Available / Unavailable')
        self.assertEqual(status_action['options'][0]['value'], 'all')
        self.assertEqual(status_action['options'][1]['text'], ':white_circle: Available')
        self.assertEqual(status_action['options'][1]['value'], 'available')
        self.assertEqual(status_action['options'][2]['text'], ':red_circle: Unavailable')
        self.assertEqual(status_action['options'][2]['value'], 'unavailable')

    def test_all_type_selected(self):
        attachment = FiltersAttachment.build(check_type='all')
        self.assert_attachment(attachment)

        selected_type = attachment['actions'][0]['selected_options'][0]
        self.assertEqual(selected_type['text'], 'All types')
        self.assertEqual(selected_type['value'], 'all')

    def test_all_status_selected(self):
        attachment = FiltersAttachment.build(status='all')
        self.assert_attachment(attachment)

        selected_status = attachment['actions'][1]['selected_options'][0]
        self.assertEqual(selected_status['text'], 'Available / Unavailable')
        self.assertEqual(selected_status['value'], 'all')
        ...

1 个答案:

答案 0 :(得分:1)

测试套件质量的标准之一是,如果测试失败以识别问题,则测试套件对您的支持程度如何。理想情况下,您应该能够通过查看哪些测试失败和哪些没有失败来单独识别问题。您不需要使用调试器来找出实际出了什么问题。

编写测试的方式不会为您提供最佳的支持。您已经在一个测试函数中包装了许多断言。因此,测试功能将由于多种原因而失败,并且当您看到其中一个功能失败时,您将必须进行详细的分析或使用调试来找出失败的原因。当使测试多余地检查方面时(如您在问题中所问的那样),您使它们变得更加具体,这使问题变得更糟。

因此,每个测试应检查一个特定方面,以便测试失败可以提供最具体的信息。这是通过结合以下两个原则来实现的:

  • 每次测试都应验证一个特定方面。
  • 同一方面不应有多余的测试。

借助所谓的参数化测试,可以方便地将每个断言转换为自己的测试。在这个问题上可以找到一些关于Python的提示:How do you generate dynamic (parameterized) unit tests in python?