zoukankan      html  css  js  c++  java
  • 不喜欢写测试的朋友看过来,与你分享写测试的经验 做一个爱写测试的程序员

    自从掌握了单元测试的要领之后,经常写测试,做测试,也非常喜欢做单元测试。我的文章《数据采集:完美下载淘宝Ip数据库 简单的程序节省60元人民币而不必购买数据库》中的代码,也是个测试方法,源代码在QQ群中公布过。

    现在把它公开给大家,分享这个Ip地址信息下载功能的测试代码:

    [TestMethod]
    public void IPLibraryTest()
     {
                string whole = "211.64.0-255.0-255";
                IPRange ipRange = new IPRange(whole);
                List<IPAddress> addresses = ipRange.GetAllIP() as List<IPAddress>;
                DataTable table = new DataTable("Ip");
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                string url = string.Empty, json = string.Empty;
                Parallel.ForEach(addresses, (address) =>
                    {
                         url = string.Format("http://ip.taobao.com/service/getIpInfo.php?ip={0}", address.ToString());
                         json = string.Empty;
                        try
                        {
                            json = Convert.ToString(NetworkHelper.PostRequest(url));
                        }
                        catch (Exception)
                        {
                                
                        }
                        Object obj2 = serializer.DeserializeObject(json);
                        if (string.IsNullOrWhiteSpace(json)||obj2 == null)
                            return;
    
                        Dictionary<String, Object> dictionary = (Dictionary<String, Object>)obj2;
    
                        foreach (KeyValuePair<string, object> valuePair in dictionary)
                        {
                            if (valuePair.Value.GetType() == typeof (Dictionary<string, object>))
                            {
                                Dictionary<String, Object> subdictionary = valuePair.Value as Dictionary<String, Object>;
                                lock (table)
                                {
                                    if (table.Columns.Count == 0)
                                    {
                                        foreach (KeyValuePair<string, object> pair in subdictionary)
                                        {
                                            table.Columns.Add(pair.Key, typeof (string));
                                        }
                                    }
    
                                    DataRow row = table.NewRow();
                                    foreach (KeyValuePair<string, object> pair in subdictionary)
                                    {
                                        row[pair.Key] = pair.Value;
                                    }
                                    table.Rows.Add(row);
                                }
                            }
                        }
                    });
     
                string databaseFile = @"H:DevelopmentSourceTestDatabase64IpLibrary.accdb";
                OleDbHelper accessHelper = new OleDbHelper(databaseFile);
                accessHelper.AppendData(table);
    }

    程序中的不合理的地方,欢迎批评指正。

    三个工具的组合 Visual Studio + Resharper + Visual Source Safe,经过几年的积累,累积了大量的测试代码。

    Visual Studio内置的MSTest本身好用,NUnit也可以,这是测试的基础工具,再配合Reshaprer的测试管理器,在方法前面点一个小按钮,即可以调试或是运行的方式开始测试,相当方便。最后,累积的测试代码,直接提交到源代码管理工具中,备以后查验。

    我们开发中经常遇到这样的情景,有一个小方法不知道是否正确,需要测试一下。不需要复杂的用户输入的功能,可以开一个控制台程序,执行测试,如用户输入复杂,则需要开一个Windows Forms程序。测试完成后,把可用的功能代码拷贝走,剩下的测试程序通常会扔掉。在没有学会MSTest之前,我经常这么做。等到以后发现有问题时,再回来来找当初的测试情景和代码,传递的参数数据,已经无从得知。

    经过这种痛苦之后,我开始尝试单元测试,把要测试的代码和数据都保存一个Test项目中,每个解决方案都跟一个测试项目,用于执行测试,保存测试参数:

    image

    经过若干年的积累,这里面积累了很多实用的代码。

    比如在做许可验证时,生成公匙和私匙,就下面二行代码,于是写成一个测试方法,保存在我的源代码服务器中

    [TestMethod]
    public void SolutionValidationTest()
    {
          string publickey = RSACryptionHelper.GeneratePublickKey(false);
          string privateKey = RSACryptionHelper.GeneratePublickKey(true);
    }

    这种代码库的积累,如果回忆起来,比查MSDN还快。

    再比如,我的许可证机制是以Signature Xml为基础的,下面的方法可以测试许可证文件,验证它的正确性。

    [TestMethod]
    public void SolutionLicenseValidationTest()
     {
                SolutionLicense license = SolutionLicense.ReadLicense();
                string licenseFile = @"H:DevelopmentBuildLicense.lic";
    
                StreamReader reader = new StreamReader(licenseFile, Encoding.UTF8, true);
    
                XmlTextReader xmlReader = new XmlTextReader(licenseFile);
                XmlDocument doc = new XmlDocument();
                doc.Load(xmlReader);
                doc.Load(reader);
    
                license = SolutionLicense.ReadLicense();
                license.VerifyLicense();
    }
     

    有时候真的很偷懒,不想写个GUI程序,就用这种方法来进行。调试过程中,如果有异常,MSTest会中断运行,显示异常的原因。用NUnit写的测试也一样的效果。有了Resharper的帮助,做代码的单元测试时,你完全像是在做功能测试一样,告诉VS我想运行一个方法,在方法名称前点击Run或是Debug即可。

    image

    行号左边的那个小按钮,对测试的运行和调试起到关键性的作用,极大的简化了测试代码的运行和检测。

    有时候,我并不想调用Assert去判断值的真或假,比如上面的生成许可证文件,我去硬盘里面看看,检查一下内容也可以判断,自动化的步骤是加一个Assert(true, File.Exist(fileName)) ,但是由决定权在你手里,能把代码测试好,功能调试好就可以收工回家。

     

    通俗的理解,单元测试的二个主要作用:

    1  保存API接口或是功能的调用方式和参数值,以留作改善或是问题查找的源头

    2  记录对新技术的学习,掌握情况,供快速参考。

    Lambda表达式代表一个匿名方法,如果调用这个方法,对它求值呢,参考下面的代码例子

    [TestMethod]
    public void TraceTestMethod()
    {
           Expression<Func<DateTime>> expr = () => DateTime.Now.AddDays(1);
           Func<DateTime> tomorrow = expr.Compile();
           Console.WriteLine(tomorrow());
            
    }

    看了这个例子后,肯清楚的解释了步骤,照葫芦化瓢,一下子就可以应用到工作中。

    再来看几个扩展方法的例子,看下面的代码,生成字节数

    [TestMethod]
    public void ByteTest()
    {
         var kb = 1.KB();
         var mb = 1.MB();
         var gb = 1.GB();
         var tb = 1.TB();
    }

    追综到源代码中,原来是这样的几个扩展方法:

    /// <summary> 
            /// Kilobytes 
            /// </summary> 
            /// <param name="value"></param> 
            /// <returns></returns> 
            public static int KB(this int value)
            {
                return value * 1024;
            }
    
            /// <summary> 
            /// Megabytes 
            /// </summary> 
            /// <param name="value"></param> 
            /// <returns></returns> 
            public static int MB(this int value)
            {
                return value.KB() * 1024;
            }
    
            /// <summary> 
            /// Gigabytes 
            /// </summary> 
            /// <param name="value"></param> 
            /// <returns></returns> 
            public static int GB(this int value)
            {
                return value.MB() * 1024;
            }
    
            /// <summary> 
            /// Terabytes 
            /// </summary> 
            /// <param name="value"></param> 
            /// <returns></returns> 
            public static long TB(this int value)
            {
                return (long)value.GB() * (long)1024;
            }

    测试代码是为自己而写,为自己掌握这项技术,熟悉这下技术,记的笔记。

    Visual Studio本身就是个很好的代码收藏工具,有最好的编辑器,调试器,再以一个源代码管理工具作为辅助,这就组合成一个很好的代码收藏工具。看了我这篇文章之后,你可能再也不想用代码收藏工具了。我鼓励你把它扔掉,把收藏的代码片段直接保存在一个测试项目中,坚持积累,积跬步而行千里路,庖丁解牛,游刃有余。

  • 相关阅读:
    tensorflow入门
    【CentOS】yum安装教训
    【转载】Linux的五个查找命令
    【git】本地git bash连接远程库github
    【python学习】字符串相关
    【Linux】单计算机安装PBS系统(Torque)与运维
    xshell上windows和linux互传文件命令
    【Linux】Linux命令行下多任务前后台切换
    【python】windows更改jupyter notebook(ipython)的默认打开工作路径
    【Introduction】R语言入门关键小结
  • 原文地址:https://www.cnblogs.com/JamesLi2015/p/3158036.html
Copyright © 2011-2022 走看看