如何测试一个给定的功能代码单元(c#)是否不创建/写入任何文件到磁盘

本文关键字:创建 是否 任何 磁盘 文件 单元 功能 测试 何测试 一个 代码 | 更新日期: 2023-09-27 18:07:51

假设有一个关键任务流程将用于处理敏感信息(想想信用卡、社会保险、患者记录等)的业务。我认为理想情况下,这个单元应该做它必须做的任何事情,这意味着它不会故意将包含敏感信息的文件写入磁盘。这里的想法是,如果运行此进程的计算机被入侵,则不会泄露敏感信息,至少不会通过文件泄露。

如果被测单元试图将任何文件写入磁盘,那么可以采用什么方法来进行单元测试,使失败?

如何测试一个给定的功能代码单元(c#)是否不创建/写入任何文件到磁盘

有FileSystemWatcher (http://www.c-sharpcorner.com/uploadfile/puranindia/filesystemwatcher-in-C-Sharp/),但是这需要您知道一个特定的目录。在您的情况下,这可能不是很有帮助,因为程序可以将任何内容写入磁盘的任何位置。这就引入了一个独特的问题。然而,我也发现了微软的一个叫Detours的东西。这似乎会拦截所有本地win32 api调用。http://research.microsoft.com/en-us/projects/detours/这样做的问题是它很难测试,并且将其集成到单元测试中将是一个挑战。

当您必须将您的软件视为"不可信的",即您需要证明它没有做任何事情时,测试就变成了一项复杂的任务,需要您在非常受控制的环境中运行它们。当连接到Win32 API时,您将被需要快速处理的API调用淹没。这可能会导致意想不到的副作用,因为应用程序不是在真正的本机环境中运行的。

我给你的建议(我已经按照FDA的严格标准为制药自动化做了几年的软件测试)是创建一个受控的环境,例如一个虚拟机,它有一个已知的启动状态。这可以通过从不实际将vmdk更改保存到磁盘来实现。您必须对文件系统进行快照。你可以通过编写一个c#应用程序来枚举虚拟驱动器上的所有文件,获取它们的大小,一些时间戳,甚至文件的哈希值来实现这一点。这可能很耗时,所以您可能希望(或能够)跳过散列。创建某种类型的报告,最简单的方法是将它们放入CSV或XML导出中。然后在正常情况下运行软件一段时间。完成后,再次运行文件系统分析并比较结果。有一些不错的应用程序可以比较文件内容(如WinMerge)。在拍摄这些快照时,最好的方法是将vmdk挂载为主机操作系统中的驱动器。这将绕过客户操作系统可能拥有的任何文件锁。

这个方法很耗时,但是很彻底。如果您不需要这种深度,您可以使用Process Monitor之类的工具,将输出写入文件,并针对该文件运行报告。然而,在我的工作中,我必须证明进程监视器显示所有IO之前,我可以使用它,这可能就像我上面提到的方法一样困难。

只是我的2美分。

更新:

我一直在考虑这个问题,如果您删除所有对System的引用,您可能能够获得相当可靠的结果。IO从你的代码。编写一个库来封装System。IO要么不实现写方法,要么只实现一个也写入日志文件的方法。在这种情况下,您只需验证每次使用库进行写操作时是否都会记录日志。然后使用不引用系统的反射来验证。在这个新的包装器库之外的IO。然后,您的测试只需查看此日志文件,以确保只发生经过批准的写操作。可以使用SQL数据库而不是平面日志文件来帮助避免篡改或污染结果的情况。这比像上面描述的那样编写虚拟机设置脚本要容易得多。当然,这都需要您访问"不受信任的"应用程序的源代码,尽管由于您正在对其进行单元测试,我假设您这样做了。

第一个选项:
也许你可以使用代码访问安全,但"拒绝"在。net 4中已经过时了(但应该在以前的版本中工作):

[FileIOPermission(SecurityAction.Deny)]
public class MyClass 
{
  ...
}

您可以在。net 4中使用NetFx40_LegacySecurityPolicy重新激活此行为

选项2:
降低特权级别也可能有效,因为我知道下载的应用程序不能在磁盘上写入,必须使用特殊的存储区域。

第三选择:
删除对System的任何引用。IO和替换为一个接口,您的代码必须使用该接口向磁盘写入数据。
然后编写一个使用System的实现。IO(在单独的项目中)
在nunit测试中,模拟该接口,并在调用方法id时抛出异常。

问题是要确保任何开发人员不会调用System。输入输出了。您可以尝试通过使用FxCop(或其他类似的工具)

强制编码规则来实现这一点。