1

我在对我的程序进行单元测试时遇到了问题。问题很简单,但我不确定为什么这不起作用。

1 -> 我构建了我的所有程序
2 -> 我构建了我的 unitTest
3 -> 测试正在运行。

当它不是从数据段获取全局数据时,一切都很好。似乎该变量未初始化/或未找到。所以当然我所有的测试都错了。

我的问题是:构建一个可执行文件,然后在上面运行测试是完全错误的吗?还是我必须同时编译所有代码+单元测试,然后运行它?还是只是缺少 SenTesting 框架?

我忘了提到这是一个 C++ const 字符串。不知道这是否会改变一些东西。

*编辑***

我的假设是错误的,但我仍然不明白超越的魔力!似乎是一个 C++ 魔法 hoydi hoo?

char cstring[] = "***";
std::string cppString = "***";
NSString* nstring = @"***";

- (void)testSync{
    STAssertNotNil(nstring, nil); // fine
    STAssertNotNil((id)strlen(bbb), nil); // fine
    STAssertNotNil((id)cppString.size(), nil); // failed
}

编辑 2 **

实际上,这部分代码没有初始化 C++ 是正常的。如果我对我的可执行文件执行 nm,我的 C 和 Obj-C 全局似乎被放入了 dataSegment。我以为我的 C++ 字符串是同样的情况,但它实际上被放入了 bss 段。这意味着它未初始化。事实是 C++ 编译器做了一些魔术,并且 C++ 字符串在 main() 调用之后被初始化,并且就像它进入 dataSegment 一样。

我不知道 testSuit 没有 main() 调用,所以 C++ 对象永远不会被初始化。有一些技术可以在 testSuit 之前调用 .ctor。但我懒得解释,这是某种话题。我刚刚用一个简单的 char 数组替换了我的 C++ 字符串,它工作得很好,因为我的值现在是 POD。

顺便说一句,如果它们只是只读的,那么全局变量中就没有魔鬼。;)

4

1 回答 1

0

好的,我可以在这里看到一些错误。

首先,这段代码在我的环境(Xcode 5)上给出了错误,并且有充分的理由(启用了 ARC)。我不知道你是如何编译的。原因是您将整数(或长整数)转换为对象,这将导致许多错误,因为它通常是无效操作。所以,真正的问题不是第三个“断言”为什么失败,而是第二个为什么成功。

至于你问题的第二部分,我不得不承认我并不完全理解你的问题,你可能需要更彻底地解释它。

通常,单元测试是测试代码的特定部分。因此,您通常不会对实际的最终可执行文件执行测试(我相信这不称为单元测试),也不必“同时编译所有 c++ 代码 + 单元测试”。

由于您使用的是 Xcode,我会给您一些指示。

  • 编写您的应用程序(或至少其中的一部分),并找到您想要对其执行单元测试的方面/功能/对象。
  • 在单独的文件中,编写单元测试来实例化这些对象并测试它们的方法,调用它们并比较输入和输出。
  • 您的应用程序中应该有第二个目标,它将仅编译单元测试源代码和相关的主程序代码。
  • 构建这个目标,或者按 command-U,它会报告成功和失败。

因此,您需要分离您的源代码并隔离您的类/方法,以使它们像这样可测试。这需要您对应用程序进行良好的架构和设计,并且您可能需要在灵活性上做出一些妥协(这由您决定)。哦,我相信在可测试的代码中,出于各种原因,您通常应该避免使用全局变量。全局变量有时很有帮助,但它们通常会使单元测试变得非常困难,(如果滥用可能会导致意大利面条代码,但这是一个完全不同的故事)

我希望我能有所帮助,即使没有完全理解你帖子的第二部分。

于 2013-10-15T10:42:27.187 回答