我已经阅读了有关何时使用assert以及何时使用异常的一些信息。 我不清楚的是为什么?
例如: 断言旨在仅用作检测编程错误(即bug)的手段。相反,异常可以指示其他类型的错误或“异常”条件;例如用户输入无效,文件丢失,堆满等等。
现在: “断言只是用来检测编程错误的手段,也就是错误” - 现在看来,所有断言都被例外所取代?例外会做同样的事情吗?
“断言仅用于调试目的,不应发生其触发条件。” - :现在好吧如果我使用异常然后execptions然后永远不会抛出异常
根据我的理解,异常可以做所有断言,除非它们不能被禁用。 禁用是否应该使用它们的唯一理由?
是否有理由使用它们而不是何时使用它们?
由于
答案 0 :(得分:3)
测试用例使用断言来确保您构建的内容在将来不会出现意外情况。例如,您可以断言以确保在错误输入时抛出异常。
在编程中多次更改一件事意味着您必须更改代码的其他部分。断言确保您更改的内容不会破坏您过去编写的代码。
例外是好的。它们是通过例外预期和处理的。例如,您有不正确的登录名和密码的例外。
您可以断言,如果登录名或密码不正确,则会引发预期的异常。
断言包含三个主要内容。您正在测试的内容(例如,函数名称,即sign_in
),内容(函数参数,即{'email': 'john@example.com', 'password': hashlib.md5('my_password')}
),以及出现的内容(assertTrue('user_name' in response, 'Expecting user_name to be in response!')
)。
例外是代码中的正常,合理的替代方案。断言是测试,以确保逻辑路径应该遵循它们。
根据python unittest framework,您可以断言抛出异常:
import random import unittest
class TestSequenceFunctions(unittest.TestCase):
def setUp(self):
self.seq = range(10)
def test_shuffle(self):
# make sure the shuffled sequence does not lose any elements
random.shuffle(self.seq)
self.seq.sort()
self.assertEqual(self.seq, range(10))
# should raise an exception for an immutable sequence
self.assertRaises(TypeError, random.shuffle, (1,2,3))
def test_choice(self):
element = random.choice(self.seq)
self.assertTrue(element in self.seq)
def test_sample(self):
with self.assertRaises(ValueError):
random.sample(self.seq, 20)
for element in random.sample(self.seq, 5):
self.assertTrue(element in self.seq)
if __name__ == '__main__':
unittest.main()
答案 1 :(得分:2)
断言被设计为有选择地关闭,默认情况下它们是关闭的。你应该在有条件的情况下使用它们,但是如果你真的需要的话可以检查。认为它们比例外情况更为特殊。
异常及其检查始终开启。虽然例外但它们仍然可以随时出现。
断言可以检查编码错误,一旦你编程没有bug,就不需要它们。由于您可能无法控制的值(例如输入),因此可以触发例外。
答案 2 :(得分:1)
工作代码中的断言(而不是测试代码)用于检查提供给代码的值是否正确。如果值错误,则抛出断言异常。
您可以编写自己的代码来测试值,并抛出您自己选择的异常。
断言易于使用,并且与日志记录一样,可以在已经彻底调试的生产代码中关闭。此外,任何阅读代码的人都知道测试的原因而不考虑它。这样可以节省时间。 (当你回去读两年前写的代码时,它也会节省你的时间。)
无论哪种方式都有效。
答案 3 :(得分:1)
许多程序员将断言转换为发布代码中的异常检查。或者他们可能会使用两种不同的断言来转换一个而不是其他断言,如果某些断言对性能非常敏感。
这是防御性编程的一部分。断言应该记录不可能的条件。然而,现实生活中的程序员知道有时会发生不可能的情况,因为未经测试的代码路径,系统库中的错误或硬件错误。
将断言转换为异常通常几乎没有什么害处。可能发生的一些伤害是在Java中,它可能会将一种新的异常类型引入到以前没有的方法中。另一个危害可能是转换后的断言可能位于需要非常高性能的循环内,并且断言检查可能会使其减慢太多。
答案 4 :(得分:0)
我认为主要区别在于断言允许您看到问题早于异常发生。所以它为你提供了一个早期的执行点,试图对它做一些事情(或者根本没什么 - 让它失败)。因此,如果你想在真正糟糕的事情发生之前看看执行是如何进行的,你会使用它们(抛出异常)。
我能想到的一个戏剧性的类比是那些联盟号国防军输送火箭弹,偶尔你会听到自动火箭在开始时偏离航线并立即触发其“自毁”。我猜它就像一个断言,他们用它来确定火箭的航向是否正确(如果它是一个例外 - 到可能抛出的时候火箭可能已经击中了什么)。
答案 5 :(得分:0)
断言被设计为有选择地关闭,默认情况下它们是关闭的。你应该在有条件的情况下使用它们,但是如果你真的需要的话可以检查。认为它们比例外情况更为特殊。
异常及其检查始终开启。虽然例外但它们仍然可以随时出现。
断言检测编码错误。一旦你的程序没有bug,就不需要它们,可以关闭它们。例外检测不正确的使用或输入,无法安全关闭。
答案 6 :(得分:0)
我在生产代码中看到两个断言用例:
在方法的开头,您将正常检查给定参数是否有效。对于公共方法,您将使用if statments和exceptions。对于私有方法,您可以使用assert进行simelar检查。这个想法是为了避免在测试过程中对产品进行冗余检查(或者当出现问题时),你可以激活断言进行一些双重检查。
使用断言的另一个原因是记录以下代码中使用的假设。就像那样,一些值在这里被认为永远不会为空。
这里有一些示例代码
public class Exampel {
public publicMethod(final Integer i) {
if (i == null) {
throw new RuntimeException("i should not be null");
}
privateMethod(i):
}
private privateMethod(final Integer i) {
assert i != null;
// do something
}
}
你不想多次检查我的null。您只需假设正确使用privateMethod
即可。你也给那些读取你代码的人提供了将null传递给privateMethod
的提示是错误的。