单元测试的重要性

70 篇文章 1 订阅

单元测试的重要性 

序:这是一篇写给所有开发者的建议,虽然不包含技术成分,但比技术本身成为重要.
 

测试的必要性

 
只要你是写代码的,写的代码质量再高,也难免有bug,而单元测试可以有效地发现这些bug,提高你的代码质量,而如果是采取测试驱动开发的,更能影响到你对整个系统的设计,这样设计出来的系统的可测试性会大大提高.
 
很多公司的开发人员写完代码就提交了,有的可能会简单写个测试代码(而非单元测试)来检验下代码是否能正常工作,当调用者调用这些方法(函数或接口)时,经常会发现有问题,由于这代码可能不是他写的,找bug就浪费了时间,有的隐藏的bug甚至在线上系统中才发现.造成的损失和影响有时就会很严重.
 

单元测试的用法

 
一般来说只要你这个方法有人会调用,就应当写单元测试,在.net里一般就是指public标识的方法,如果想代码的质量非常好,就必须代码覆盖率高,如t果想图省事,正常的业t务流程一定要覆盖到.
 
当一个方法写完后(或某个类写完)后,就应写单元测试代码,验证完代码都能正常工作后再继续下一步.
 
当你修改数据库或代码后,应当运行所有的单元,如果有测试不通过,说明该修改有问题,就应该修复bug
 
当你对代码进行重构时,运行单元测试来验证修改没有问题更是非常有用的工具,而且非常有效率,因为在大的系统里,你修改的代码可能影响到的地方很多,没有单元测试的帮助你想很好的控制修改带来的影响很难.
 
如果你有自构建的工具,单元测试就应当加到里面,代码编译完后就运行单元测试代码,这样可以对提交的代码再做一次把关.
 
对某个方法写单元测试时应该覆盖到所有的逻辑,就是对方法里的判断,输出,异常等都要测试到,而且测试代码不要在db(有db操作的)留下垃圾,比如你测试一个update的方法,为了测试,你得先添加一个数据吧,再对这个数据修改,断言(判断)是否修改成功,最后你还得把这条添加用于测试的数据给清除掉.
 

不写单元测试的理由

 
有很多人不愿意,有的甚至不屑于写单元测试,认为浪费时间,看不到它的好处,如果你能认识到单元测试的用法中的几点,估计就不会这么想了,写单元测试在编码的时候确实会增加一些工作量,但带来的好处是提高了代码质量,而且写测试有时还可以帮你更好的理清思路,有时通过测试还会发现代码设计中的不足,更为主要的是对以后的代码修改维护带来效率上的提升.
 
所以说,如果一个代码系统没有单元测试,其质量也好不到哪去,没有写的赶紧写吧,用了你就知道它人价值所在.
 

vs2013架设单元测试环境

 
 

