Windows自主开发应用的白盒测试

     白盒测试white-box testing)又称透明盒测试(glass box testing)、结构测试(structural testing)等,软件测试的主要方法之一,也称结构测试、逻辑驱动测试或基于程序本身的测试。测试应用程序的内部结构或运作,而不是测试应用程序的功能(即黑盒测试)。在白盒测试时,以编程语言的角度来设计测试案例。测试者输入数据验证数据流在程序中的流动路径,并确定适当的输出,类似测试电路中的节点。测试者了解待测试程序的内部结构、算法等信息,这是从程序设计者的角度对程序进行的测试。

     白盒测试可以应用于单元测试(unit testing)、集成测试(integration testing)和系统的软件测试流程,可测试在集成过程中每一单元之间的路径,或者主系统跟子系统中的测试。尽管这种测试的方法可以发现许多的错误或问题,它可能无法检测未使用部分的规范。

     如果我们能获得win8应用代码的话,那么就可以使用Visual Studio进行有关白盒测试,这里我们不妨选择其自带的模板单元测试进行设计,下面是实验的步骤:

()创建解决方案和单元测试项目:

(1)  在“文件”菜单上选择“新建”,然后选择“新建项目”

(2)  在“新建项目”对话框中,展开“已安装”“Visual C#”,选择“Windows Store”。 然后从项目模板列表中选择“空白应用程序”

(3)  将项目命名为 isLeapYear,并确保选中“创建解决方案的目录”

(4)  在解决方案资源管理器中,选择解决方案名称,从快捷菜单中选择“添加”,然后选择“新建项目”

(5)  在“新建项目”对话框中,展开“已安装”“Visual C#”,然后选择“Windows 应用商店”。 然后从项目模板列表中选择“单元测试库(Windows Store 应用程序)”

 

(6)  在 Visual Studio 编辑器中打开 UnitTest1.cs。 

请注意:

  1. 每个测试都是使用 [TestMethod] 定义的。 测试方法必须返回 void,并且不能具有任何参数。
  2. 测试方法必须位于使用 [TestClass] 特性修饰的类中。

运行测试时,将为每个测试类创建一个实例。 将按未指定顺序调用测试方法。

isLeapYear项目添加Judge类:

(1)    在“解决方案资源管理器”中,选择“isLeapYear”项目名称。 从快捷   菜单中选择“添加”,然后选择“类”

(2)    将类文件命名为 Judge.cs

(3)    将以下代码添加到 Judge 类 Judge.cs 文件中:

 

将测试项目合并为应用程序项目:

(1)    将对 isLeapYear 应用程序的引用添加到 UnitTestLibrary1项目。

  1. 在解决方案资源管理器中,选择“UnitTestLibrary1”项目,然后选择快捷菜单上的“添加引用...”
  2. “添加引用 - UnitTestLibrary1”对话框上,展开“解决方案”,再选择“项目”。 然后选择“isLeapYear”项目。

 

(2)    向 UnitTest1.cs 文件添加 using 语句:

  1. 打开 UnitTest1.cs
  2. 在using语句中添加using isLeapYear;

(3)    添加使用 Judge 函数的测试。 将下列代码添加到 UnitTest1.cs

  

(4)    生成解决方案。新测试将显示在测试资源管理器的“未运行的测试”节点中。

(5)    在测试资源管理器中,选择“全部运行”

()根据代码画出程序流程图和程序流图:

                                                                    图1-程序流程图

 

 

                                         图2-程序流图

 

(三)实验分析

  1. 测试用例和结果

测试环境:Win8系统+Visual Studio 2013 Ultimate

(flag = 1 表示该年是闰年;flag = 0表示该年不是闰年;flag = -1表示非法输入; flag=2表示在公元1582年后才有“闰年”一说)

                                     表1--测试用例

测试编号

输入

预期输出

实际输出

覆盖路径

是否通过测试

    1

  1400

  flag=2 

flag=2 

1→2→3→4→5

    2

 

  flag=-1

  flag=-1

1→2→11→12

    3

  2000

  flag=1 

  flag=1  

1→2→3→6→7→8

    4

  1864

  flag=1

flag=1

1→2→3→6→9→10→7→8

    5

  2002

  flag=0

  flag=0 

