![]() |
1
2
这是那些嘲弄一切的概念被推翻的领域之一。当然,单独测试每个方法是一种“更好”的方法,但是将所有方法的测试版本与将代码指向测试数据库(如有必要,在每次测试运行开始时重置)的工作进行比较。 这就是我在代码中使用的方法,它在组件之间有很多复杂的交互,并且工作得很好。由于每个测试将运行更多的代码,因此您更可能需要使用调试器单步执行,以准确地找到出错的地方,但是您可以获得单元测试的主要好处(知道出错的地方),而不需要付出大量的额外努力。 |
![]() |
2
18
这种类型的(尝试的)单元测试,通过一个公共方法覆盖整个庞大的代码库,总是让我想起外科医生、牙医或妇科医生,他们通过小开口执行复杂的操作。可能,但不容易。 封装 在面向对象的设计中是一个古老的概念,但有些人认为它是一个极端,以致于测试性受到了影响。还有一个OO原则叫做 Open/Closed Principle 这更符合可测试性。封装仍然是有价值的,但不会以牺牲可扩展性为代价——事实上, testability is really just another word for the Open/Closed Principle . 我不是说你应该公开你的私有方法,但我要说的是你应该考虑将你的应用程序重构成可组合的部分——许多小类协作而不是一个大类 Transaction Script . 你可能认为这样做对于一个单一供应商的解决方案没有多大意义,但现在你正在受苦,这是一条出路。 当您在一个复杂的API中拆分一个方法时,通常会发生的情况是您还获得了许多额外的灵活性。最初作为一次性项目的东西可能会变成一个可重用的库。 下面是关于如何为手头的问题执行重构的一些想法:每个ETL应用程序都必须执行 至少 这三个步骤:
(因此,名称
ETL
)作为重构的开始,这至少为我们提供了三个具有不同职责的类:
现在放大这三个领域中的每一个,看看在哪里你可以更进一步地划分职责。
如果您有许多源数据和目标数据的“行”,则可以在映射器中为每个逻辑“行”等进一步拆分这些数据。 它不需要变得杂乱无章,另外的好处(除了自动化测试)是对象模型现在变得更加灵活了。如果你需要写 另一个 ETL应用程序涉及双方中的一方,您已经阅读过至少三分之一的代码编写。 |
![]() |
3
7
我想到的是 重构 : 重构并不意味着你将你的3.5K位置划分为 n 部分。我不建议把你80种方法中的一些公开或者像这样的东西。这更像是垂直分割代码:
因此,您不必编写覆盖整个3.5K loc的单元测试。在一个测试中只包含其中的一小部分,您将有许多相互独立的小测试。 编辑 这是一个不错的 list of refactoring patterns . 其中一个很好地显示了我的意图: Decompose Conditional . 在这个例子中,某些表达式被分解为方法。不仅使代码更容易阅读,而且您还获得了对这些方法进行单元测试的机会。 更好的是,您可以将此模式提升到更高的层次,并将这些表达式、算法、值等分解出来,不仅限于方法,还包括它们自己的类。 |
![]() |
4
6
您最初应该拥有的是集成测试。这些将测试函数是否按预期执行,您可以点击实际的数据库。 一旦你有了这个savety网络,你就可以开始重构代码,使其更易于维护,并引入单元测试。 正如serbrech所提到的,有效地使用遗留代码将帮助您永不停息,我强烈建议您甚至为绿地项目阅读它。 http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 我要问的主要问题是代码多久更改一次?如果不经常,那么尝试引入单元测试真的值得吗?如果经常更改,那么我肯定会考虑清理一下。 |
![]() |
5
4
听起来集成测试可能足够了。尤其是当这些导出例程完成后不会更改,或者只在有限的时间内使用时。只需获取一些带有变体的示例输入数据,并进行测试,以验证最终结果是否如预期的那样。 测试的一个问题是您必须创建的假数据量。您可以通过创建共享夹具来减少这一点。( http://xunitpatterns.com/Shared%20Fixture.html )对于单元测试,fixture可能是要导出的业务对象的内存表示,或者对于集成测试,它可能是用已知数据初始化的实际数据库。重点是,无论您如何生成共享的fixture,在每个测试中都是相同的,因此创建新的测试只是对现有fixture做一些小的调整以触发您想要测试的代码的问题。 那么应该使用集成测试吗?一个障碍是如何设置共享夹具。如果可以在某个地方复制数据库,那么可以使用dbunit之类的工具来准备共享的fixture。将代码分解为片段(导入、转换、导出)可能更容易。然后使用基于dbunit的测试来测试导入和导出,并使用常规的单元测试来验证转换步骤。如果这样做,就不需要dbunit为转换步骤设置共享设备。如果您可以将代码分为3个步骤(提取、转换、导出),那么至少您可以将测试工作集中在稍后可能出现错误或更改的部分。 |
![]() |
6
3
我和C没有任何关系,但我知道你可以在这里试试。如果您将代码拆分一点,那么您将注意到您所拥有的基本上是对序列执行的操作链。 第一个获得当前日期的付款:
第二个无条件地处理结果
第三个执行条件处理:
现在,您可以使这些阶段更通用(对不起,伪代码,我不知道C):
如您所见,现在您已经有了一组未连接的阶段,它们可以分别测试,然后以任意顺序连接在一起。这种连接或成分也可以单独测试。等等(例如-你可以选择测试什么) |
![]() |
7
2
我想托马兹·齐林斯基有一个答案。但是如果你说你有3500行程序代码,那么问题就更大了。 将它切割成更多的函数并不能帮助您测试它。但是,这是识别可以进一步提取到另一个类中的职责的第一步(如果您对这些方法有好的名称,在某些情况下这是显而易见的)。 我想有了这样一个类,您就有了一个令人难以置信的依赖项列表,可以处理这些依赖项,只是为了能够将这个类声明为一个测试。然后很难在测试中创建该类的实例… 迈克尔·费瑟的《处理遗留代码》一书很好地回答了这些问题。 能够很好地测试代码的第一个目标应该是识别类的角色并将其分成更小的类。当然,这很容易说,具有讽刺意味的是,没有测试来保证修改的安全性是有风险的…… 您说该类中只有一个公共方法。这样可以简化重构,因为您不必担心所有私有方法的用户。封装是很好的,但是如果你在这个类中有那么多私有的东西,这可能意味着它不属于这里,你应该从那个怪物中提取不同的类,这样你最终可以测试。一块一块地,设计应该看起来更干净,并且您将能够测试更多的代码。 你最好的朋友,如果你开始这将是一个重构工具,那么它将帮助你在提取类和方法时不要破坏逻辑。 迈克尔·费瑟的书似乎又是你必须读的书:) http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052 增加的例子: 这个例子来自迈克尔·费瑟的书,很好地说明了你的问题,我认为:
很明显,把nextterm和hasmore的方法公开是没有意义的。没有人应该看到这些方法,我们移动到下一项的方式绝对是类内部的。那么如何测试这个逻辑呢?? 如果你看到这是一个单独的责任,并提取一个类,比如记号赋予器。这个方法将突然在这个新类中公开!因为这就是它的目的。然后很容易测试这种行为… 因此,如果您将它应用到您的巨大代码块上,并将其片段提取到职责较少的其他类中,并且在将这些方法公开的情况下,您也可以轻松地测试它们。 你说你正在访问大约40个不同的表来映射它们。为什么不为映射的每个部分将其分解为类呢? 我读不懂的代码有点难以解释。你可能还有其他问题阻止你这样做,但这是我最好的尝试。 希望这有帮助 祝你好运: |
![]() |
8
2
我真的很难接受你有多个3.5 klines的数据导出函数 根本没有共同的功能 他们之间。如果事实上是这样,那么单元测试可能不是您需要在这里看到的。如果每个导出模块实际上只做一件事,而且本质上是不可分割的,那么可能需要一个快照比较、数据驱动的集成测试套件。 如果有一些共同的功能位,那么提取它们中的每一个(作为单独的类),并分别测试它们。这些小助手类自然会有不同的公共接口,这将减少无法测试的私有API的问题。 对于实际的输出格式,您没有给出任何细节,但是如果它们通常是表格、固定宽度或分隔文本,那么您至少应该能够将导出器拆分为结构和格式代码。我的意思是,与上面的示例代码不同,您的示例代码如下:
这个
另一种分割方法是将数据提取和格式化彼此分离。编写代码,将各个数据库中的所有记录提取到一个中间表示中,这是一组所需的表示,然后编写相对简单的筛选例程,将每个供应商的uber格式转换为所需的格式。 在进一步考虑之后,我意识到您已经将它标识为ETL应用程序,但是您的示例似乎将这三个步骤结合在一起。这意味着第一步是将事物拆分,以便先提取所有数据,然后翻译,然后存储。您当然可以单独测试这些步骤。 |
![]() |
9
1
我维护一些与您描述的类似的报告,但它们没有您描述的那么多,数据库表也更少。我使用了一个3倍的策略,可以很好地扩展到对您有用的程度:
|
![]() |
10
0
你查过了吗 Moq? 从网站引用:
|
![]() |
Lorn · 查找特定字符并将记录更改为null 6 年前 |
![]() |
TULSI · 如何进行高层设计文档ETL 6 年前 |
|
Galen · 当我运行intellij idea的Kettle 8.0源代码时,我得到了以下错误:log4j:错误无法解析文件[插件/kettle5-log4j-plugin/log4j.xml] 6 年前 |
![]() |
Rachel · 分配10484320字节时缓冲区失败 6 年前 |
![]() |
jValls · XML搜索字符串XPath查询talend 6 年前 |
![]() |
vaa · Pentaho釜组by与类型concatenate产生重复 7 年前 |