附录:vs(c#)的一段测试代码,基于nunit的

 
using System.Threading.Tasks;
using NUnit.Framework;
using BankRollService.Business.Implement;
using BankRollService.Dal.Implement;
using BankRollService.Dal.Interface;
using BankRollService.DTO.Balance;
using IntegrationTest.ResourceConfigs;
using Util.Table.Interface;

namespace IntegrationTest.MicroServices.Deal.BankRoll
{
    [TestFixture]
    public class BalanceBusinessTests
    {
        private BalanceBusiness _balanceBusiness;//被测对象
        
        private IBalanceTable _balanceTable;
        private IBankRollDatabase _database;

        /// <summary>
        /// 全局setup,不能使用async,使用wait
        /// </summary>
        [TestFixtureSetUp]
        public void TestFixtureSetUp()
        {
            CloudResourceConfig.InitCloudConfig();
            PrepaitData().Wait();
        }

        
        private async Task PrepaitData()
        {
            _balanceTable = new BalanceTable();
            _database=new BankRollDatabase(_balanceTable);
            _balanceBusiness = new BalanceBusiness(_balanceTable);
            
        }

        /// <summary>
        /// 每次测试setup,不能使用async
        /// </summary>
        [SetUp]
        public void SetUp()
        {
            _database.TruncateAllTablesAsync().Wait();

        }

        [Test]
        public async void Test_创建资金池_获取余额_修改_删除()
        {
        
            
            await _balanceBusiness.DeleteBalanceAsync(1);
            await _balanceBusiness.DeleteBalanceAsync(101);

            //id=1 用户
            //id=101 商铺
            var userModel = new BalanceCreate
            {
                Id=1,
                Total=10000,
            };
            var dtoUser = await _balanceBusiness.CreateBalance(userModel);
            //Console.WriteLine(list.total);
            Assert.AreEqual(dtoUser.Id, 1);

            var storeModel = new BalanceCreate
            {
                Id = 101,
                Total = 10000,
            };
            var dtoStore = await _balanceBusiness.CreateBalance(storeModel);
            //Console.WriteLine(list.total);
            Assert.AreEqual(dtoStore.Id, 101);

            var dtoUser2 = await _balanceBusiness.GetBalanceAsync(dtoUser.Id);
            Assert.AreEqual(dtoUser2.Total, 10000);

            var dtoStore2 = await _balanceBusiness.GetBalanceAsync(dtoStore.Id);
            Assert.AreEqual(dtoStore2.Total, 10000);

            var mod = new BalanceUpdate
            {
                Total=15000,
                WithDrawTotal=0
            };
            var dtoUpdate = await _balanceBusiness.UpdateBalanceAsync(dtoStore.Id,mod);
            Assert.AreEqual(dtoUpdate.Total, 15000);

            var result = await _balanceBusiness.DeleteBalanceAsync(dtoStore.Id);
            var dtoStore3 = await _balanceBusiness.GetBalanceAsync(dtoStore.Id);
            Assert.AreEqual(dtoStore3,null);

            //删除
            await _balanceBusiness.DeleteBalanceAsync(1);
            await _balanceBusiness.DeleteBalanceAsync(101);
        }}}

 
当然如果涉及到测试代码中用到其它层的代码,mock就会经常用到,如下的部分代码
using System.Collections.Generic;
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
......

namespace TL.IntegrationTest.MicroServices.Deal.Order
{
    [TestFixture]
    public class DeliveryOrderBusinessTests
    {
        private DeliveryOrderBusiness _deliveryOrderBusiness;//被测对象
        
        private Mock<ITransactionBusiness> _transactionBusinessMock;
        

        /// <summary>
        /// 全局setup,不能使用async,使用wait
        /// </summary>
        [TestFixtureSetUp]
        public void TestFixtureSetUp()
        {
            CloudResourceConfig.InitCloudConfig();
            PrepaitData().Wait();
        }


        private async Task PrepaitData()
        {
           ........
            _transactionBusinessMock = new Mock<ITransactionBusiness>();
            _deliveryOrderBusiness = new DeliveryOrderBusiness(_orderDatabase, _orderTable, _orderDetailTable,
                _orderRefundTable, _giftMoneyTable, _transactionBusinessMock.Object);
            _giftOrderBusiness = new GiftOrderBusiness(_orderDatabase, _giftOrderTable, _giftOrderDetailTable,
                _giftMoneyTable, _giftTable, _transactionBusinessMock.Object);

        }

        /// <summary>
        /// 每次测试setup,不能使用async
        /// </summary>
        [SetUp]
        public void SetUp()
        {
            orderDetail.Clear();
            orderDetail.Add(new OrderDetailCreate()
            {
                Amount = 100,
                Count = 1,
                DiscountMsg = "",
                Price = 100,
                ProductId = 1001,
                ProductLogoUrl = "",
                ProductName = "test1001",
            });

            Test_清空表_生成初始数据().Wait();

        }

        public async Task Test_清空表_生成初始数据()
        {
            ......
        }


        [Test]
        public async void Test_生成收货订单_需要支付_没使用礼金_等待发货()
        {
            var model = new OrderCreate()
            {
                Amount = 100,
                GiftMoney = 0,
                StoreId = 101,
                UserId = 1,
                Freight = 10,
                ReceiveOrderDetailCreates = orderDetail,
                ShippingAddress = "深圳市南山区特发信息港408"
            };
            var dto = await _deliveryOrderBusiness.CreateOrder(model);
            //Console.WriteLine(list.total);
            Assert.AreEqual(dto.UserId, 1);
            Assert.AreEqual(dto.OrderState, OrderState.已创建);
            var tsId = new DtoTransactionId()
            {
                Id = 20160226000000001,
            };
            _transactionBusinessMock.Setup(m => m.GetTransactionId()).ReturnsAsync(tsId);

            var payCerf = new DtoPaymentCertificate()
            {
                Certificate = "pay_testdsfsdfsdffortest"
            };
            _transactionBusinessMock.Setup(m => m.CreateOrderSpend(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<OrderSpendCreate>())).ReturnsAsync(payCerf);
            var pay = await _deliveryOrderBusiness.CreatePaymentCertificate(dto.Id.ToString(), PayChannel.alipay);
            Assert.AreNotEqual(pay, null);

            //支付成功后回调
            await _deliveryOrderBusiness.PaySuccess(dto.Id.ToString());

            dto = await _deliveryOrderBusiness.GetOrder(dto.Id.ToString());
            Assert.AreEqual(dto.OrderState, OrderState.等待卖家发货);

        }
    }
}
 
        [Ignore]
        [Test]
        public async Task TestQuery_in_polygon_query()
        {
            //特发 22.55591,113.9561
            var query = "desc:'人'&&filter=distance(lng,lat,\"113.9561\",\"22.55591\")<1&&sort=+distance(lng,lat,\"113.9561\",\"22.55591\")";
            //var query = "desc:'人'";
            var result = await _ops.Search<tlUser>("tluser001", query, 0, 20);

            Assert.GreaterOrEqual(result.total, 1);

        }

        [Test]
        [TestCase("zTest:A", "zTest:B", -1, -2, -11, -12)]
        public async void RelationGroupStartStopAsync(string pa, string pb, int idA, int idA2, int idB, int idB2)
        {
            //_friendUtil.
        }

        [Test]
        [ExpectedException(typeof(UtilCrashException))]
        public async void Test获取表的记录总数_错误表名_抛异常()
        {
            var n1 = await _rds.GetCountAsync("test" + "dfsdfsd",null);
        }

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值