<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.8" -->
<?xml-stylesheet href="https://wwoss.direct.quickconnect.to/lib/exe/css.php?s=feed" type="text/css"?>
<rss version="2.0">
    <channel xmlns:g="http://base.google.com/ns/1.0">
        <title>worldwide open-source software - wiki:devel:parser:test</title>
        <description></description>
        <link>https://wwoss.direct.quickconnect.to/</link>
        <lastBuildDate>Sat, 11 Apr 2026 04:45:15 +0000</lastBuildDate>
        <generator>FeedCreator 1.8</generator>
        <image>
            <url>https://wwoss.direct.quickconnect.to/lib/exe/fetch.php?media=wiki:logo.png</url>
            <title>worldwide open-source software</title>
            <link>https://wwoss.direct.quickconnect.to/</link>
        </image>
        <item>
            <title>simple_test_lexer_notes</title>
            <link>https://wwoss.direct.quickconnect.to/doku.php?id=wiki:devel:parser:test:simple_test_lexer_notes&amp;rev=1737041805</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;заметка_simple_test_lexer&quot;&gt;Заметка simple test lexer&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Просто привожу быстрый пример, пока экспериментирую с Simple Tests Lexer. Если вам нужен инструмент для разбора какого-нибудь мини-языка в PHP , это хорошее место для поиска.
&lt;/p&gt;

&lt;p&gt;
Одним из побочных продуктов &lt;a href=&quot;https://wwoss.direct.quickconnect.to/doku.php?id=wiki:devel:parser:test:simple_test&quot; class=&quot;wikilink1&quot; title=&quot;wiki:devel:parser:test:simple_test&quot; data-wiki-id=&quot;wiki:devel:parser:test:simple_test&quot;&gt;Simple Test&lt;/a&gt; является лексер на основе регулярных выражений, который можно найти в CVS &lt;a href=&quot;http://web.archive.org/web/20070814083008/http://cvs.sourceforge.net/viewcvs.py/simpletest/simpletest/parser.php?rev=1.58&amp;amp;view=auto&quot; class=&quot;urlextern&quot; title=&quot;http://web.archive.org/web/20070814083008/http://cvs.sourceforge.net/viewcvs.py/simpletest/simpletest/parser.php?rev=1.58&amp;amp;view=auto&quot; rel=&quot;ugc nofollow&quot;&gt;здесь&lt;/a&gt;. Маркус использует его для построения &lt;abbr title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/abbr&gt;- парсера для Simple Test, но его можно применять практически к чему угодно. Обратите внимание, что есть отдельная версия лексера, доступная на Marcus SourceForge «code dump» - &lt;a href=&quot;http://sf.net/projects/lamplib&quot; class=&quot;urlextern&quot; title=&quot;http://sf.net/projects/lamplib&quot; rel=&quot;ugc nofollow&quot;&gt;http://sf.net/projects/lamplib&lt;/a&gt; .
&lt;/p&gt;

&lt;p&gt;
Сейчас я вынужден исследовать его из-за необходимости. &lt;a href=&quot;http://web.archive.org/web/20070814083008/http://wact.sourceforge.net/&quot; class=&quot;urlextern&quot; title=&quot;http://web.archive.org/web/20070814083008/http://wact.sourceforge.net/&quot; rel=&quot;ugc nofollow&quot;&gt;WACT&lt;/a&gt; разрабатывает шаблонное выражение/язык привязки данных, использование которого описано в &lt;a href=&quot;http://web.archive.org/web/20070814083008/http://wact.sourceforge.net/index.php/TemplateAuthorsGuide&quot; class=&quot;urlextern&quot; title=&quot;http://web.archive.org/web/20070814083008/http://wact.sourceforge.net/index.php/TemplateAuthorsGuide&quot; rel=&quot;ugc nofollow&quot;&gt;Руководстве для авторов шаблонов&lt;/a&gt;. К сожалению, есть ошибка (эффекты &lt;a href=&quot;http://web.archive.org/web/20070814083008/http://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=983454&amp;amp;group_id=85372&amp;amp;atid=575984&quot; class=&quot;urlextern&quot; title=&quot;http://web.archive.org/web/20070814083008/http://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=983454&amp;amp;group_id=85372&amp;amp;atid=575984&quot; rel=&quot;ugc nofollow&quot;&gt;описаны здесь&lt;/a&gt;), которая, похоже, предполагает, что синтаксис PCRE в PHP изменился где-то между PHP 4.1.2 и 4.3.2.
&lt;/p&gt;

