回答
是的。测试只能证明您所测试的没有缺陷。动态测试不能涵盖所有依赖性环境中的所有可能的输入和输出。
首先是简单地不测试有问题的代码。这可以通过检查您的测试的coverage进行验证。即使你达到100%的覆盖率,仍然可能存在缺陷。
接下来是不检查所有可能的输入类型和范围。例如,如果您有扫描字符串中某个单词的功能,则需要检查...
- 字符串的开始处的单词。
- 字符串末尾的单词。
- 单词在字符串中间。
- 一个没有单词的字符串。
- 空字符串。
这些被称为boundary conditions,包括喜欢的东西:
- 负数
- 空字符串
- 空
- 非常大的值
- 小数
- 个Unicode的
- 空文件
- 非常大的文件
如果有问题的代码在全局变量保持状态,也许在一个对象,也许,你要测试的状态不会被破坏或干扰随后的运行。
如果您正在进行并行处理,您必须测试由于尝试同时执行同一事件而导致的死锁或损坏的任何数量的可能性。例如,两个进程试图写入同一个文件。或者两个进程都在等待同一资源的锁定。他们只锁定他们需要的东西吗?他们尽快放弃锁定吗?
一旦你测试了代码应该工作的所有方式,你必须测试它可能发生故障的所有方式,它是否以异常(而不是垃圾)方式优雅地失败,错误是否使它损坏状态等等。它如何处理资源故障,如未能连接到数据库?这对于处理数据库和文件非常重要,以确保失败不会让事情发生部分改变。
例如,如果你从一个账户转移资金到另一个你可能会这样写:
my $from_balance = get_balance($from);
my $to_balance = get_balance($to);
set_balance($from, $from_balance - $amount);
set_balance($to, $to_balance + $amount);
会发生什么,如果第一set_balance
后的程序崩溃?如果另一个流程更改为get_balance
和set_balance
之间的平衡,会发生什么情况?必须考虑并测试这些并发问题。
代码可以运行在不同的环境中。不同的操作系统。不同的编译器。不同的依赖关系。不同的数据库所有的版本都不一样。所有这些都必须经过测试。
该测试可能只是错误的。在测试中可能是一个错误。在规范中可能是一个错误。通常,用不同的方式测试相同的代码以避免这个问题。
该测试可以是正确的,规范可以是正确的,但功能是错误的。这可能是一个糟糕的设计。这可能是一个坏主意。你可以说这不是一个“bug”,但如果用户不喜欢它,它需要被修复。
如果你的测试使用了大量的嘲讽,你的嘲笑可能不会反映被嘲弄的东西实际上是如何表现的。
依此类推。
对于所有这些缺陷,动态测试仍然是测试超过几十行代码的最佳选择。
- 1. 什么是故障 - 段故障,即...?
- 2. ,检测故障
- 3. C++程序故障?
- 4. 方法是故障
- 5. 单元测试WCF故障
- 6. JUnit测试类故障
- 7. 故障可以用Python
- 8. 故障使用单元测试
- 9. 如何跳过surefire测试但运行故障安全测试?
- 10. 通过sed管道故障
- 11. 线程故障
- 12. 动态随机数故障
- 13. 试图动态asp:FileUpload,刷新故障
- 14. WCF故障状态?
- 15. 故障快速和故障安全异常处理原则是否不兼容?
- 16. Django动态过滤器故障
- 17. 应用程序洞察中的区域可用性故障故障排除
- 18. 故障使用PHP
- 19. 故障使用MYSQL
- 20. FTS使用故障
- 21. Cairngorm故障处理程序
- 22. RFID阅读程序故障
- 23. 故障与“是”在Haskell
- 24. 什么是故障屏蔽?
- 25. Redis/Jedis没有单点故障和自动故障转移
- 26. 当应用程序出现故障时是否可以获取警报?
- 27. CSS浮动故障
- 28. jQuery动画故障
- 29. jQuery动画故障?
- 30. 离子Gradle故障“找不到com.android.tools.build:gradle:2.2.3”
呃......呃?我不知道你在问什么,我相当肯定其他人可能会遇到同样的问题。你认为你可以澄清一点吗? :) –
我相信这是经典的“我怎么知道我的软件是否是无bug的”问题。 – Schwern