Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 单元测试非常简单的函数_Python_Unit Testing - Fatal编程技术网

Python 单元测试非常简单的函数

Python 单元测试非常简单的函数,python,unit-testing,Python,Unit Testing,假设我有一个简单的函数形式: def square(x): return x**2 如果我编写一个单元测试来测试正确性,那么这样做是否被认为是不好的做法: def test_square(self): for _ in range(50): rand_num = random.uniform(-10,10) self.assertAlmostEqual(square(rand_num), rand_num**2, msg=

假设我有一个简单的函数形式:

def square(x):
    return x**2
如果我编写一个单元测试来测试正确性,那么这样做是否被认为是不好的做法:

def test_square(self):
        for _ in range(50):
            rand_num = random.uniform(-10,10)
            self.assertAlmostEqual(square(rand_num), rand_num**2, msg= "Failed for input: {}".format(rand_num))
从某种意义上说,我不是在编写手动用例,而是在单元测试中重写函数?为什么或者为什么这不被视为良好实践


我假设还有其他测试检查无效的输入和内容;我这样问是为了测试函数的正确性。随机输入几乎从来都不是你想要的。如果您的测试有时成功,但由于测试生成的随机输入不同而在其他测试上失败,这将不会有很大帮助

您只需测试最小值即可确保结果正确。如果您有bug或回归,您可以根据需要添加额外的测试

这就足够了

def test():
    assert square(3) == 9
请注意,测试不依赖于任何特定的实现细节(即,它只包括计算的
9
,而不是
3**2
)。通常,您希望您的测试具有尽可能少的依赖性和复杂性。一般来说,您试图一次测试一件事情,较少的依赖性意味着您实际测试的是您想要的事情,而不是与某些依赖性的交互

如果您注意到一个带有负数的bug,那么您可以添加一个额外的测试

def test():
    assert square(3) == 9
    assert square(-3) == 9
通常,人们要么在开发完功能后添加单元测试,要么在一开始就尝试创建整个单元测试功能


最好的方法通常是一次测试一个功能,一次添加一个功能,并一起开发测试和功能。

通过将代码逐字复制到测试中,实际上并不检查任何假设。这是一个重言式的说法。将单元测试分为
测试输入
函数输出
预期输出
您正在测试您对函数应如何与实际实现协同工作的假设


事实总是如此,因为即使引入了回归,您的测试套装也不会报告回归。您正在尝试使用
属性库测试编写测试。这是测试算法的有效方法
Haskell.quickcheck
是第一个实现

它除了生成随机数(在指定的属性空间中)之外,还减少了设置,以便轻松调试失败的测试


你很幸运:Python有一个

是什么使得单元测试太复杂而不够复杂,讽刺的是,这并不是一个简单的区别。感谢你的输入,我想我的问题不是一般的单元测试有多复杂,而是关于逐字复制函数代码以测试正确性是否可以,我个人的单元测试标准基本上分为“正确性测试”、“负面测试”、“测试底层系统故障”、“证明假设”、“错误路径”等。对我来说,每个单元测试都被分解为一个功能和该功能的一个方面。太多的复杂性来自重叠。啊,有趣。我个人认为这不是一种有效的测试方法。其中一个中的任何逻辑假设都将在另一个中进行。我将单元测试视为
输入
预期输出
函数输出
@7VoltCrayon,你的代码是
x**2
,你在断言平方(rand_num)=
x**2
,我想你是想写平方(rand_num)=
rand_num**2
。这只是断言测试中的
x**2
等于代码中的
x**2
。这只能在解释器损坏的情况下失败。这一点很好,但是如果有人意外地更改了平方函数以返回x**3怎么办。在这种情况下,这些测试可能有用吗?一个细微的区别是,我正在测试函数(x)=ExpectedFunction(x),其中ExpectedFunction是已知的期望输出。如果您硬编码了预期结果(因此对于输入=2,输出=4,3==9,…),那么如果您把代码弄乱了,您会看到它被破坏。“如果有人意外更改平方函数以返回x**3”-1,该怎么办。这就是为什么命名好函数以证明原始程序员的意图很重要的原因。2.我相信,如果你担心这个问题,一个额外的测试用例就足够了——根据投票率最高的答案,你几乎不需要大量生成的测试用例。谢谢你,我想我的问题不是关于输入的随机性,而是关于做什么:断言平方(3)=9,就像你提到的,或者类似于x=3,断言平方(x)=x**2。右边的表达式可能稍微复杂一点(比如说涉及到几次乘法和加法)。我是手动将输出的预期值放在RHS上,还是可以在那里重写expectedFunction,其中expectedFunction是已知的工作函数implementation@7VoltCrayon您通常希望单元测试具有尽可能少的依赖项,并且复杂性最低,因为您通常尝试测试一件事情,测试中涉及的变量越少,可能产生错误的来源就越少。在你的例子中,如果可能的话,我只会在测试中包含硬编码的计算输出,我不会尝试编码一个产生相同结果的实现。你的评论实际上就是我所问问题的答案,你能把它添加到你的答案中吗?我几乎总是从最简单的输入开始,在这种情况下,0和
assertEqual(平方(0),0)
。这样的情况往往被忽视。除此之外,如果可能的话,我同意预先计算的答案。请注意,
9
很可能被计算为
3*3
,因此实际上有一个测试。
assert function(input)  == function(input)