所以我写了一个单元测试来比较PHP中的裁剪图像(使用imagemagick)。测试工作正常,但在一次比较大量图像时我遇到了问题。根据创建图像的时间,每个图像都会接收直接嵌入原始数据的时间戳。在比较文件之前,我一直在使用正则表达式来提取时间戳,但似乎每隔一段时间,其中一个图像文件中会有其他原始数据,即使它们完全相同。
举个例子,这是我的一个测试的结果(请注意,我将图像的二进制数据作为字符串进行比较):
ImageTest :: testAutoCrop
断言两个字符串相等无效。
---预计
+++ Actual
@@ @@
2 N - 3 M +
- ?F sO = f ?????????????????????
?(???/o????M)???o%tEXt??%tEXt
+?F sO = f ??????????????????????
?(???/o????M)???o%tEXt
正如你所看到的......这两个文件之间的唯一区别是预期的图像中有这个额外的字符串:“?%tEXt”。
有人可以帮助我理解这个随机数据代表什么吗?这将帮助我弄清楚如何修改我的单元测试,以便不再发生这样的问题。
谢谢,
马尔科姆
PS:如果我需要提供更多信息,请告诉我。
答案 0 :(得分:2)
所以我最终提出了解决这个问题的方法。几点事情要澄清:
我之所以进行单元测试是因为我们的图像服务Web应用程序(PHP)使用Imagemagick处理所有图像处理,操作,HTML转换为图像,PDF转换为图像(jpg,png,gif,所有非cmyk,pdf)转换发生在我们的主网站上。需要确保在我们为此图像服务应用程序添加新功能时,已经有足够的测试来确保所有功能仍能正常运行。
我们在每张图片中看到的字符串数据(又名:?%tEXt)是图片的exif数据。 (http://en.wikipedia.org/wiki/Exchangeable_image_file_format)为了比较图片(来自David Andersson的回复(https://stackoverflow.com/users/904933/david-andersson),我们需要从图像中完全删除所有评论数据以及创建日期时间戳/修改信息。这样你就可以处理简单的图像,而不处理其他类型的元数据。我们使用以下功能进行处理:
protected static function _removeTimeStamp( $string, $pdf = false ) {
/* Note: Assume $string parameter is the image you're planning on cleaning in string format. */
/* If you're working with a pdf, you need to remove the CreationDate using regex from the string representation. */
if ( $pdf )
return preg_replace( '/(CreationDate[^)]+)/', '', $string );
/* Create a path for the temporary image we're going to need to create that will hold the exif free image */
$strip_tmp = 'test/strip_tmp';
/* write contents of string to temp string file */
file_put_contents( $strip_tmp, $string );
/* this will remove all exif data along with the date:create and date:modify properties from the image */
exec( 'convert ' . $strip_tmp . ' -strip +set date:create +set date:modify ' . $strip_tmp . ' 2> /dev/null' );
/* get the string representation of the new "cleaned" image */
$result = file_get_contents( $strip_tmp );
/* delete the temp file */
unlink( $strip_tmp );
/* return the cleaned string */
return $result;
} // _removeTimeStamp
在对每个图像进行比较之前对它们进行比较(以字符串格式)。希望这可以帮助将来可能做类似事情的人。
我计划更详细地写一篇博文,以展示我如何处理其他一些测试。当我这样做时,我将使用评论或此答案中的链接更新此问题。希望这有助于某人。
答案 1 :(得分:1)
在单元测试中,您应该只测试您的单位,而不是第三方代码的单位。
您尚未指定有关图像缩放器的任何详细信息,但我假设您正在使用第三方函数,这些函数计为自己的单位(一个函数是一个单位,就像一个类是一个单位)。 / p>
所以问题是:你的代码,你的单位是否生成了二进制数据?我猜不是,否则你会知道为什么二进制数据不同。
由于这些不是你的单位,不要为它们编写测试。相反,转到原始单元来自(上游)的项目并检查他们的测试套件。
如果您担心集成测试(测试不同单元相互协作),您应该定义可以处理子组件返回的(不同)数据的稳定测试。例如。您可能需要进行图像比较(是像素大小并且是像素值(以及文件格式可能)正确)而不是比较二进制数据,因为文件格式通常允许多种方式如何编码同一图像数据(加上元数据)。