&lt;p&gt;
Рассматриваемое регулярное выражение:
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;re0&quot;&gt;$regex&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;/^((?Us).*)&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt; &lt;a href=&quot;http://www.php.net/preg_quote&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;preg_quote&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;{$&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;/&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;
	        &lt;span class=&quot;st_h&quot;&gt;&#039;(([^&amp;quot;\&#039;}]+|(\&#039;|&amp;quot;)(?U).*\4)+)&#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt;
	        &lt;a href=&quot;http://www.php.net/preg_quote&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;preg_quote&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;}&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;/&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;((?s).*)$/&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Я не нашел никаких очевидных указаний на изменения в синтаксисе в руководстве PHP / CVS (любой вклад будет очень признателен). Это регулярное выражение также заставляет меня ломать голову (Джефф тоже ломает голову над этим), поэтому изучаю возможности более управляемого подхода к разбору языка выражений шаблонов.
&lt;/p&gt;

&lt;p&gt;
В любом случае, если говорить коротко, вот очень простой пример использования Simple Tests lexer в качестве шаблонизатора, который может помочь кому-то начать. Дополнительные примеры лучше всего искать, изучая &lt;a href=&quot;http://web.archive.org/web/20070814083008/http://cvs.sourceforge.net/viewcvs.py/simpletest/simpletest/test/parser_test.php?rev=1.46&amp;amp;view=auto&quot; class=&quot;urlextern&quot; title=&quot;http://web.archive.org/web/20070814083008/http://cvs.sourceforge.net/viewcvs.py/simpletest/simpletest/test/parser_test.php?rev=1.46&amp;amp;view=auto&quot; rel=&quot;ugc nofollow&quot;&gt;тестовые случаи парсера&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Если у меня есть такой шаблон;
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;Начальное сообщение — &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$Greeting&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt;br&lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt;
Последнее слово по теме — &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$Closing&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
где &lt;code&gt;{$Greeting}&lt;/code&gt; и &lt;code&gt;{$Closing}&lt;/code&gt; — ссылки на переменные шаблона, которые я хочу заменить некоторыми значениями, назначенными мной шаблонизатору, синтаксический анализатор, использующий лексический анализатор Simple Tests, может выглядеть так:
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt; 
&lt;span class=&quot;co1&quot;&gt;// Включить парсер &lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;  &lt;span class=&quot;st_h&quot;&gt;&#039;path/to/simpletest/parser.php&#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
класс YetAnotherTemplateParser &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;co1&quot;&gt;// Здесь размещается вывод шаблона &lt;/span&gt;
	&lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt;  &lt;span class=&quot;re0&quot;&gt;$output&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;&#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;co1&quot;&gt;// Хэш переменных для замены &lt;/span&gt;
	&lt;span class=&quot;kw2&quot;&gt;var&lt;/span&gt;  &lt;span class=&quot;re0&quot;&gt;$phpVars&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;co1&quot;&gt;// Регистрация переменной &lt;/span&gt;
	&lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; registerVariable &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; 
		&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;phpVars&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$name&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$value&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	 &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;co1&quot;&gt;// Отображение страницы &lt;/span&gt;
	&lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; display &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; 
		&lt;span class=&quot;kw1&quot;&gt;echo&lt;/span&gt;  &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	 &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;co4&quot;&gt;/**
	* Функция обратного вызова (или режим/состояние), вызываемая Lexer. Эта
	* имеет дело с текстом за пределами ссылки на переменную.
	* @param string совпадающий текст
	* @param int состояние лексера (здесь игнорируется)
	*/&lt;/span&gt; 
	&lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; writePlainText &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$match&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$state&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; 
		&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$match&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		 &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt;  &lt;span class=&quot;kw4&quot;&gt;TRUE&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	 &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;co4&quot;&gt;/**
	* Обратный вызов для ссылок на переменные шаблона.
	* @param string совпадающий текст
	* @param int состояние лексера
	*/&lt;/span&gt; 
	&lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; writeVariable &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$match&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$state&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; 
		&lt;span class=&quot;kw1&quot;&gt;switch&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$state&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; 	
			&lt;span class=&quot;co1&quot;&gt;// Ввод ссылки на переменную &lt;/span&gt;
			&lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; LEXER_ENTER&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
				 &lt;span class=&quot;co1&quot;&gt;// Начало ссылки на переменную — пока ничего не нужно делать &lt;/span&gt;
			&lt;span class=&quot;kw1&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
			&lt;span class=&quot;co1&quot;&gt;// Содержимое переменной reference &lt;/span&gt;
			&lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; LEXER_UNMATCHED&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
				 &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;  &lt;a href=&quot;http://www.php.net/isset&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;isset&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;phpVars&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$match&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; 
					&lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;.=&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;phpVars&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$match&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
				 &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; 
			&lt;span class=&quot;kw1&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
			&lt;span class=&quot;co1&quot;&gt;// Выход из ссылки на переменную &lt;/span&gt;
			&lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; LEXER_EXIT&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
				 &lt;span class=&quot;co1&quot;&gt;// Конец ссылки на переменную - ничего не нужно делать - завершено &lt;/span&gt;
			&lt;span class=&quot;kw1&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;			
		 &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; 
		&lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt;  &lt;span class=&quot;kw4&quot;&gt;TRUE&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	 &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// Создаем парсер шаблона &lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$Parser&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; YetAnotherTemplateParser &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// Регистрируем некоторые переменные шаблона для замены &lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$Parser&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;registerVariable&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;Greeting&#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;Hello World!&#039;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
 &lt;span class=&quot;re0&quot;&gt;$Parser&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;registerVariable&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;Closing&#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;Goodbye World!&#039;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;//Создаем лексический анализатор &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// Второй аргумент: начальное &amp;quot;состояние&amp;quot; или функция обратного вызова &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// Третий аргумент: чувствительность к регистру ВКЛ - не имеет значения для этого примера, &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// так как шаблоны регулярных выражений не являются буквами, но, чтобы вы знали, &lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$Lexer&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;&amp;amp;new&lt;/span&gt; SimpleLexer &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$Parser&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;writePlainText&#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;TRUE&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// Добавить ссылку на переменную, начинающую шаблон регулярного выражения &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// Второй аргумент: текущее состояние, к которому применяется этот шаблон - предотвращает &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// синтаксис шаблона, подобный {$my{$var, вызывающий два &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// перехода &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// Третий аргумент: состояние (функция обратного вызова) для отправки дальнейших вызовов &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// после того, как шаблон будет найден &lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$Lexer&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;addEntryPattern&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039; \{ \$ &#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;writePlainText&#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;writeVariable&#039;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// Добавляем шаблон выхода для ссылок на переменные, возвращая лексер в &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// его предыдущее состояние (использует стек состояний) &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// Второй аргумент: состояние, в котором применяется этот шаблон &lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$Lexer&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;me1&quot;&gt;addExitPattern&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039; \} &#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;writeVariable&#039;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;re0&quot;&gt;$template&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st_h&quot;&gt;&#039;Вступительное сообщение — {$Greeting}&amp;lt;br&amp;gt;
	Последнее слово по теме — {$Closing}&#039;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;re0&quot;&gt;$Lexer&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; разбор &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;re0&quot;&gt;$template&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;re0&quot;&gt;$Parser&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt; дисплей &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
 &lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Надеюсь, комментарии объяснят, что происходит.
