我们要求单元测试文件需要与项目构建中的源文件分开。
这意味着我们不能这样做来测试源文件。
unit_testing_file.c
#include <source_file.c>
//testcases for testing source_file.c
...
我在这里看到的两个问题只是:
关于链接(测试文件和源文件在编译后变成1个目标文件而不是2个)
两个文件中的变量范围现在变得相同。
导致在测试文件中包含源文件可能是一种不好的做法。但它并没有真正说服我。
现场背后是否还有另外一个原因,我们不能在测试文件中包含源文件?
答案 0 :(得分:1)
这在测试C时非常常见。它以这种方式完成的原因是它允许你通过&#34;穿过&#34;一些C(相当弱)的抽象和数据隐藏。
例如,考虑一个具有static
变量的单元,其值需要在测试中检查。您无法从其他翻译单元(即C文件)访问该文件,因为它static
,如果单元(模块)没有变量的获取器,则测试无法检查。
通过{{1}将测试中的C文件放入测试代码,它们编译为相同的翻译单元,您甚至可以访问#include
个变量。
答案 1 :(得分:0)
要求的原因可以简单到“因为老板这么说” - 你必须问那个给你要求的人。
AFAIK,没有技术理由不执行#include <source.c>
事情。相反,这是C中最难看的方式,可以访问通常不受限制的东西,比如静态函数和变量;如你所说,使用#include
,你与source.c文件中的范围相同。
至于你提到的目标文件成为一个,我不明白这是多么重要。无论如何,人们可能会认为这几乎就是链接的定义。
如果您真正想要的是找借口来对抗这个要求(这就是我要做的!),我会尝试对source.c文件中的静态函数进行单元测试,并将其显示为一个例子,如果不使用#include
,会有多么丑陋。
为什么我会反对这个要求,或者至少会质疑它?因为如上所述,替代方案甚至更加丑陋:
#ifdefs
删除帮助程序代码=使生产源复杂化,违反了一些编码指南#define static
=是的,没错,我已经看到单元测试框架这样做只是为了消除static
。可怕的,搞乱范围,改变静态变量的行为!答案 2 :(得分:0)
如何做到这一点是整体设计决策。
显然,保持测试独立于实际代码是有好处的。实际代码与测试之间缺乏紧密耦合将是主要原因;绝不允许测试中的更改影响实际代码。任何关键任务计划都有要求将测试分开用于此目的。
另一个理念是在开发代码的同时始终开发测试(流行语:“TDD”),因为所有代码都需要进行测试,并且当您拥有所有详细信息时,您最有能力编写相关测试代码的功能仍在你的脑海中,即在开发过程中。一些设计将测试作为正在开发的代码模块的一部分。这种哲学最有力的论据是,测试本身的质量通常会变得更好,并且你隐含地保证代码总是经过测试。
虽然让开发代码的人编写测试是有好处的 - 为了使它们最相关,但也有一个缺点:作为程序员,你往往会对你自己的代码中出现的明显错误视而不见。因此,让另一个拥有不同观点的人看代码是一个非常好的主意。同样,让另一个人编写测试可能是明智的,以验证程序是否遵循规范。
至于你的具体情况,有一个初学者级的程序设计规则如下:如果你发现自己#include
:在你的程序中的任何地方找到一个C文件,你的程序设计基本上是有缺陷的。当需要这样做时,它几乎总是意味着你的整个程序形状非常糟糕,需要从头开始重写。
现在,测试是另一回事。在测试期间,在生产代码中被视为100%不良做法可能是正常的。为了测试,您应该保持内部翻译单元内部的测试。这些测试可能/应该在生产发布后删除。根据编码标准的说法,编译器开关可能就足够了。如果不允许生产代码包含任何测试,则只需删除该代码即可。 (您可以在版本控制系统中保留该文件的两个版本。将测试版本放在自己的“分支”中。
如果测试是“黑盒子”测试,就像你只测试翻译单元的界面一样,那么就根本不需要访问内部。
答案 3 :(得分:0)
不将.c源包含在测试源中的一个原因是您不在生产代码中执行此操作 - 将其编译到自己的编译单元并链接它以便使用它。您的测试应该像任何其他&#34;客户&#34;并在要测试的编译单元中链接。
通过充当另一个客户,测试可以使用相同的编译单元暴露生产代码也可能遇到的问题。
以其他方式执行此操作,包括源代码,&#34;污染&#34;您的代码与您的测试代码 - 混合到同一个编译单元 - 它实际上可以掩盖问题。