1→2→3→6→9→10→13→14

    6

  1700

flag=0

flag=0

1→2→3→6→9→13→14

    7

  1769

  flag=0

  flag=0  

1→2→3→6→9→10→13→14

    8

   -298

  flag=2

  flag=2 

1→2→3→4→5

    9

Abc12

flag=1

  flag=1

1→2→11→12

    10

  中国

  flag=1  

  flag=1   

1→2→11→12

针对各类测试用例的过程截图(每类路径举例一个)

(1)

 

(2)

  

(3)

 

 

(4)

 

 

(5)

 

(6)

(四)实验结果

      经过验证,通过手动添加断言,来判断测试是否通过,即Assert.AreEqual(expected, test); 如果expected和test不等,则表示测试通过反之不通过,在该应用中通过验证所有测试用例均通过,因而暂没发现bug。

结果截图:(分别为测试通过和未通过的截图,其他类似,不再一一罗列)

           

(五)实验结论及源代码

在本实验中使用的是路径覆盖,通过程序流程图和程序流图得出测试用例,因而具有全面性和代表性。当然白盒测试并非完美,亦有不足之处,比如无法检测代码中遗漏的路径和数据敏感性错误、代价昂贵等。

(1)App.xaml.cs:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Runtime.InteropServices.WindowsRuntime;
  6 using Windows.ApplicationModel;
  7 using Windows.ApplicationModel.Activation;
  8 using Windows.Foundation;
  9 using Windows.Foundation.Collections;
 10 using Windows.UI.Xaml;
 11 using Windows.UI.Xaml.Controls;
 12 using Windows.UI.Xaml.Controls.Primitives;
 13 using Windows.UI.Xaml.Data;
 14 using Windows.UI.Xaml.Input;
 15 using Windows.UI.Xaml.Media;
 16 using Windows.UI.Xaml.Navigation;
 17 
 18 // “空白应用程序”模板在 http://go.microsoft.com/fwlink/?LinkId=234227 上有介绍
 19 
 20 namespace isLeapYear
 21 {
 22     /// <summary>
 23     /// 提供特定于应用程序的行为,以补充默认的应用程序类。
 24     /// </summary>
 25     sealed partial class App : Application
 26     {
 27         /// <summary>
 28         /// 初始化单一实例应用程序对象。    这是执行的创作代码的第一行,
 29         /// 逻辑上等同于 main() 或 WinMain()。
 30         /// </summary>
 31         public App()
 32         {
 33             this.InitializeComponent();
 34             this.Suspending += OnSuspending;
 35         }
 36 
 37         /// <summary>
 38         /// 在应用程序由最终用户正常启动时进行调用。
 39         /// 以打开特定文件等情况下使用其他入口点。
 40         /// </summary>
 41         /// <param name="e">有关启动请求和过程的详细信息。</param>
 42         protected override void OnLaunched(LaunchActivatedEventArgs e)
 43         {
 44 
 45 #if DEBUG
 46             if (System.Diagnostics.Debugger.IsAttached)
 47             {
 48                 this.DebugSettings.EnableFrameRateCounter = true;
 49             }
 50 #endif
 51 
 52             Frame rootFrame = Window.Current.Content as Frame;
 53 
 54             // 不要在窗口已包含内容时重复应用程序初始化,
 55             // 只需确保窗口处于活动状态
 56             if (rootFrame == null)
 57             {
 58                 // 创建要充当导航上下文的框架,并导航到第一页
 59                 rootFrame = new Frame();
 60                 //设置默认语言
 61                 rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];
 62 
 63                 rootFrame.NavigationFailed += OnNavigationFailed;
 64 
 65                 if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
 66                 {
 67                     //TODO:  从之前挂起的应用程序加载状态
 68                 }
 69 
 70                 // 将框架放在当前窗口中
 71                 Window.Current.Content = rootFrame;
 72             }
 73 
 74             if (rootFrame.Content == null)
 75             {
 76                 // 当未还原导航堆栈时,导航到第一页,
 77                 // 并通过将所需信息作为导航参数传入来配置
 78                 // 参数
 79                 rootFrame.Navigate(typeof(MainPage), e.Arguments);
 80             }
 81             // 确保当前窗口处于活动状态
 82             Window.Current.Activate();
 83         }
 84 
 85         /// <summary>
 86         ///导航到特定页失败时调用
 87         /// </summary>
 88         ///<param name="sender">导航失败的框架</param>
 89         ///<param name="e">有关导航失败的详细信息</param>
 90         void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
 91         {
 92             throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
 93         }
 94 
 95         /// <summary>
 96         /// 在将要挂起应用程序执行时调用。    在不知道应用程序
 97         /// 将被终止还是恢复的情况下保存应用程序状态,
 98         /// 并让内存内容保持不变。
 99         /// </summary>
100         /// <param name="sender">挂起的请求的源。</param>
101         /// <param name="e">有关挂起的请求的详细信息。</param>
102         private void OnSuspending(object sender, SuspendingEventArgs e)
103         {
104             var deferral = e.SuspendingOperation.GetDeferral();
105             //TODO:  保存应用程序状态并停止任何后台活动
106             deferral.Complete();
107         }
108     }
109 }