&lt;/p&gt;

&lt;p&gt;
Конечно, это очень нетребовательный язык, но, судя по опыту, Simple Tests Lexer может прекрасно масштабироваться до довольно сложного языка ( &lt;abbr title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/abbr&gt;, для которого Маркус его использует, не так уж и прост в анализе).
&lt;/p&gt;

&lt;p&gt;
Примечание: это не для того, чтобы побудить вас писать еще больше шаблонизаторов! &lt;a href=&quot;http://web.archive.org/web/20070814083008/http://www.sitepoint.com/forums/showthread.php?threadid=123769&quot; class=&quot;urlextern&quot; title=&quot;http://web.archive.org/web/20070814083008/http://www.sitepoint.com/forums/showthread.php?threadid=123769&quot; rel=&quot;ugc nofollow&quot;&gt;Их более чем достаточно&lt;/a&gt;. Например, разбор &lt;abbr title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/abbr&gt; , Javascript, VBScript (подталкивание подталкивание) или SQL может быть стоящей миссией или для мини-языков, таких как язык выражений шаблонов WACT.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;\u0417\u0430\u043c\u0435\u0442\u043a\u0430 simple test lexer&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;\u0437\u0430\u043c\u0435\u0442\u043a\u0430_simple_test_lexer&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-9299&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;дополнения_и_файлы&quot;&gt;Дополнения и Файлы&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
&lt;a href=&quot;http://web.archive.org/web/20070814083008/http://www.phppatterns.com/docs/develop/simple_test_lexer_notes&quot; class=&quot;urlextern&quot; title=&quot;http://web.archive.org/web/20070814083008/http://www.phppatterns.com/docs/develop/simple_test_lexer_notes&quot; rel=&quot;ugc nofollow&quot;&gt;Ссылка на оригинальную статью&lt;/a&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;\u0414\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438 \u0424\u0430\u0439\u043b\u044b&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;\u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f_\u0438_\u0444\u0430\u0439\u043b\u044b&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;9300-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Thu, 16 Jan 2025 15:36:45 +0000</pubDate>
        </item>
        <item>
            <title>simple_test</title>
            <link>https://wwoss.direct.quickconnect.to/doku.php?id=wiki:devel:parser:test:simple_test&amp;rev=1738392799</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;simple_test_for_php&quot;&gt;Simple Test for PHP&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Новости: Начался цикл релиза 1.0.1. Функции включают загрузку включаемых файлов, улучшенную поддержку PHP5 для фиктивных объектов и поддержку &lt;abbr title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/abbr&gt;-меток. Также проведена большая очистка имен методов и некоторый внутренний рефакторинг.
