白盒测试
白盒测试法全面了解程序内部逻辑结构, 对所有逻辑路径进行测试。 白盒测试法是穷举路径测试。在使用这一方案时, 测试者必须检查程序的内部结构, 从检查程序的逻辑着手 , 得出测试数据。
1.白盒测试的范围
白盒测试是软件测试体系中一个分支, 测试关注对象是一行行可见代码,如果代码不可见,就不是白盒,而是黑盒测试了。 白盒测试也通常被认为是单元测试与集成测试的统称, 但这个概念是相对的, 与当前项目遵循的研发流程有关,某些流程把白盒测试划分为单元测试与集成测试, 而另一些流程, 把白盒测试划分为模块单元测试、模块系统测试、多模块集成测试, 还有一些流程把单元测试与集成测试混为一体,统称为持续集成测试。白盒测试方法, 范围限定在功能测试之前,针对源码行的所有测试, 即被测对象是看得到的功能源码,每个测试者必须先获得源码才能实施测试。
2.白盒测试的目的
通过检查软件内部的逻辑结构, 对软件中的逻辑路径进行覆盖测试; 在程序不同地方设立检查点, 检查程序的状态, 以确定实际运行状态与预期状态是否一致。
3.白盒测试的特点
依据软件设计说明书进行测试,对程序内部细节严密检验, 针对特定条件设计测试用例, 对软件的逻辑路径进行覆盖测试。
4.白盒测试的步骤
测试计划阶段: 根据需求说明书, 制定测试进度;
测试设计阶段: 依据程序设计说明书,按照一定规范化的方法进行软件结构划分和设计测试用例。
测试执行阶段: 输入测试用例, 得到测试结果。
测试总结阶段: 对比测试的结果和代码的预期结果,分析错误原因, 找到并解决错误。
5.白盒测试的方法
总体上分为静态方法和动态方法两大类。
静态分析是一种不通过执行程序而进行测试的技术。 静态分析的关键功能是检查软件的表示和描述是否一致, 有没有冲突或者有没有歧义。
动态分析的主要特点 是 当 软 件 系 统 在 模 拟 的 或 真 实 的 环中执行之前、之中和之后, 对软件系统行为的分析。 动态分析包含了程序在受控的环境下使用特定的期望结果进行正式的运行。它显示了一个系统在检查状态下是正确还是不正确。 在动态分析技术中,最重要的技术是路径和分支测试。
6.接下来介绍怎么使用visual studio的模板来对应用商店应用进行白盒测试:
(原文请参考https://msdn.microsoft.com/zh-cn/library/jj159318.aspx?f=255&MSPPError=-2147217396)
-
在“文件”菜单上选择“新建”,然后选择“新建项目”。
-
在“新建项目”对话框中,展开“已安装”、“Visual C#”,选择“Windows Store”。 然后从项目模板列表中选择“空白应用程序”。
-
将项目命名为 Maths,并确保选中“创建解决方案的目录”。
-
在解决方案资源管理器中,选择解决方案名称,从快捷菜单中选择“添加”,然后选择“新建项目”。
-
在“新建项目”对话框中,展开“已安装”、“Visual C#”,然后选择“Windows 应用商店”。 然后从项目模板列表中选择“单元测试库(Windows Store 应用程序)”。
-
在 Visual Studio 编辑器中打开 UnitTest1.cs。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using Maths; namespace RooterTests { [TestClass] public class UnitTest1 [TestMethod] public void TestMethod1() { }
请注意:
-
每个测试都是使用 [TestMethod] 定义的。 测试方法必须返回 void,并且不能具有任何参数。
-
测试方法必须位于使用 [TestClass] 特性修饰的类中。
运行测试时,将为每个测试类创建一个实例。 将按未指定顺序调用测试方法。
-
您可定义在每个模块、每个类或每个方法前后调用的特定方法。 有关更多信息,请参见 MSDN 库中的在单元测试中使用 Microsoft.VisualStudio.TestTools.UnitTesting 成员。
-
-
在 UnitTest1.cs 文件的 TestMethod1 中插入一些测试代码:
[TestMethod] public void TestMethod1() { Assert.AreEqual(0, 0); }
请注意,Assert 类提供的若干静态方法可用于验证测试方法的结果。
-
在“测试”菜单上,选择“运行”,然后选择“全部运行”。
将生成并运行测试项目。 随即显示“测试资源管理器”窗口,并且测试列出在“已通过的测试”下。 窗口底部的“摘要”窗格将提供有关所选测试的其他详细信息。
-
将对 Maths 应用程序的引用添加到 RooterTests 项目。
-
在解决方案资源管理器中,选择“RooterTests”项目,然后选择快捷菜单上的“添加引用...”。
-
在“添加引用 - RooterTests”对话框上,展开“解决方案”,再选择“项目”。 然后选择“Maths”项目。
-
-
向 UnitTest1.cs 文件添加 using 语句:
-
打开 UnitTest1.cs。
-
在 using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; 行下添加以下代码:
using Maths;
-
-
添加使用 Rooter 函数的测试。 将下列代码添加到 UnitTest1.cpp:
[TestMethod] public void BasicTest() { Maths.Rooter rooter = new Rooter(); double expected = 0.0; double actual = rooter.SquareRoot(expected * expected); double tolerance = .001; Assert.AreEqual(expected, actual, tolerance); }
-
生成解决方案。
新测试将显示在测试资源管理器的“未运行的测试”节点中。
-
在测试资源管理器中,选择“全部运行”。
您已设置测试和代码项目,并验证了您可在代码项目中运行运行函数的测试。 现在您可开始编写真实测试和代码。
-
添加新测试:
[TestMethod] public void RangeTest() { Rooter rooter = new Rooter(); for (double v = 1e-6; v < 1e6; v = v * 3.2) { double expected = v; double actual = rooter.SquareRoot(v*v); double tolerance = ToleranceHelper(expected); Assert.AreEqual(expected, actual, tolerance); } }
提示 建议您不要更改已通过的测试。 而是添加新测试,更新代码以便测试通过,然后添加其他测试等。
当您的用户更改其要求时,请禁用不再正确的测试。 编写新测试并使它们以相同的增量方式一次运行一个。
-
在测试资源管理器中,选择“全部运行”。
-
测试将不会通过。
提示 编写测试后,立即验证每个测试是否都将失败。 这帮助您避免易犯的错误,不会编写从不失败的测试。
-
增强受测代码,以便新测试通过。 将 Rooter.cs 中的 SqareRoot 函数更改为:
public double SquareRoot(double x) { double estimate = x; double diff = x; while (diff > estimate / 1000) { double previousEstimate = estimate; estimate = estimate - (estimate * estimate - x) / (2 * estimate); diff = Math.Abs(previousEstimate - estimate); } return estimate; }
-
生成解决方案,然后在测试资源管理器中,选择“全部运行”。
现在所有三个测试都将通过。
提示 |
---|
通过添加测试的方式一次性开发代码。 确保所有测试在每次迭代后都通过。 |
-
向 UnitTest1.cs 添加另一个测试:
// Verify that negative inputs throw an exception. [TestMethod] public void NegativeRangeTest() { string message; Rooter rooter = new Rooter(); for (double v = -0.1; v > -3.0; v = v - 0.5) { try { // Should raise an exception: double actual = rooter.SquareRoot(v); message = String.Format("No exception for input {0}", v); Assert.Fail(message); } catch (ArgumentOutOfRangeException ex) { continue; // Correct exception. } catch (Exception e) { message = String.Format("Incorrect exception for {0}", v); Assert.Fail(message); } } }
-
在测试资源管理器中,选择“全部运行”。
测试将不会通过。 在测试资源管理器中选择测试名称。 将突出显示失败的断言。 失败消息将在测试资源管理器的细节窗格中可见。
-
若要查看测试未通过的原因,请单步执行以下函数:
-
在 SquareRoot 函数的开头设置断点。
-
在未通过测试的快捷菜单上,选择“调试选定的测试”。
当运行在断点处停止时,请单步执行以下代码。
-
向 Rooter 方法添加代码以捕获异常:
public double SquareRoot(double x) { if (x < 0.0) { throw new ArgumentOutOfRangeException(); }
-
在测试资源管理器中,选择“全部运行”以测试已纠正的方法,并确保您未引入回归测试。
-
所有测试都将通过。
-
更改结果实现
// old code //result = result - (result*result - v)/(2*result); // new code result = (result + v/result) / 2.0;
-
选择“全部运行”以测试已重构的方法,并确保您未引入回归测试。
提示 |
---|
一组稳定的优良单元测试可保证您在更改代码时不会引入 Bug。 |
重构测试代码以消除重复代码。
请注意,RangeTest 方法对 Assert 方法中使用的公差变量的分母进行硬编码。 如果您计划添加其他使用同一公差计算的测试,则在多个位置使用硬编码的值可能导致错误。
-
向 Unit1Test 类添加一个私有方法以计算公差值,然后改调用该方法。
private double ToleranceHelper(double expected) { return expected / 1000; } ... [TestMethod] public void RangeTest() { ... // old code // double tolerance = expected/1000; // new code double tolerance = ToleranceHelper(expected); Assert.AreEqual(expected, actual, tolerance); } ...
-
选择“全部运行”以测试已重构的方法,并确保您未引入错误。