简体   繁体   English

使用unittest的Python中许多测试用例的正确结构

[英]Proper structure for many test cases in Python with unittest

I am looking into the unittest package, and I'm not sure of the proper way to structure my test cases when writing a lot of them for the same method. 我正在研究unittest包,并且我不确定在为同一方法编写大量测试用例时构建测试用例的正确方法。 Say I have a fact function which calculates the factorial of a number; 假设我有一个计算数字阶乘的fact函数; would this testing file be OK? 这个测试文件可以吗?

import unittest

class functions_tester(unittest.TestCase):
    def test_fact_1(self):
        self.assertEqual(1, fact(1))
    def test_fact_2(self):
        self.assertEqual(2, fact(2))
    def test_fact_3(self):
        self.assertEqual(6, fact(3))
    def test_fact_4(self):
        self.assertEqual(24, fact(4))
    def test_fact_5(self):
        self.assertFalse(1==fact(5))
    def test_fact_6(self):
        self.assertRaises(RuntimeError, fact, -1)
        #fact(-1)

if __name__ == "__main__":
    unittest.main()

It seems sloppy to have so many test methods for one method. 对于一种方法,有这么多测试方法似乎很草率。 I'd like to just have one testing method and put a ton of basic test cases (ie 4! ==24, 3!==6, 5!==120, and so on), but unittest doesn't let you do that. 我想只有一个测试方法,并放置了大量的基本测试用例(即4!== 24,3!== 6,5!== 120,依此类推),但是unittest不允许你去做。

What is the best way to structure a testing file in this scenario? 在这种情况下构建测试文件的最佳方法是什么?

Thanks in advance for the help. 先谢谢您的帮助。

You can put the asserts in a loop: 您可以将断言置于循环中:

def test_fact(self):
    tests = [(1,1), (2,2), (3,6), (4,24), (5,120)]
    for n,f in tests:
        self.assertEqual(fact(n), f)

I'd say your ways of doing it is generally fine (but read on). 我会说你做这件事的方式一般都很好(但请继续阅读)。

You could, as interjay suggested, do a loop (and, incidentally, it only counts as one test because the unittest module counts the number of functions, not the number of asserts). 正如interjay建议的那样,你可以做一个循环(顺便说一下,它只算作一个测试,因为unittest模块计算函数的数量,而不是断言的数量)。 But I assume you won't exhaustively try to test every number, or even all numbers within a very large interval. 但我认为你不会穷尽地尝试在很长的时间间隔内测试每个数字,甚至是所有数字。 So looping won't save you much, and, especially in testing, you should aim at being explicit. 所以循环不会为你节省太多,特别是在测试中,你应该以明确为目标。

Having said that, you should test for a small number of subsequent numbers (say, 1 through 5), and then try to get a feel for where possible corner cases and failures points are. 话虽如此,您应该测试少量后续数字(例如,1到5),然后尝试了解角落情况和失败点的可能性。 Say, test for 10, 100, 1000 (that is, change order of magnitude), negative numbers, zero etc. 比如说,测试10,100,1000(即变化的数量级),负数,零等。

BTW, watch out for your two last tests. 顺便说一句,请注意你最近的两次测试。 The first of them doesn't mean much. 第一个并不意味着什么。 fact(5) is different than a LOT of numbers (infinite numbers, actually). 事实(5)不同于很多数字(实际上是无限数字)。 Test for the correct case, testing for the incorrect ones isn't productive. 测试正确的情况,测试不正确的情况是不高效的。

def test_fact_5(self):
    self.assertFalse(1==fact(5))

The second one is badly named: "test_fact_6" makes me think you're testing fact(6). 第二个名字很糟糕:“test_fact_6”让我觉得你在测试事实(6)。 You should name it as something like "test_fact_minus_one", or at least "test_fact_negative_number". 您应该将其命名为“test_fact_minus_one”,或至少“test_fact_negative_number”。

def test_fact_6(self):
    self.assertRaises(RuntimeError, fact, -1)

Test naming is very important, both when you're debugging errors and when you refer back to the tests as documentation. 测试命名非常重要,无论是在调试错误时还是作为文档返回测试时。

You've said you're looking into unittest , but consider using nose tests instead - they allow you to generate independant test cases programmatically. 你说你正在寻找进入unittest ,但考虑使用nose试验,而不是-它们允许你以编程方式生成独立的测试用例。

How to generate dynamic (parametrized) unit tests in python? 如何在python中生成动态(参数化)单元测试? (answer) (回答)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM