我有一个PHPUnit测试,它使用regexp验证日志文件的输出。日志文件看起来像这样(第一行是空的,但我不知道如何在这里显示):
<empty line>
lfworker01:
-----------------------------------------------------------
Last update: 2012-06-14 11:43:17
Last Segment Sent: 2009-12-02 23:25:00 (1259792700)
Current Segement: 2009-12-03 00:25:00 (1259796300)
Clicks processed Segment: 3
Open sessions Segment: 1
Duration Segment: 0,06 sec
Speed Segment: 47,67 clicks/sec
Uptime: 0 days 00:00:00
Clicks processed overall: 3
Avg Speed overall: 81,70 clicks/sec
Current memory used: 16,75 MB
Max memory used: 16,75 MB
我正在使用正则表达式验证内容:
$strExpectedMeasurementLog = "#
lfworker01:
-----------------------------------------------------------
Last update: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}
Last Segment Sent: 2009-12-02 23:25:00 \(1259792700\)
Current Segement: 2009-12-03 00:25:00 \(1259796300\)
Clicks processed Segment: 3
Open sessions Segment: 1
Duration Segment: \d*,\d{2} sec
Speed Segment: \d*,\d{2} clicks/sec
Uptime: 0 days 00:00:00
Clicks processed overall: 3
Avg Speed overall: \d*,\d{2} clicks/sec
Current memory used: \d*,\d{2} MB
Max memory used: \d*,\d{2} MB#";
$strActualMeasurementLog = file_get_contents( dirname( __FILE__)."/applogs/measurement.log");
self::assertRegExp( $strExpectedMeasurementLog, $strActualMeasurementLog);
PHPUnit测试是在unix环境中创建的。此测试在unix测试环境中传递,但在Windows测试环境中失败。我通过将此函数应用于measurement.log文件来替换带有unix换行符的Windows换行符:
public function unixtodos( $strPathFile )
{
$strCurrent = file_get_contents( $strPathFile );
$strPattern = "|\r\n|";
$strReplace = "\n";
$strNew = preg_replace( $strPattern, $strReplace, $strCurrent );
file_put_contents( $strPathFile, $strNew );
}
它仍然不符合我的想法:(
答案 0 :(得分:1)
解决方案是始终检查换行符。我在使用php的Windows机器上创建的日志文件具有unix换行符:
从unix中的CVS中检出的PHPUnit源文件具有unix换行符:
Windows中CVS的PHPUnit源文件签出有Windows换行符:
这些换行符打破了我的正则表达式验证。所以现在我总是将换行符替换为unix换行符。
// replace possible windows line breaks with unix line breaks
$strExpectedMeasurementLog = preg_replace( "|\r\n|", "\n", $strExpectedMeasurementLog);
$strActualMeasurementLog = preg_replace( "|\r\n|", "\n", $strActualMeasurementLog);
答案 1 :(得分:0)
一种方法是用“\ s +”替换正则表达式中的所有空格。即说“我希望这里有一些空白,但我不在乎它到底是什么”。我认为这非常适合您的情况,因为这意味着当生成报告的人稍微调整布局时,您的测试不会中断。 (重要提示:如果您的测试的重点是在某人稍微调整报表布局时捕获,那么这是错误的方法!)
缺点是你的正则表达式成为一个可怕的反斜杠模糊,而不是你目前的可读模板。但让我们让PHP为我们做咕噜咕噜的工作;请参阅下面的示例,其中preg_replace使正则表达式对空格差异不敏感。
/** */
class RegexTest extends PHPUnit_Framework_TestCase{
function testRegex(){
$strExpectedMeasurementLog = "#
lfworker01:
-----------------------------------------------------------
Last update: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}
Last Segment Sent: 2009-12-02 23:25:00 \(1259792700\)
Current Segement: 2009-12-03 00:25:00 \(1259796300\)
Clicks processed Segment: 3
Open sessions Segment: 1
Duration Segment: \d*,\d{2} sec
Speed Segment: \d*,\d{2} clicks/sec
Uptime: 0 days 00:00:00
Clicks processed overall: 3
Avg Speed overall: \d*,\d{2} clicks/sec
Current memory used: \d*,\d{2} MB
Max memory used: \d*,\d{2} MB#";
$strExpectedMeasurementLog=preg_replace("/\s+/",'\s+',$strExpectedMeasurementLog);
$strActualMeasurementLog = file_get_contents("test.lf.txt");
self::assertRegExp( $strExpectedMeasurementLog, $strActualMeasurementLog);
$strActualMeasurementLog = file_get_contents("test.crlf.txt");
self::assertRegExp( $strExpectedMeasurementLog, $strActualMeasurementLog);
}
}
(test.lf.txt是您的问题的复制和粘贴; test.crlf.txt是它的副本,在我的文本编辑器中将LF更改为CRLF。)
<强>精化强>
以上内容有点粗糙,因为它允许使用空格字符而不是换行符。因此,一份可怕的错误报告可能仍会通过。哪个可能不好?下一个版本只是将换行符替换为模板“接受任何CR和LF的组合”:
$strExpectedMeasurementLog=preg_replace("/[\r\n]+/",'[\r\n]+',$strExpectedMeasurementLog);
虽然不是你问题的一部分,但是这个替换“任何空格序列,而不是单个空格”,“需要一个或多个空格”:
$strExpectedMeasurementLog=preg_replace("/ {2,}/",' +',$strExpectedMeasurementLog);