zoukankan      html  css  js  c++  java
  • 初次使用单元测试后的体会

          我们搞开发的往往觉得自己写的代码没问题,用不着测试,以前,我也这么认为,觉得测试浪费时间,也就没仔细研究过测试。

          最近,闲来想试试单元测试,结合之前的编程经验,发现,单元测试至少是保证软件质量的最佳方式之一。一波一波程序员开发、维护一个产品,程序员之间的差别太大了,就像“明显没有错误”和“没有明显错误”的区别,怎么来保证产品在不断迭代中的质量,保留里面正确的部分,去掉bug呢?架构设计里面讲究面向接口,单元测试就能起到接口的作用。

          通过单元测试的类,它的行为是符合当初单元设计的目标的。只要编写单元测试时,从多方面检验类的行为,就能确保在这样的情景下,类是符合设计的。在Vistual Studio中,最简单的单元测试就是使用本身自带的功能(不需要从网上找NUnit的程序集,直接在项目上引用"Microsoft.VisualStudio.QualityTools.UnitTestFramework"程序集就ok了)。还有另外一个好处,是方便调试。单元测试项目可以在测试运行时,对被测试类下断点,非常节约调试时间。

          我是这么做的,单元测试的代码放到独立的项目中去,引用要测试的项目,在被测试项目中添加Assembly特性如下:

    [assembly: InternalsVisibleTo("Projky.UnitTests")]

    这样,单元测试就能对被测试项目中internal修饰符的类可见,又不破坏程序集的可见性。

         举一个简单的需求,要将如“30d9132169211a45”或者“30-D9-13-21-69-21-1A-45”或者“30 D9 13 21 69 21 1A 45”这样的16进制字符串转换为Byte[]数组。设计了一个ByteString的类来实现需求。

    internal class ByteString {
            public static Byte[] ConverterToBytes(string value) {
                if (value.IndexOf("-") > -1) {
                    value = value.Replace("-", "");
                } else if (value.IndexOf(" ") > -1) {
                    value = value.Replace(" ", "");
                }
    
                Debug.Assert(value.Length % 2 == 0, "Invalid byte string length.");
    
                List<Byte> list = new List<Byte>(value.Length / 2);
    
                for (int i = 0; i < value.Length; i += 2) {
                    int bHi = GetInteger(value[i]);
                    int bLow = GetInteger(value[i + 1]);
                    Byte temp = (Byte)(bHi << 4 | bLow);
                    list.Add(temp);
                }
                return list.ToArray();
            }
    
            static int GetInteger(char ch) {
                if (Char.IsDigit(ch)) { 
                    return ch - '0';
                }
                int value = 10;
    
                switch (ch) { 
                    case 'a':
                    case 'A':
                     value = 10;
                     break;
                    case 'b':
                    case 'B':
                     value = 11;
                     break;
                    case 'c':
                    case 'C':
                     value = 12;
                     break;
                    case 'd':
                    case 'D':
                     value = 13;
                     break;
                    case 'e':
                    case 'E':
                     value = 14;
                     break;
                    case 'f':
                    case 'F':
                     value = 15;
                     break;
                    default:
                     throw new NotSupportedException(ch.ToString() + " is not valid char.");
                }
                return value;
            }
        }

          那么,简单验证该类的行为(接口)可以编写下面的测试类:

    [TestClass]
        public class ByteStringTest {
            [TestMethod]
            public void ConverterToBytes() {
                string input = "30d9132169211a45";
                Byte[] bytes = ByteString.ConverterToBytes(input);
                Assert.IsTrue(bytes.Length == input.Length / 2);
                Assert.IsTrue(bytes[0] == 0x30);
                Assert.IsTrue(bytes[1] == 0xd9);
                Assert.IsTrue(bytes[2] == 0x13);
                Assert.IsTrue(bytes[3] == 0x21);
                Assert.IsTrue(bytes[4] == 0x69);
                Assert.IsTrue(bytes[5] == 0x21);
                Assert.IsTrue(bytes[6] == 0x1a);
                Assert.IsTrue(bytes[7] == 0x45);
    
                input = "30-D9-13-21-69-21-1A-45";
                bytes = ByteString.ConverterToBytes(input);
                Assert.IsTrue(bytes.Length == 8);
                Assert.IsTrue(bytes[0] == 0x30);
                Assert.IsTrue(bytes[1] == 0xd9);
                Assert.IsTrue(bytes[2] == 0x13);
                Assert.IsTrue(bytes[3] == 0x21);
                Assert.IsTrue(bytes[4] == 0x69);
                Assert.IsTrue(bytes[5] == 0x21);
                Assert.IsTrue(bytes[6] == 0x1a);
                Assert.IsTrue(bytes[7] == 0x45);
    
                input = "30 D9 13 21 69 21 1A 45";
                bytes = ByteString.ConverterToBytes(input);
                Assert.IsTrue(bytes.Length == 8);
                Assert.IsTrue(bytes[0] == 0x30);
                Assert.IsTrue(bytes[1] == 0xd9);
                Assert.IsTrue(bytes[2] == 0x13);
                Assert.IsTrue(bytes[3] == 0x21);
                Assert.IsTrue(bytes[4] == 0x69);
                Assert.IsTrue(bytes[5] == 0x21);
                Assert.IsTrue(bytes[6] == 0x1a);
                Assert.IsTrue(bytes[7] == 0x45);
            }
        }

    如果单元测试运行失败,例如Assert.IsTrue()方法中,参数为False,则在VS中会抛异常,这样,就知道哪里不正确了。

    注意用[TestClass]标记作为单元测试承载的类,是public可见性,而里面单个的独立测试方法,则采用[TestMethod]标记,同样是public可见性。

    在Visual Studio里面还有一个技巧,按Ctrl + R,A可以自动运行单元测试项目。如果被测试类有断点的话,测试到该位置时,也会断下来。

         

  • 相关阅读:
    centos networkmanager 和 network配置冲突
    Struts ajax json重新整理
    Struts2 ajax json小例子
    (转)json-lib 的maven dependency
    Struts2文件下载
    jQuery自定义滚动条插件mCustomScrollbar
    Struts2自定义拦截器
    Spring的自动装配在session监听器失效
    mysql 分组+排序+限定
    mysql触发器
  • 原文地址:https://www.cnblogs.com/ProJKY/p/unittests.html
Copyright © 2011-2022 走看看