zoukankan      html  css  js  c++  java
  • 超级简单:一个超轻量级的测试平台

        有时候,在开发环境中测试核心业务职能,可能需要花很长而宝贵的时间。

        幸运地是有很多简单而且自动化的测试平台。尽管如此,这个操作却不会总是能提供预期的结果。有时,它需要人为进行检查和评价。

        此外,在一个大型项目中,编译几十个类,每一点变动是非常耗费时间和精力的,自动测试将不会达到预期的行为。OBP控制台测试框架是一个非常简单,轻量级的类库,它用于测试你的业务对象,但它没有一个像windows forms,web, silverlight 、WPF的图形界面。

        OBP控制台测试库的主要目的是:在将代码整合到相关项目中之前,检查它的核心业务功能。

      在测试类有下列行为:

        在运行时,通过自定义属性和反射找出测试类和测试方法

        提供测试人员提供一个简单菜单式的控制台的用户界面

        允许重复使用菜单(控制台上的)

        便利地显示的业务对象的集合,并能便利从中选择单独的业务对象进行测试。

      文章中的一些定义

        测试方法 :能通过执行一些动作来验证开发项目的行为、动作、过程。

        测试类 :包含一个或多个测试方法的类。它也可能还包含测试类成员来执行重叠测试。

        菜单 :是在控制台上显示一系列的活动,允许测试人员使用键盘调用一个给定的测试方法。

      结构:

       整个类库是建立在一个简单的类上:CustomConsoleTest。这个类完成以下行动:

       1、它使用反射浏览所有子类的方法并找出有“TestMethod”属性的方法。

       2、使用“TestMethod”属性,它能正确显示在菜单上使用的方法的名称。

           测试时,简化了业务对象集合的显示,以及简化在集合中选择单独的业务对象。

       3、为了进行测试,你需要实例化一个CustomConsoleTest子类(这个类是抽象的)和调用方法“Execute”方法。

       在这个简单的类中,神奇之处是一个测试类可以嵌入其他的测试类,执行父类中的测试方法能调用子类的Execute方法。因此,你能很快建立一个分层控制台菜单,用于在整合之前专注于核心业务功能的测试。

      实现:

      所有的测试类都要继承CustomConsoleTest。下面是构造函数:

    CustomConsoleTest
     public CustomConsoleTest()
            {
                var t 
    = this.GetType();
                
    int i = 0;
                
    string name = null;
                
    // find the methods
                foreach (var m in t.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
                {
                    
    if (IsValidMethod(m, ref name))
                    {
                        var item 
    = new MethodItem(name, m);
                        _methods.Add(_menuKeys[i], item);
                        
    ++i;
                    }
                }
            }

       当CustomConsoleTest子类被实例化,执行以下操作:

       1、使用反射去查找有自定义属性TestMethod的方法。

       2、当一个方法有TestMethod属性,它被添加到一个类名为MethodItem的集合,这个集合包含MethodInfo实例和方法的名称。

       一旦测试方法发现,它将显示在菜单上,允许测试人员通过键盘上的键调用的测试方法。

       为了完成这些,测试人员必须调用方法“Execute”的方法,这个方法浏览方法集合和在菜单上显示测试方法友好名称(如[TestMethod("List Machines")]中就显示List Machines)。

       为了重复的测试,因此能实现重复菜单,测试类可以嵌入其他测试类,调用测试方法也将调用嵌入类的"Execute"。代码如下:

    Execute
     public void Execute()
            {
                
    char c = '*';
                
    while ((c != 'q'&& (c != 'Q'))
                {
                    
    foreach (var p in _methods)
                        Console.WriteLine(
    "{0} - {1}", p.Key, p.Value.DisplayText);
                    Console.WriteLine(
    "q - Quit");
                    Console.WriteLine();
                    c 
    = Console.ReadKey(true).KeyChar;
                    
    if (_methods.ContainsKey(c))
                        
    try
                        {
                            var m 
    = _methods[c];
                            m.Method.Invoke(
    thisnull);
                        }
                        
    catch (Exception ex)
                        {
                            Console.ForegroundColor 
    = ConsoleColor.Red;
                            Console.WriteLine(
    "An exception has occured when invoking the method {0}",
                                ex);
                        }
                }
            }

       为了方便地显示和选择集合中的项,我添加一个泛型函数来简化集合处理,这假设集合实现了通用接口IEnumerable<T>。 

    DisplayCollection
    protected void DisplayCollection<T>(IEnumerable<T> aCollection)
    {
        
    if (aCollection.Count() == 0)
            Console.WriteLine(
    "No item in the collection");
        
    int i = 1;
        _elts.Clear();
        
    foreach (var e in aCollection)
        {
            Console.WriteLine(
    "{0} - {1}", i, GetDescription(e));
            _elts.Add(i, e);
            
    ++i;                
        }
        Console.WriteLine();
    }

       SelectItem方法使在控制台模式下选择测试方法更加容易:

    代码
      protected T SelectItem<T>(IEnumerable<T> aCollection) where T : class
            {
                DisplayCollection
    <T>(aCollection);
                
                
    while (true)
                {
                    Console.WriteLine(
    "Type the element number or q to exit");
                    var text 
    = Console.ReadLine();
                    
    if ((text == "q"|| (text == "Q"))
                        
    return null;
                    
    try
                    {
                        
    int index = Convert.ToInt32(text);
                        
    if (_elts.ContainsKey(index))
                            
    return (T)_elts[index];
                        
    else
                            Console.WriteLine(
    "The list does not contain that number, try again !");
                    }
                    
    catch
                    {
                        Console.WriteLine(
    "Wrong value");
                    }
                }
            }

       为了显示菜单,我将寻找到的测试方法放在MethodItem类中

    代码
     class MethodItem
        {
            
    internal MethodItem(string aDisplayText, MethodInfo aMethod)
            {
                DisplayText 
    = aDisplayText;
                Method 
    = aMethod;
            }

            
    internal string DisplayText { getprivate set; }

            
    internal MethodInfo Method { getprivate set; }
        }

     示例:

       将所有的功能展示在一个机器和零配件的示例中,应用程序包括两种类型的业务对象:Machine(机器)和SparePart(零配件)。

     

    代码
    class Machine : Asset
    {
       //机器类中有添加零配件AddPart方法。CreateInstances静态的构建方法,零配件列表:List<SparePart>
        
    internal void AddPart(SparePart aPart)
        {
            Parts.Add(aPart);
            AddWeight(aPart.Weight);
        }
        
        
    public Machine(string aName)
            : 
    base(aName)
        {
            Parts 
    = new List<SparePart>();
        }
        
        
    public static void CreateInstances()
        {
            Machines 
    = new List<Machine>();
            
    for (int i = 0; i < new Random().Next(10+ 1; i++)
                Machines.Add(
    new Machine(string.Format("Machine{0}", i)));
        }
        
        
    public static List<Machine> Machines
        {
            
    get;
            
    private set;
        }
        
        
    public List<SparePart> Parts { getprivate set; }
    }

     零配件类:

    代码
    class SparePart : Asset
    {
        
    public SparePart(Machine aMachine, string aName, double aWeight):
            
    base(aName)
        {
            Machine 
    = aMachine;
            Weight 
    = aWeight;
            aMachine.AddPart(
    this);            
        }
        
        
    public static void CreateInstances()
        {
            Parts 
    = new List<SparePart>();
            var random 
    = new Random();
            
    foreach(var m in Machine.Machines)
                
    for (int i = 0; i < random.Next(5); i++)
                {
                    var part 
    = new SparePart(m, string.Format
                        (
    "{0}-part{1}", m.Name, i),
                        random.NextDouble());
                    Parts.Add(part);
                }
        }
        
        
    public Machine Machine { getprivate set; }
        
        
    public static List<SparePart> Parts
        { 
    getprivate set; }
    }

     要实现我的测试操作,我需要三个类:MachineTest测试Machine,PartTest测试spare部分,SoftwareTest中嵌入这两个的测试。

    代码
    /// <summary>
    /// this class is used to test software
    /// </summary>
    class SoftwareTest : CustomConsoleTest
    {
        
    /// <summary>
        
    /// machine test
        
    /// </summary>
        private MachineTest _machineTest = new MachineTest();
        
        
    /// <summary>
        
    /// part test
        
    /// </summary>
        private PartTest _partTest = new PartTest();
        
        [TestMethod(
    "Machines")]        
        
    private void ExecuteMachineTest()
        {
            _machineTest.Execute();
        }
        
        [TestMethod(
    "Parts")]
        
    private void ExecutePartTest()
        {
            _partTest.Execute();
        }
        
        
    static SoftwareTest()
        {
            Machine.CreateInstances();
            SparePart.CreateInstances();
        }
    }
    代码
    class MachineTest : CustomConsoleTest
    {
        [TestMethod(
    "List Machines")]
        
    private void ListMachines()
        {
            DisplayCollection
    <Machine>(Machine.Machines);
        }
        
        
    protected override string GetDescription(object e)
        {
            
    if(e is Machine)
            {
             var m 
    = e as Machine;
             
    return string.Format("Machine {0} | {1:0.00} | Parts : {2}",
                 m.Name, m.Weight, m.Parts.Count);
            }
            
    return base.GetDescription(e);
        }
    }

      为了更精细显示的业务对象,我重写的方法GetDescription,它本身是以ToString方法为基础。

    代码
    class PartTest : CustomConsoleTest
    {
        
    protected override string GetDescription(object e)
        {
            
    if (e is SparePart)
            {
                var p 
    = e as SparePart;
                
    return string.Format("Machine : 
                    {0- {1}", p.Machine.Name, p.Name);
            }
            
    return base.GetDescription(e);
        }
        
        
    /// <summary>
        
    /// selection
        
    /// </summary>
        [TestMethod("Select A Part")]
        
    protected void TestSelect()
        {
            var p 
    = SelectItem<SparePart>(SparePart.Parts);
            
    if (p != null)
                Console.WriteLine(
    "You have selected the part {0}", p.Name);
        }
    }

     总结:

        以我个人开发大型软件系统的经验,自动化测试是很好,但还往往不够,在非常特别的情况,要耗很多时间去测试。我的做法很重要一点是没有软件界面部分,在控制台项目中进行测试非常的快。

    参考代码:/Files/zhuqil/TestBO.zip

    参考原文:http://www.codeproject.com/KB/cs/SimpleConsoleTestClass.aspx



    (全文完)


    以下为广告部分

    您部署的HTTPS网站安全吗?

    如果您想看下您的网站HTTPS部署的是否安全,花1分钟时间来 myssl.com 检测以下吧。让您的HTTPS网站变得更安全!

    SSL检测评估

    快速了解HTTPS网站安全情况。

    安全评级(A+、A、A-...)、行业合规检测、证书信息查看、证书链信息以及补完、服务器套件信息、证书兼容性检测等。

    SSL证书工具

    安装部署SSL证书变得更方便。

    SSL证书内容查看、SSL证书格式转换、CSR在线生成、SSL私钥加解密、CAA检测等。

    SSL漏洞检测

    让服务器远离SSL证书漏洞侵扰

    TLS ROBOT漏洞检测、心血漏洞检测、FREAK Attack漏洞检测、SSL Poodle漏洞检测、CCS注入漏洞检测。

    作者:朱祁林 出处:http://zhuqil.cnblogs.com 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。  
  • 相关阅读:
    7.9 C++ STL算法
    7.8 C++容器适配器
    7.7 C++基本关联式容器
    Django项目静态文件加载失败问题
    Centos6.5安装mysql5.7详解
    使用Xshell上传下载文件
    linux中MySQL本地可以连接,远程连接不上问题
    Linux常用命令
    Linux环境安装python3
    python 字符串最长公共前缀
  • 原文地址:https://www.cnblogs.com/zhuqil/p/TestBO.html
Copyright © 2011-2022 走看看