从命令行运行单元测试时SSL连接有问题

14

目标

我们的目标是在持续集成环境 (Jenkins) 中执行单元测试。

(我认为每个问题都需要说明自己究竟想要实现什么。也许问题实际上可以用非常不同的方式解决)

更新:更多关于“为什么要这样做?”

首先,我们正在与特定的、自行开发的硬件进行通信。我希望持续 集成 测试告诉我是否有人改变了箱子的行为而没有告诉所有开发人员(是的,是的,我知道,这样的事情 从来没有 发生过...)。

第二,我们的一些(但不是全部)连接使用默认情况下无效的证书,因此我们有代码来检查证书的有效性(SecTrustEvaluate 等)。当然理想情况下,我们的测试也应该测试这段代码。但那似乎要求太多了。

第三:好吧,如果我可以得到真正的东西,为什么要模拟任何东西呢?IDE 对此没有问题,为什么命令行会有问题。

如果我想要可预测性,我会在所有测试中返回 YES ;)(我也 看到过人们这样做)。不,我想知道代码是否真正适用于我们的设备。这是一种扭曲的欲望吗?

目前已解决的问题

从命令行运行测试似乎很简单,但...

xcodebuild -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO clean test

结果会导致一个丑陋的错误:

unsupported build action 'test'

所以我在网上搜索并找到了这篇文章关于使用命令行运行OCUnit测试

我按照所有步骤操作,现在可以像这样从命令行运行我的测试:

xcodebuild -scheme CITests -sdk iphonesimulator TEST_AFTER_BUILD=YES ONLY_ACTIVE_ARCH=NO clean build

未解决的问题

然而,现在任何连接到SSL服务器的NSURLConnection都将失败,因为“此服务器的证书无效”。我听说过从命令行运行测试时出现钥匙串问题,但这可能是真的吗?所有SSL连接都被拒绝了吗?

复现步骤

获取示例:https://github.com/below/SSLTestDemo。打开它,并使用Xcode自带的Test ⌘U命令运行示例测试。测试应该成功。

现在在命令行上运行测试:

xcodebuild -scheme CITests -sdk iphonesimulator TEST_AFTER_BUILD=YES ONLY_ACTIVE_ARCH=NO clean build

由于“此服务器的证书无效”错误,测试失败。

有什么指针吗?

  • 我做错了吗?
  • 这是真正的 bug 吗?
  • 如果是,有解决方法吗?

任何意见都会受到赞赏!


1
为什么要进行联网单元测试?通常情况下,我们会模拟这些操作以获得更可预测的结果并消除外部依赖。 - Pfitz
请查看我上面的补充。 - below
回答你的问题,“为什么要模拟当你可以使用真实东西”: 你想消除变量。如果你在单元测试中真正连接到设备,测试失败可能会出现很多其他原因,而不仅仅是代码提交。比如设备关机、未连接到网络等。并不是说这些测试没有价值,但它们并不是单元测试。 - thekbb
好的。这些是集成测试,这正是我们想要做的。 - below
1
当作为单元测试运行时,您可能会遇到SSL主机检查问题。请参阅 http://quellish.tumblr.com/post/33284931593/ssl-connections-from-an-ocunit-test-failing - quellish
2个回答

2

好的,我最终在Jenkins测试时没有检查证书。

由于在应用程序中禁止此类检查的代码很危险 - 毕竟,在您出货之前,它可能不会被删除 - 因此,您必须设置环境变量和编译器标志来激活它 …

附言:

苹果认为这是一个错误,rdar://problem/10406441


0

我在XCode中遇到了SSL连接问题(使用XCode 4.5)

我的解决办法是在我的单元测试setUp中关闭HTTPS证书检查:

- (void)setUp
{
    // Set-up code here.
    [super setUp];

    NSURL *URL = [NSURL URLWithString:<#Your SSL Address#>];

    [NSURLRequest.class performSelector:NSSelectorFromString(@"setAllowsAnyHTTPSCertificate:forHost:")
                             withObject:NSNull.null  // Just need to pass non-nil here to appear as a BOOL YES, using the NSNull.null singleton is pretty safe
                             withObject:[URL host]];
}

我所调用的奇怪格式是因为这是一个私有方法,它拒绝使用最新的工具链进行编译。由于这仅在单元测试目标中使用,因此不会影响生产代码,因此安全免受攻击、错误和苹果应用商店批准。个人经验可能有所不同。


你可以使用类扩展来允许从测试内部访问该方法。请参考我的先前评论中的示例。 - quellish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接