&lt;/p&gt;

&lt;p&gt;
Далее предполагается, что вы знакомы с концепцией модульного тестирования, а также с языком веб-разработки PHP. Это руководство для нетерпеливого нового пользователя SimpleTest . Для более полной документации, особенно если вы новичок в модульном тестировании, см. текущую документацию , а для примеров тестовых случаев см. учебник по модульному тестированию .
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Simple Test for PHP&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;simple_test_for_php&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-1106&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;быстрое_использование_тестера&quot;&gt;Быстрое использование тестера&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Среди инструментов тестирования программного обеспечения модульный тестер является наиболее близким к разработчику. В контексте гибкой разработки тестовый код находится прямо рядом с исходным кодом, поскольку оба пишутся одновременно. В этом контексте SimpleTest стремится стать полным решением для тестирования PHP-разработчиков и называется «Simple», потому что он должен быть простым в использовании и расширении. На самом деле это был не очень удачный выбор названия. Он включает в себя все типичные функции, которые можно ожидать от JUnit и портов PHPUnit , но также добавляет фиктивные объекты . Он также имеет некоторую функциональность JWebUnit . Сюда входит навигация по веб-страницам, тестирование cookie-файлов и отправка форм.
&lt;/p&gt;

&lt;p&gt;
Самый быстрый способ продемонстрировать это — привести пример.
&lt;/p&gt;

