zoukankan      html  css  js  c++  java
  • 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 }

     

  • 相关阅读:
    内存溢出
    Spring-bean的循环依赖以及解决方式
    JUC中Lock和ReentrantLock介绍及源码解析
    RocketMQ阅读注意
    RocketMQ环境搭建
    HSF源码阅读
    最近找工作,有招JAVA开发的可以联系我,如果不嫌弃我2年前用C,也可以联系我
    Spring Extensible XML
    MySQL主主+Keepalived架构安装部署
    记录一则数据库死锁故障的分析过程
  • 原文地址:https://www.cnblogs.com/xlwm/p/4454510.html
Copyright © 2011-2022 走看看