由于我们越来越依赖于计算,包括日常生活中非常重要的任务,所以我只是想知道如何测试这些重要组件。
从技术上讲,如何测试编译器和汇编器?(我想这与停止问题有关!)
由于我们越来越依赖于计算,包括日常生活中非常重要的任务,所以我只是想知道如何测试这些重要组件。
从技术上讲,如何测试编译器和汇编器?(我想这与停止问题有关!)
Answers:
您不确定,但是您只是假设它们是,直到发现它们不是。这些年来,编译器和硬件中存在许多错误。
测试这些方法(例如编译器)的方式是:非常狭窄,严格地定义它们,仔细编写它们,然后使用庞大的测试套件进行测试以验证其正确性。加上编译器的广泛用户基础,将检测并报告更多错误。相比之下,牙医预约计划应用程序具有更少的用户,仍然能够检测缺陷的用户更少。
SQLite包含约73k行代码,而其测试套件包含约91378k行代码,是SQLite本身的1250倍以上。我希望编译器和其他核心工具具有相似的比率。当今的处理器基本上是使用软件来设计的,使用的是诸如Verilog或VHDL之类的硬件描述语言,并且这些处理器还具有在其上运行的软件测试以及专用的IO引脚,以便在制造时进行自测。
归根结底,这是一个概率游戏,重复而广泛的测试使您可以将缺陷的概率降低到可接受的低水平,就像其他软件项目一样。
用外行的话来说:
底线:
我想说的是OOP(O ld,O pen和P opular)。我只是编了首字母缩写。
一直都是乌龟。
没有什么可以确定的。您别无选择,只能选择置信度。
您可以将其视为堆栈:数学>物理>硬件>固件>操作系统>汇编器/编译器/等
在每个级别上,您都可以执行一些测试来提高您的置信度。这些测试中的一些具有形式证明的质量,其中一些是基于观察的,大多数是两者的结合。
棘手的部分是在其中的一些测试中弄清递归,因为我们现在使用程序来进行证明和观察性分析,而现在手工很难做到这一点。
最终,尽管答案是您尝试了所有可以想到的东西。静态分析,模糊测试,模拟,使用有目的地选择的极端输入或随机输入运行,运行/映射每个控制路径,形式证明等。基本上,测试的目标应始终是尽一切可能证明您的产品(例如理论/芯片/程序)无法正常工作。如果您付出了真正的努力却仍然失败,则可以提高对产品正确性的置信度。
测试充其量是一个半决定性的过程,这意味着只要有一个错误,您最终就会发现它,但是您永远无法确定自己已经找到了所有错误。即使使用了经过正式验证的软件,您仍然依赖于物理,用于进行形式证明的工具,并且您证明的事情对于程序执行(通常是主观上)“预期”的事情是必要且充分的。更不用说您使用的所有其他组件都没有形式证明。
对于新开发者来说,这是一个“危险”的问题,因为他们将开始指责他们的工具而不是他们的代码(在那里,这样做,看到太多人这样做了)。尽管编译器,运行时环境,OS等中存在错误,但是开发人员应该切合实际,并记住这一点,直到有证据和单元测试表明存在其他错误为止,该错误才存在于代码中。
在使用C,C ++和Java进行编程的25年以上的过程中,我发现:
所有其他错误均与错误直接相关,或更常见的是,对库的工作原理缺乏了解。有时似乎是错误的原因是由于不兼容,例如Java类结构的更改如何破坏了某些AOP库。
我认为这里有趣的一点是,绝大多数商业软件(甚至是开源软件)许可证都明确规定您不能信任该软件。
本软件按“原样”提供,不提供任何形式的明示或暗示担保,包括但不限于对适销性,特定目的的适用性和非侵权性的担保。
来自Microsoft Word许可协议
。除有限保修和适用法律允许的最大范围外,Microsoft及其供应商按原样和所有故障提供软件和支持服务(如果有),并在此否认所有其他担保和条件,无论是明示,暗示或法定的,包括但不限于对适销性,对特定目的的适用性,可靠性或可用性,响应的准确性或完整性,结果,工人的努力,所有与软件有关的病毒,缺乏疏忽,以及通过软件提供或未能提供支持或其他服务,信息,软件和相关内容,或由于使用软件而引起的其他情况。
从本质上讲,几乎在您使用的每个软件中,许可证中的这一句话都告诉您,您不能信任该软件,更不用说使用的编译器了。
软件就像一个科学理论,它被认为可以按照指定的方式工作,直到不起作用为止。
作为数学语言*的编译器作家,根据我的经验,从理论上我可以说你不能。而且某些错误会给出错误的结果,例如(从我的耻辱列表中)6/3*2
从正确的位置进行计算6/(3*2)
并输出1而不会崩溃或产生无意义的编译错误。
但是恕我直言,许多编译器没有其他软件那样多的错误,因为:
test_unit("2+(-2)*(-2+1)*3+1",9);
对于汇编程序,机器说明等,以上内容也适用;另一方面,芯片设计和生产中的验证和确认流程要严格得多,因为这是一项巨大的业务:电子设计自动化。
在生产之前,应该对每个CPU进行严格的测试,因为每个bug的成本将近两百万美元:芯片生产中存在大量的非经常性生产成本。因此,公司在投入生产之前会花很多钱并为他们的设计编写很多仿真代码,尽管这不能提供100%的保证-例如:Pentium FDIV bug。
简而言之,不太可能在编译器,机器代码等中出现严重的错误。
我谦虚的数学语言 *
完美无瑕?他们不是。我最近安装了一些“更新”,由于各种基础工作方式的无法解释的变化,我的ASP.NET站点又几个月后(以及代码的几个重新编程部分)再次正常工作。
但是,它们经过许多非常聪明的注重细节的人员的测试,然后使用,他们往往会注意到并报告和修复大多数问题。Stack Exchange是一个很好的例子(并改进了),所有使用这些工具的人们如何至少在实际使用范围内,如何帮助测试和分析这些惊人的复杂和低级工具的工作方式。
但是完美无缺。尽管您还可以看到Stack Exchange上的人员对性能细节以及标准合规性和怪异之处有了深刻的了解,但始终存在缺陷和不完善之处,尤其是当不同的人对缺陷的看法不同时。
为了表明底层系统是完美无缺的,您要么
a)需要证明它们是完美的
b)进行详尽的测试
在软件测试中,穷举测试仅用于某些简单功能的单元测试。
示例:您要测试某个字段的8个字符的utf-8输入,您可以选择将输入剪切为utf-8最大长度6的8倍(以字节为单位),这样实际上就有8 * 6 = 48个字节无限的可能性。
您现在可以认为您只需要测试8个字符中每个字符的1,112,064个有效代码点,即。1,112,064 ^ 8(例如10 ^ 48)测试(这已经不太可能了),但是实际上您必须测试48个字节或256 ^ 48中的每个字节的每个值,这大约是10 ^ 120,这与国际象棋的复杂度相同与宇宙中大约10 ^ 80的原子总数相比。
取而代之的是,您可以按增加的使用顺序使用,并且每个测试都应涵盖所有先前的测试:
a)测试好样品和坏样品。
b)代码覆盖率,即 尝试测试每一行代码,这对于大多数代码而言相对简单。现在您想知道您无法测试的代码的最后1%是什么...错误,无效代码,硬件异常等。
c)路径覆盖,测试所有组合中所有分支的所有结果。现在您知道了当您的职能包含10个以上条件时测试部门为什么讨厌您。您还想知道为什么无法测试最后1%的内容...有些分支依赖于先前的分支。
d)数据测试,测试一些具有边界值,常见问题值和幻数的样本,零,-1、1,最小+/- 1,最大+/- 1、42,rnd值。如果这不能为您提供路径覆盖,则说明您尚未捕获分析中的所有值。
如果您已经这样做,则应该为ISTQB基础考试做好准备。