【3】测试、避免调试、规格

测试:

程序的形式推理(验证)-> 代码审核 -> 测试

测试优先编程

尽早并经常进行测试 单个功能开发顺序:
1.编写功能说明
2.编写符合规范的测试
3.编写实际代码,一旦代码通过测试即完成

通过分区选择测试用例

将输入的每个子域由一组输入组成。子域合在一起完全覆盖了输入空间,因此每个输入都位于至少一个子域中
子域的思想:将输入空间划分为程序在其上具有相似行为的相似输入集。

在分区中包括边界:
eg: • 0是正数和负数之间的边界
• 数值类型的最大值和最小值,例如int和double
• 集合类型的空性(空字符串,空列表,空数组)
• 集合的第一个和最后一个元素
---------------
覆盖分区的两个极端

• 完整的笛卡尔积。 每个测试分区的合法组合都包含一个测试用例。
• 覆盖每个部分。
每个维度的每个部分都至少包含一个测试用例,但不一定是每个组合。

使用JUnit进行自动化的单元检测
黑盒和白盒测试

黑盒测试:仅从规范中选择测试用例,而不从功能的实现中选择。

白盒测试(也称为玻璃盒测试)意味着选择具有实际功能实现知识的测试用例。(例如,如果实现根据输入选择不同的算法,则应根据这些域进行分区。如果该实现保留一个内部缓存来记住先前输入的答案,那么您应该测试重复的输入)测试用例不需要规范未明确要求的特定实现行为
• 语句覆盖率:每个语句是否都由某个测试用例运行?
• 分支覆盖:对于程序中的每个if或while语句,某个测试用例是否同时遵循正确与错误的方向?
• 路径覆盖:某个测试用例是否采用了分支的所有可能组合(程序中的每个路径)
分支覆盖范围比语句覆盖范围要强,路径覆盖范围比分支覆盖范围要强

单元测试:隔离测试单个模块(例如方法或类)
集成测试对模块的组合甚至整个程序进行测试
自动化测试是指运行测试并自动检查其结果

避免调试

消除错误:

不变性(不受更改的影响)是防止错误的另一项设计原则。一个不可变的类型是一个类型,其价值一旦被创造永远无法改变。

本地化错误

尝试将它们本地化到程序的一小部分,这样就不必费劲查找错误的原因

断言(assert)

断言可以记录当时有关程序状态的假设 在Java中,运行时断言是该语言的内置功能 assert x >= 0; 如果x ==
-1,则此断言失败并显示错误消息 Java断言的一个严重问题是断言默认情况下处于关闭状态

您应该断言一些事情:

方法参数要求,如sqrt。 方法返回值要求。 这种断言有时称为自我检查。例如,

    assert x >= 0;
    double r;
    ... // compute result r
    assert Math.abs(r*r - x) < .0001;
    return r; } ```

涵盖所有情况。如果条件语句或转换未涵盖所有可能的情况,则优良作法是使用断言阻止非法情况:

```switch (vowel) {   case 'a':   case 'e':   case 'i':   case 'o':  
case 'u': return "A";   default: assert false; } ```


切勿使用断言来测试程序外部的条件,例如文件的存在,网络的可用性或人类用户键入的输入的正确性。断言测试程序的内部状态,以确保它在其规范的范围内。断言失败时,表明该程序在某种意义上已经脱离轨道,进入了无法正常运行的状态。因此,断言失败表明存在错误。外部故障不是bug,您无法对程序进行任何预先更改以防止它们发生。外部故障应使用异常处理。

模块化: 模块化意味着将系统划分为组件或模块,每个组件或模块都可以与系统其余部分分开设计,实施,测试,推理和重用。
由一个非常长的main()函数组成的程序是整体的一个模块会很难理解,也很难隔离错误。所以相比之下,分解为小函数和类的程序则更具模块化。

封装:封装是指在模块周围建造墙,以使模块负责其自身的内部行为,并且系统其他部分中的错误不会破坏其完整性。
一种封装是访问控制
使用public和private控制变量和方法的可见性和可访问性。任何代码都可以访问公共变量或方法(假设包含该变量或方法的类也是公共的)。私有变量或方法只能由同一类中的代码访问。尽可能地保持私有状态,尤其是对于变量,可以提供封装,因为它限制了可能无意中导致错误的代码。
> 另一种封装来自可变范围
从表达式和语句可以引用该变量的意义上来说,变量的范围是程序文本中定义该变量的部分。方法参数的范围是方法的主体。局部变量的范围从其声明扩展到下一个右花括号。保持变量作用域尽可能小,可以更容易地推断出程序中可能存在错误的位置。例如,假设您有一个像这样的循环:
for (i = 0; i < 100; ++i) {

doSomeThings();
… }

代码评审

两个主要目的:

o 提升代码质量 o 提升程序员的水平

代码风格因人而异,每个公司也都会有自己的标准

o 不要重复你的代码(DRY)
o 仅在需要的地方做注释
o 快速失败/报错
o 避免使用幻数
o 一个变量有且仅有一个目的
o 使用好的命名
o 避免使用全局变量
o 返回结果而非打印它
o 使用空白符提升可读性

规格说明

一种 规格 方法的组成由几个子句组成:
• 一种 前提,由关键字require指示
前提条件是对客户端(即方法的调用者)的义务。这是调用该方法的状态的条件
• 一种 后置条件,由关键字effects指示
后置条件是该方法的实现者的义务

良好的设计规格

• 规范的形式:简洁,清晰,结构合理,以便于阅读
• 规范应该连贯
• 连接结果应该有效益
• 规格应足够坚固,在完善顾客的需求的时候,不会轻易将之前的都被破坏掉
• 规格也应足够弱:比如再打开文件时,应给它不能打开文件而报错返回的时候,不能只是强制打开
• 在可能的情况下应使用抽象类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值