“在强签名的程序集上运行单元测试失败”问题调查

问题背景
最初的时候程序集没有签名,单元测试都可以正常运行,并且可以得到代码覆盖率。程序集加上强名称签名,密钥文件有密码保护,由此导致所有单元测试全部运行失败。错误信息如下
Strong name verification failed for the instrumented assembly 'SignedLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1696e096eba75082'. Please ensure that the right key file for re-signing after instrumentation is specified in the test run configuration.  (强名称验证失败, 请确信为重新签名指定了正确的密钥文件)

调查过程
首先根据错误信息在MSDN上找到了相关的网页,给出了失败原因和对策。
http://msdn2.microsoft.com/zh-cn/library/ms243141(VS.80).aspx
我分别使用了里面提供的两个办法
1. 在测试配置里指定密钥文件,从而可以使得VS2005可以对程序集进行重新签名. 结果:失败。因为MSDN中已经明确说明,有密码保护的密钥文件通过这种方式进行重签名时会失败。
2. 在测试安装脚本里添加禁用签名验证的命令,在测试清理脚本里添加启用签名验证的命令。这样可以跳过签名验证,从而不必重新签名,也就不会失败。结果也是失败的。原因未知。
于是,当时下了个结论:禁用签名的命令不起作用。VS2005一定要对签过名的程序集进行签名验证,验证后一定要再签名,再签名时由于密钥文件的密码保护导致失败。

进一步调查
后来考虑, 如果这个结论成立的话,强名称签名的程序集就无论如何也不能进行单元测试了,这显然是不合理的。并且,在试验上面两个方法时,偶尔也会成功。
于是反复测试,偶然的机会发现,第二个方法里,如果只在安装脚本里禁用,不在清理脚本中启用,则除第一次测试失败以外,第二次和以后的各次测试都可以成功。由此推断,在清理脚本里不去启用签名验证的情况下,虽然安装脚本中的禁用签名命令在第一次测试时就运行了,但在第二次测试时才起作用,说明禁用签名命令执行的时机还不够早。
为了验证这个想法,我把安装脚本和清理脚本都清空,而是在测试之前在控制台上执行禁用签名验证的命令,再去启动测试,测试结束后,再到控制台上启用签名验证。结果,全部成功,并且反复执行都成功。

回看
再次仔细阅读MSDN,发现最初的理解有偏差,并且结论下的比较草率。
1. 单元测试的整个过程有哪些步骤,进行哪些动作,做哪些判断,哪个命令有哪些影响,这一系列问题最终是画了个流程图才搞清楚。所以,要善用各种图
2. 最初调查的结论下的过于草率。没把造成一个结果所有可能的原因都考虑进去。看一个行为是否成功,要确保很多方面。比如,它是否真的执行了,执行的上下文、环境、参数是否正确,执行的顺序是否正确,等等。并且还应该用正确的方法去验证以上各条。在调查这个问题时,用到的方法是把执行结果写文件,和在关注的时间点写文件.

你可能感兴趣的:(File,单元测试,测试,脚本,assembly)