&lt;p&gt;
Предположим, мы тестируем простой класс регистрации файла, который называется Log in classes/log.php . Начнем с создания тестового скрипта, который назовем tests/log_test.php и заполним его следующим образом…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/unit_tester.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/reporter.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;../classes/log.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; TestOfLogging &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; UnitTestCase &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Здесь папка &lt;em&gt;simpletest&lt;/em&gt; либо локальная, либо находится в пути. Вам придется отредактировать эти расположения в зависимости от того, где вы разместили набор инструментов. &lt;span style=&quot;color:#22b14c;&quot;&gt;TestOfLogging&lt;/span&gt; — наш первый тестовый случай, и в настоящее время он пуст.
Теперь у нас есть пять строк кода scaffolding и все еще нет тестов. Однако с этой части мы получаем возврат наших инвестиций очень быстро. Предположим, что класс &lt;span style=&quot;color:#22b14c;&quot;&gt;Log&lt;/span&gt; принимает имя файла для записи в конструкторе, и у нас есть временная папка, в которую можно поместить этот файл…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/unit_tester.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/reporter.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;../classes/log.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; TestOfLogging &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; UnitTestCase &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; testCreatingNewFile&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;sy0&quot;&gt;@&lt;/span&gt;&lt;a href=&quot;http://www.php.net/unlink&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;unlink&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; &lt;a href=&quot;http://www.php.net/log&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;Log&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/file_exists&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;file_exists&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;Should write this to a file&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/file_exists&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;file_exists&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
При запуске тестового случая он ищет любой метод, начинающийся со строки &lt;span style=&quot;color:#22b14c;&quot;&gt;test&lt;/span&gt;, и выполняет этот метод. Обычно у нас, конечно, больше одного тестового метода. Утверждения в тестовых методах запускают сообщения в тестовую среду, которая немедленно отображает результат. Этот немедленный ответ важен не только в случае, если код вызывает сбой, но и для того, чтобы операторы &lt;span style=&quot;color:#22b14c;&quot;&gt;print&lt;/span&gt; могли отображать свое содержимое прямо рядом с соответствующим тестовым случаем.
&lt;/p&gt;

&lt;p&gt;
Чтобы увидеть эти результаты, нам нужно запустить тесты. Если это единственный тестовый случай, который мы хотим запустить, мы можем добиться этого с помощью…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/unit_tester.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/reporter.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;../classes/log.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; TestOfLogging &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; UnitTestCase &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; testCreatingNewFile&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;sy0&quot;&gt;@&lt;/span&gt;&lt;a href=&quot;http://www.php.net/unlink&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;unlink&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; &lt;a href=&quot;http://www.php.net/log&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;Log&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/file_exists&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;file_exists&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;Should write this to a file&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/file_exists&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;file_exists&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;re0&quot;&gt;$test&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;&amp;amp;new&lt;/span&gt; TestOfLogging&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$test&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; HtmlReporter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
В случае сбоя дисплей выглядит так…
&lt;/p&gt;
&lt;div class=&quot;plugin_note noteclassic&quot;&gt;&lt;strong&gt;testoflogging&lt;/strong&gt;&lt;br/&gt;

Fail: testcreatingnewfile→True assertion failed.&lt;br/&gt;

&lt;span style=&quot;color:white/red;&quot;&gt;1/1 test cases complete. 1 passes and 1 fails.&lt;/span&gt;

&lt;/div&gt;
&lt;p&gt;
…и если это пройдет вот так…
&lt;/p&gt;
&lt;div class=&quot;plugin_note noteclassic&quot;&gt;&lt;strong&gt;testoflogging&lt;/strong&gt;&lt;br/&gt;

&lt;span style=&quot;color:white/green;&quot;&gt;1/1 test cases complete. 2 passes and 0 fails.&lt;/span&gt;

&lt;/div&gt;
&lt;p&gt;
И если вы это получите…
&lt;/p&gt;
&lt;pre class=&quot;code&quot;&gt;Fatal error: Failed opening required &amp;#039;../classes/log.php&amp;#039; (include_path=&amp;#039;&amp;#039;) in
/home/marcus/projects/lastcraft/tutorial_tests/Log/tests/log_test.php on line 7&lt;/pre&gt;

