我想说使用反射来进行简单的单元测试有很多正当的理由。引用https://github.com/kbilsted/StatePrinter
手动单元测试的问题
这很费力。
当我一遍又一遍地键入和重新键入时:Assert.This、Assert.That、……不禁想知道为什么计算机不能为我自动执行这些操作。所有这些不必要的打字都需要时间并消耗我的精力。
使用 Stateprinter 时,只要预期值和实际值不匹配,就会为您生成断言。
代码和测试不同步
当代码发生更改时,例如通过向类添加字段,您需要在某些测试中添加断言。但是,找到位置是一个完全手动的过程。在没有人全面了解所有类的大型项目中,所需的更改并未在所有应有的地方进行。
当将代码从一个分支合并到另一个分支时,也会出现类似的情况。假设您将错误修复或功能从发布分支合并到开发分支,我一遍又一遍地观察到代码被合并,所有测试都运行,然后合并被提交。人们忘记重新访问并仔细检查整个测试套件,以确定开发分支上存在测试,而不是发生合并的分支上存在测试,并相应地调整它们。
使用 Stateprinter 时,比较对象图而不是单个字段。因此,当创建一个新字段时,所有相关测试都会失败。您可以将打印调整到特定字段,但您失去了自动检测图表变化的能力。
可读性差我
您在测试类、测试方法的良好命名和测试元素的标准命名方面取得了长足的进步。但是,没有任何命名约定可以弥补断言造成的视觉混乱。当使用索引从列表或字典中挑选元素时,会更加混乱。在将它与 for、foreach 循环或 LINQ 表达式结合使用时,不要让我开始。
使用 StatePrinter 时,比较对象图而不是单个字段。因此,测试中不需要逻辑来挑选数据。
可读性差二
当我阅读如下测试时。想想这里真正重要的是什么
Assert.IsNotNull(result, "result");
Assert.IsNotNull(result.VersionData, "Version data");
CollectionAssert.IsNotEmpty(result.VersionData)
var adjustmentAccountsInfoData = result.VersionData[0].AdjustmentAccountsInfo;
Assert.IsFalse(adjustmentAccountsInfoData.IsContractAssociatedWithAScheme);
Assert.AreEqual(RiskGroupStatus.High, adjustmentAccountsInfoData.Status);
Assert.That(adjustmentAccountsInfoData.RiskGroupModel, Is.EqualTo(RiskGroupModel.Flexible));
Assert.AreEqual("b", adjustmentAccountsInfoData.PriceModel);
Assert.IsTrue(adjustmentAccountsInfoData.IsManual);
当我们真正想要表达的是
adjustmentAccountsInfoData.IsContractAssociatedWithAScheme = false
adjustmentAccountsInfoData.Status = RiskGroupStatus.High
adjustmentAccountsInfoData.RiskGroupModel = RiskGroupModel.Flexible
adjustmentAccountsInfoData.PriceModel = "b"
adjustmentAccountsInfoData.IsManual = true
说服力差
当业务对象的字段数量增加时,测试的可信度则相反。是否涵盖所有领域?字段是否被多次错误地比较?还是针对错误的领域?当您必须对一个对象执行 25 次断言时,您就知道痛苦,并且煞费苦心地确保对照正确的字段检查正确的字段。然后审阅者必须进行同样的练习。为什么这不是自动化的?
使用 StatePrinter 时,比较对象图而不是单个字段。您知道所有字段都被覆盖,因为所有字段都已打印。