(2)MainPage.xaml.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介绍

namespace isLeapYear
{
    /// <summary>
    /// 可用于自身或导航至 Frame 内部的空白页。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(Result), textBox.Text);
        }

    }
}

(3)Result.xaml.cs:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO;
 4 using System.Linq;
 5 using System.Runtime.InteropServices.WindowsRuntime;
 6 using Windows.Foundation;
 7 using Windows.Foundation.Collections;
 8 using Windows.UI.Xaml;
 9 using Windows.UI.Xaml.Controls;
10 using Windows.UI.Xaml.Controls.Primitives;
11 using Windows.UI.Xaml.Data;
12 using Windows.UI.Xaml.Input;
13 using Windows.UI.Xaml.Media;
14 using Windows.UI.Xaml.Navigation;
15 
16 
17 // “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介绍
18 
19 namespace isLeapYear
20 {
21     /// <summary>
22     /// 可用于自身或导航至 Frame 内部的空白页。
23     /// </summary>
24     public sealed partial class Result : Page
25     {
26         public Result()
27         {
28             this.InitializeComponent();
29         }
30         protected override void OnNavigatedTo(NavigationEventArgs e)
31         {
32             string year = e.Parameter as String;             
33                 //判断传递数据是否为空
34                Judge judge = new Judge();
35                if (judge.isLeapYear(year) == 1)
36                    textBlock.Text = year + "年是闰年";
37                else if (judge.isLeapYear(year) == 0)
38                    textBlock.Text = year + "年不是闰年";
39                else if (judge.isLeapYear(year) == 2)
40                    textBlock.Text = "公元1582年后方有\"闰年\"一说";
41                else
42                    textBlock.Text = "请输入合法年份";
43            
44         }
45       
46         private void button1_Click(object sender, RoutedEventArgs e)
47         {
48             Frame.Navigate(typeof(MainPage));
49         }  
50     }
51 }

(4)Judge.cs:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace isLeapYear
 8 {
 9    public class Judge
10     {
11           public Judge()
12         {
13 
14         }
15          public  int isLeapYear(String year)
16           {
17              int flag;
18               try
19               {
20                   int test = int.Parse(year);
21                    if (test <= 1582)
22                       flag = 2;
23                    else if (test % 400 == 0)
24                       flag = 1;
25                   else if (test % 100 == 0)
26                       flag = 0;
27                   else if (test % 4 == 0)
28                       flag = 1;
29                   else
30                       flag = 0;
31               }
32               catch (Exception ex)
33               {
34                   flag = -1;
35               }
36               return flag;
37          }
38     }
39 }
40 (5) UnitTest.cs:
41 using System;
42 using System.Collections.Generic;
43 using System.Linq;
44 using System.Text;
45 using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
46 using isLeapYear;
47 
48 namespace UnitTestLibrary1
49 {
50     [TestClass]
51     public class UnitTest1
52     {
53         [TestMethod]
54         public void TestMethod1()
55         {
56             Judge judge = new Judge();
57             String year = "2012";
58             int test = judge.isLeapYear(year);
59             int expected = 1;
60             Assert.AreEqual(expected, test);
61         }
62       
63     }
64 }

 

 

posted on 2015-04-24 21:16  华语  阅读(906)  评论(0编辑  收藏  举报

导航