&lt;p&gt;
это означает, что у вас отсутствует файл &lt;em&gt;classes/Log.php&lt;/em&gt;, который может выглядеть так…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; &lt;a href=&quot;http://www.php.net/log&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;Log&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
        &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; &lt;a href=&quot;http://www.php.net/log&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;Log&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$file_path&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
		&lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; message&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;\u0411\u044b\u0441\u0442\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u0441\u0442\u0435\u0440\u0430&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;\u0431\u044b\u0441\u0442\u0440\u043e\u0435_\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435_\u0442\u0435\u0441\u0442\u0435\u0440\u0430&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;1107-7200&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;групповые_тесты&quot;&gt;Групповые тесты&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Маловероятно, что в реальном приложении мы когда-либо запустим только один тестовый случай. Это означает, что нам нужен способ группировки случаев в тестовый сценарий, который может, при необходимости, запустить каждый тест в приложении.
&lt;/p&gt;

&lt;p&gt;
Наш первый шаг — удалить включения и отменить наш предыдущий взлом…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;../classes/log.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; TestOfLogging &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; UnitTestCase &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; testCreatingNewFile&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;sy0&quot;&gt;@&lt;/span&gt;&lt;a href=&quot;http://www.php.net/unlink&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;unlink&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; &lt;a href=&quot;http://www.php.net/log&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;Log&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertFalse&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/file_exists&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;file_exists&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;Should write this to a file&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertTrue&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/file_exists&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;file_exists&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Далее мы создаем новый файл с именем &lt;code&gt;tests/all_tests.php&lt;/code&gt; и вставляем следующий код…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/unit_tester.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/reporter.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;re0&quot;&gt;$test&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;&amp;amp;new&lt;/span&gt; GroupTest&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;All tests&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$test&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;addTestFile&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;log_test.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$test&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; HtmlReporter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Метод &lt;span style=&quot;color:#22b14c;&quot;&gt;GroupTest::addTestFile()&lt;/span&gt; включит файл тестового случая и прочитает все новые созданные классы, которые являются потомками &lt;span style=&quot;color:#22b14c;&quot;&gt;SimpleTestCase&lt;/span&gt;, одним из примеров которых является &lt;span style=&quot;color:#22b14c;&quot;&gt;UnitTestCase&lt;/span&gt;. На данный момент сохраняются только имена классов, чтобы тестовый исполнитель мог создать экземпляр класса, когда он будет проходить через ваш тестовый набор.
Чтобы это работало правильно, файл тестового случая не должен слепо включать какие-либо другие расширения тестового случая, которые на самом деле не запускают тесты. Это может привести к подсчету дополнительных тестовых случаев во время тестового прогона. Вряд ли это серьезная проблема, но чтобы избежать этого неудобства, просто добавьте директиву &lt;span style=&quot;color:#22b14c;&quot;&gt;SimpleTestOptions::ignore()&lt;/span&gt; где-нибудь в файле тестового случая. Кроме того, файл тестового случая не должен был быть включен в другом месте, иначе в этот групповой тест не будут добавлены случаи. Это будет более серьезной ошибкой, так как если классы тестового случая уже загружены PHP, метод &lt;span style=&quot;color:#22b14c;&quot;&gt;GroupTest::addTestFile()&lt;/span&gt; не обнаружит их.
&lt;/p&gt;

&lt;p&gt;
Для отображения результатов необходимо только вызвать &lt;em&gt;tests/all_tests.php&lt;/em&gt; с веб-сервера.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;\u0413\u0440\u0443\u043f\u043f\u043e\u0432\u044b\u0435 \u0442\u0435\u0441\u0442\u044b&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;\u0433\u0440\u0443\u043f\u043f\u043e\u0432\u044b\u0435_\u0442\u0435\u0441\u0442\u044b&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:5,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;7201-10628&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;использование_фиктивных_объектов&quot;&gt;Использование фиктивных объектов&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Давайте перенесемся еще дальше в будущее.
&lt;/p&gt;

&lt;p&gt;
Предположим, что наш класс логирования протестирован и завершен. Предположим также, что мы тестируем другой класс, который требуется для записи сообщений журнала, скажем, &lt;span style=&quot;color:#22b14c;&quot;&gt;SessionPool&lt;/span&gt;. Мы хотим протестировать метод, который, вероятно, в конечном итоге будет выглядеть так…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; SessionPool &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;sy0&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; logIn&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;sy0&quot;&gt;...&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;_log&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;User &lt;span class=&quot;es4&quot;&gt;$username&lt;/span&gt; logged in.&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;sy0&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
    &lt;span class=&quot;sy0&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
В духе повторного использования мы используем наш класс &lt;span style=&quot;color:#22b14c;&quot;&gt;Log&lt;/span&gt;. Обычный тестовый случай может выглядеть так…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;../classes/log.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;../classes/session_pool.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; TestOfSessionLogging &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; UnitTestCase &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; setUp&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;sy0&quot;&gt;@&lt;/span&gt;&lt;a href=&quot;http://www.php.net/unlink&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;unlink&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; tearDown&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;sy0&quot;&gt;@&lt;/span&gt;&lt;a href=&quot;http://www.php.net/unlink&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;unlink&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; testLogInIsLogged&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; &lt;a href=&quot;http://www.php.net/log&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;Log&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$session_pool&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;&amp;amp;new&lt;/span&gt; SessionPool&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$session_pool&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;logIn&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;fred&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$messages&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;a href=&quot;http://www.php.net/file&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;file&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/temp/test.log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertEqual&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$messages&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;User fred logged in.&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Этот дизайн тестового случая не совсем плох, но его можно улучшить. Мы тратим время на возню с файлами журналов, которые не являются частью нашего теста. Хуже того, мы создали тесные связи между классом Log и этим тестом. Что, если мы больше не будем использовать файлы, а вместо этого будем использовать библиотеку syslog ? Вы заметили дополнительный возврат каретки в сообщении? Это было добавлено регистратором? Что, если он также добавил временную метку или другие данные?
Единственная часть, которую мы действительно хотим проверить, — это то, что определенное сообщение было отправлено в регистратор. Мы уменьшаем связанность, если можем передать фальшивый класс регистрации, который просто записывает вызовы сообщения для тестирования, но не предпринимает никаких действий. Однако он должен выглядеть точно так же, как наш оригинал.
&lt;/p&gt;

&lt;p&gt;
Если поддельный объект не пишет в файл, то мы экономим на удалении файла до и после каждого теста. Мы могли бы сэкономить еще больше тестового кода, если бы поддельный объект любезно выполнил утверждение для нас.
&lt;/p&gt;

&lt;p&gt;
Слишком хорошо, чтобы быть правдой? К счастью, мы можем легко создать такой объект…
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;../classes/log.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;../classes/session_pool.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
Mock&lt;span class=&quot;sy0&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;me2&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;Log&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; TestOfSessionLogging &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; UnitTestCase &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; testLogInIsLogged&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;&amp;amp;new&lt;/span&gt; MockLog&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;expectOnce&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;message&#039;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;User fred logged in.&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$session_pool&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;&amp;amp;new&lt;/span&gt; SessionPool&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;re0&quot;&gt;$log&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$session_pool&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;logIn&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;fred&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Тест будет запущен, когда вызов &lt;span style=&quot;color:#22b14c;&quot;&gt;message()&lt;/span&gt; будет вызван на объекте &lt;span style=&quot;color:#22b14c;&quot;&gt;MockLog&lt;/span&gt;. Вызов mock запустит сравнение параметров, а затем отправит результирующее событие pass или fail на дисплей теста. Здесь также можно включить подстановочные знаки, чтобы тесты не стали слишком конкретными.
Если мок достигает конца тестового случая без вызова метода, ожидание &lt;span style=&quot;color:#22b14c;&quot;&gt;expectOnce()&lt;/span&gt; вызовет сбой теста. Другими словами, мок может обнаружить как отсутствие поведения, так и его наличие.
&lt;/p&gt;

&lt;p&gt;
Для фиктивных объектов в наборе SimpleTest можно задать произвольные возвращаемые значения, последовательности возвращаемых значений, возвращаемые значения, выбранные в соответствии с входящими аргументами, последовательности ожидаемых параметров и ограничения на количество вызовов метода.
&lt;/p&gt;

&lt;p&gt;
Для запуска этого теста библиотека фиктивных объектов должна быть включена в тестовый набор, например, в &lt;em&gt;all_tests.php&lt;/em&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0438\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435_\u0444\u0438\u043a\u0442\u0438\u0432\u043d\u044b\u0445_\u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:7,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;10629-16374&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;тестирование_веб-страниц&quot;&gt;Тестирование веб-страниц&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Одним из требований к веб-сайтам является то, что они производят веб-страницы. Если вы создаете проект сверху вниз и хотите полностью интегрировать тестирование по ходу дела, то вам понадобится способ автоматической навигации по сайту и проверки вывода на корректность. Это работа веб-тестера.
&lt;/p&gt;

&lt;p&gt;
Веб-тестирование в SimpleTest довольно примитивно, например, нет JavaScript. Чтобы дать представление, вот тривиальный пример, где извлекается домашняя страница, с которой мы переходим на страницу «about», а затем тестируем некоторый определенный клиентом контент.
&lt;/p&gt;
&lt;pre class=&quot;code php&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/web_tester.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;require_once&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;simpletest/reporter.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw2&quot;&gt;class&lt;/span&gt; TestOfAbout &lt;span class=&quot;kw2&quot;&gt;extends&lt;/span&gt; WebTestCase &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; setUp&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;http://test-server/index.php&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;About&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw2&quot;&gt;function&lt;/span&gt; testSearchEngineOptimisations&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertTitle&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;A long title about us for search engines&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;re0&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;assertPattern&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st_h&quot;&gt;&#039;/a popular keyphrase/i&#039;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$test&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;&amp;amp;new&lt;/span&gt; TestOfAbout&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;re0&quot;&gt;$test&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;me1&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;new&lt;/span&gt; HtmlReporter&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sy1&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Используя этот код в качестве приемочного теста, вы можете быть уверены, что контент всегда соответствует спецификациям как разработчиков, так и других заинтересованных сторон проекта.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435_\u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043d\u0438\u0446&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:10,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;16375-18299&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit6&quot; id=&quot;дополнения_и_файлы&quot;&gt;Дополнения и Файлы&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;http://web.archive.org/web/20070814114708/http://www.lastcraft.com/simple_test.php#unit&quot; class=&quot;urlextern&quot; title=&quot;http://web.archive.org/web/20070814114708/http://www.lastcraft.com/simple_test.php#unit&quot; rel=&quot;ugc nofollow&quot;&gt;Ссылка на оригинальную статью&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://simpletest.sourceforge.net/en/start-testing.html&quot; class=&quot;urlextern&quot; title=&quot;https://simpletest.sourceforge.net/en/start-testing.html&quot; rel=&quot;ugc nofollow&quot;&gt;simpletest.sourceforge.net&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://github.com/simpletest/simpletest&quot; class=&quot;urlextern&quot; title=&quot;https://github.com/simpletest/simpletest&quot; rel=&quot;ugc nofollow&quot;&gt;github_simpletest&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://wwoss.direct.quickconnect.to/lib/exe/fetch.php?media=wiki:devel:parser:test:simpletest-main.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:devel:parser:test:simpletest-main.zip (188.1 KB)&quot;&gt;SimpleTest&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;\u0414\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438 \u0424\u0430\u0439\u043b\u044b&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;\u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f_\u0438_\u0444\u0430\u0439\u043b\u044b&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:11,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;18300-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sat, 01 Feb 2025 06:53:19 +0000</pubDate>
        </item>
    </channel>
</rss>
