<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Davidaylmer</id>
	<title>MoodleDocs - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.moodle.org/dev/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Davidaylmer"/>
	<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/Special:Contributions/Davidaylmer"/>
	<updated>2026-08-20T23:55:13Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014/Email_Logging&amp;diff=44571</id>
		<title>Hackfest UK 2014/Email Logging</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014/Email_Logging&amp;diff=44571"/>
		<updated>2014-04-29T11:54:53Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Message Logging and Reporting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Contact Names: (please add name if interested)&lt;br /&gt;
*Larry Zoumas (larry(dot)zoumas@xtractor.se)&lt;br /&gt;
*Martin Sandberg (martin(dot)sandberg@xtractor.se)&lt;br /&gt;
*David Aylmer (david(d)aylmer(a)floream(d)com)&lt;br /&gt;
*Rob Hardy (r(dot)hardy(at)yorksj(dot)ac(dot)uk)&lt;br /&gt;
*Marcus Green (m(dot)green(at)yorksj(dot)ac(dot)uk)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
*This plugin will allow admins and teachers to search through messages sent to users. The purpose is to easily answer the question of whether or not a user was notified of an important event, such as a face-to-face session, quiz deadline, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
*Not all emails go through the messaging system. This needs to be investigated and fixed.&lt;br /&gt;
*We might want to allow a place for developers to add hooks or decorate this functionality.&lt;br /&gt;
*We are not sure how this will work with email digests. We should probably log when the digest email goes out.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Email functions not using the messaging system&#039;&#039;&#039;&lt;br /&gt;
*Self Enrolment Enrolment plugin (core)&lt;br /&gt;
*moodle account being locked out after multiple invalid login attempts. (lockoutemailbody) (core)&lt;br /&gt;
*When a badge has been awarded (core)&lt;br /&gt;
*Emailing admins about failed login attempts (core)&lt;br /&gt;
*To alert support email if log table can not be written into (core)&lt;br /&gt;
*Welcome emails (core)&lt;br /&gt;
*Password reset (core)&lt;br /&gt;
*Confirmation email activation link (core)&lt;br /&gt;
*Confirmation two (emailpasswordconfirmation) (core)&lt;br /&gt;
*Password change is disabled email (core)&lt;br /&gt;
*When using the email message output plugin (core)&lt;br /&gt;
*When sending forum digests (forum cron - core)&lt;br /&gt;
*Journal mod (journal cron -core)&lt;br /&gt;
*When oublogs are moderated and require confirmation by the author (core)&lt;br /&gt;
*If user changes email address confirmation is required (core)&lt;br /&gt;
NOTE: Many third party (moodle partner) add-ons will use direct calls to email_to_user. This function should be better encapsulated in regards to information hiding design principles.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Capabilities&#039;&#039;&#039;:&lt;br /&gt;
*Can view own messages&lt;br /&gt;
*Can view other messages&lt;br /&gt;
*Can view messages in your courses (teacher)&lt;br /&gt;
*Can view message body information&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Options&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
*Optionally log body of message&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Proposed Table Schema&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*from (user_id)&lt;br /&gt;
*from_address (email address or identifier when the message was sent)&lt;br /&gt;
*message_type (FK mdl_message_provider)&lt;br /&gt;
*moduleid&lt;br /&gt;
*courseid&lt;br /&gt;
*subject &lt;br /&gt;
*body_id&lt;br /&gt;
*time&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log_user&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*message_log_id (FK to messaging log)&lt;br /&gt;
*userid&lt;br /&gt;
*to_address (email address or identifier when the message was sent)&lt;br /&gt;
*time&lt;br /&gt;
*status&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log_body&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*body_text&lt;br /&gt;
*file_id (FK to mdl_files to see attachment size, etc)&lt;br /&gt;
*email_headers (if any)&lt;br /&gt;
*message_format (html or text)&lt;br /&gt;
&lt;br /&gt;
[[Image:moodle_message_log.png|ER diagram of tables]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reporting&#039;&#039;&#039;&lt;br /&gt;
Output headings suggested order (left to right)&lt;br /&gt;
*Message type&lt;br /&gt;
*Course category (with link to category)&lt;br /&gt;
*Course (with link to course)&lt;br /&gt;
*Component/module (with link to mod e.g. forum post/discussion etc)&lt;br /&gt;
*Peview body link (html/text)&lt;br /&gt;
*Sender Fullname (link to profile)&lt;br /&gt;
*Recipient Fullname (with link to profile)&lt;br /&gt;
*Recipient email/jabberid/mobile phoine number/etc sent to&lt;br /&gt;
*subject&lt;br /&gt;
*time sent&lt;br /&gt;
*status (success)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;filters&#039;&#039;&#039;&lt;br /&gt;
*Download as spreadsheet&lt;br /&gt;
*Paging number of users&lt;br /&gt;
*Filter by course&lt;br /&gt;
*Filter by activity&lt;br /&gt;
*Filter by user&lt;br /&gt;
*Filter by message_type&lt;br /&gt;
*Filter by sent datetime&lt;br /&gt;
*Filter by subject&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tracker issue&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-45160 Extend messaging system to log messages sent...]&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014/Email_Logging&amp;diff=44466</id>
		<title>Hackfest UK 2014/Email Logging</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014/Email_Logging&amp;diff=44466"/>
		<updated>2014-04-17T12:15:22Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Message Logging and Reporting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Contact Names: (please add name if interested)&lt;br /&gt;
*Larry Zoumas (larry(dot)zoumas@xtractor.se)&lt;br /&gt;
*Martin Sandberg (martin(dot)sandberg@xtractor.se)&lt;br /&gt;
*David Aylmer (david(d)aylmer(a)floream(d)com)&lt;br /&gt;
*Rob Hardy (r(dot)hardy(at)yorksj(dot)ac(dot)uk)&lt;br /&gt;
*Marcus Green (m(dot)green(at)yorksj(dot)ac(dot)uk)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
*This plugin will allow admins and teachers to search through messages sent to users. The purpose is to easily answer the question of whether or not a user was notified of an important event, such as a face-to-face session, quiz deadline, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
*Not all emails go through the messaging system. This needs to be investigated and fixed.&lt;br /&gt;
*We might want to allow a place for developers to add hooks or decorate this functionality.&lt;br /&gt;
*We are not sure how this will work with email digests. We should probably log when the digest email goes out.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Capabilities&#039;&#039;&#039;:&lt;br /&gt;
*Can view own messages&lt;br /&gt;
*Can view other messages&lt;br /&gt;
*Can view messages in your courses (teacher)&lt;br /&gt;
*Can view message body information&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Options&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
*Optionally log body of message&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Proposed Table Schema&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*from (user_id)&lt;br /&gt;
*from_address (email address or identifier when the message was sent)&lt;br /&gt;
*message_type (FK mdl_message_provider)&lt;br /&gt;
*moduleid&lt;br /&gt;
*courseid&lt;br /&gt;
*subject &lt;br /&gt;
*body_id&lt;br /&gt;
*time&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log_user&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*message_log_id (FK to messaging log)&lt;br /&gt;
*userid&lt;br /&gt;
*to_address (email address or identifier when the message was sent)&lt;br /&gt;
*time&lt;br /&gt;
*status&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log_body&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*body_text&lt;br /&gt;
*file_id (FK to mdl_files to see attachment size, etc)&lt;br /&gt;
*email_headers (if any)&lt;br /&gt;
*message_format (html or text)&lt;br /&gt;
&lt;br /&gt;
[[Image:moodle_message_log.png|ER diagram of tables]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reporting&#039;&#039;&#039;&lt;br /&gt;
Output headings suggested order (left to right)&lt;br /&gt;
*Message type&lt;br /&gt;
*Course category (with link to category)&lt;br /&gt;
*Course (with link to course)&lt;br /&gt;
*Component/module (with link to mod e.g. forum post/discussion etc)&lt;br /&gt;
*Peview body link (html/text)&lt;br /&gt;
*Sender Fullname (link to profile)&lt;br /&gt;
*Recipient Fullname (with link to profile)&lt;br /&gt;
*Recipient email/jabberid/mobile phoine number/etc sent to&lt;br /&gt;
*subject&lt;br /&gt;
*time sent&lt;br /&gt;
*status (success)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;filters&#039;&#039;&#039;&lt;br /&gt;
*Download as spreadsheet&lt;br /&gt;
*Paging number of users&lt;br /&gt;
*Filter by course&lt;br /&gt;
*Filter by activity&lt;br /&gt;
*Filter by user&lt;br /&gt;
*Filter by message_type&lt;br /&gt;
*Filter by sent datetime&lt;br /&gt;
*Filter by subject&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tracker issue&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-45160 Extend messaging system to log messages sent...]&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014/Email_Logging&amp;diff=44465</id>
		<title>Hackfest UK 2014/Email Logging</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014/Email_Logging&amp;diff=44465"/>
		<updated>2014-04-17T12:13:14Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Message Logging and Reporting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*Contact Names: (please add name if interested)&lt;br /&gt;
*Larry Zoumas (larry(dot)zoumas@xtractor.se)&lt;br /&gt;
*Martin Sandberg (martin(dot)sandberg@xtractor.se)&lt;br /&gt;
*David Aylmer (davidaylmer(a)hotmail.com)&lt;br /&gt;
*Rob Hardy (r(dot)hardy(at)yorksj(dot)ac(dot)uk)&lt;br /&gt;
*Marcus Green (m(dot)green(at)yorksj(dot)ac(dot)uk)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
*This plugin will allow admins and teachers to search through messages sent to users. The purpose is to easily answer the question of whether or not a user was notified of an important event, such as a face-to-face session, quiz deadline, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
*Not all emails go through the messaging system. This needs to be investigated and fixed.&lt;br /&gt;
*We might want to allow a place for developers to add hooks or decorate this functionality.&lt;br /&gt;
*We are not sure how this will work with email digests. We should probably log when the digest email goes out.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Capabilities&#039;&#039;&#039;:&lt;br /&gt;
*Can view own messages&lt;br /&gt;
*Can view other messages&lt;br /&gt;
*Can view messages in your courses (teacher)&lt;br /&gt;
*Can view message body information&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Options&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
*Optionally log body of message&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Proposed Table Schema&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*from (user_id)&lt;br /&gt;
*from_address (email address or identifier when the message was sent)&lt;br /&gt;
*message_type (FK mdl_message_provider)&lt;br /&gt;
*moduleid&lt;br /&gt;
*courseid&lt;br /&gt;
*subject &lt;br /&gt;
*body_id&lt;br /&gt;
*time&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log_user&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*message_log_id (FK to messaging log)&lt;br /&gt;
*userid&lt;br /&gt;
*to_address (email address or identifier when the message was sent)&lt;br /&gt;
*time&lt;br /&gt;
*status&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log_body&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*body_text&lt;br /&gt;
*file_id (FK to mdl_files to see attachment size, etc)&lt;br /&gt;
*email_headers (if any)&lt;br /&gt;
*message_format (html or text)&lt;br /&gt;
&lt;br /&gt;
[[Image:moodle_message_log.png|ER diagram of tables]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reporting&#039;&#039;&#039;&lt;br /&gt;
Output headings suggested order (left to right)&lt;br /&gt;
*Message type&lt;br /&gt;
*Course category (with link to category)&lt;br /&gt;
*Course (with link to course)&lt;br /&gt;
*Component/module (with link to mod e.g. forum post/discussion etc)&lt;br /&gt;
*Peview body link (html/text)&lt;br /&gt;
*Sender Fullname (link to profile)&lt;br /&gt;
*Recipient Fullname (with link to profile)&lt;br /&gt;
*Recipient email/jabberid/mobile phoine number/etc sent to&lt;br /&gt;
*subject&lt;br /&gt;
*time sent&lt;br /&gt;
*status (success)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;filters&#039;&#039;&#039;&lt;br /&gt;
*Download as spreadsheet&lt;br /&gt;
*Paging number of users&lt;br /&gt;
*Filter by course&lt;br /&gt;
*Filter by activity&lt;br /&gt;
*Filter by user&lt;br /&gt;
*Filter by message_type&lt;br /&gt;
*Filter by sent datetime&lt;br /&gt;
*Filter by subject&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Tracker issue&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[https://tracker.moodle.org/browse/MDL-45160 Extend messaging system to log messages sent...]&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014/Email_Logging&amp;diff=44452</id>
		<title>Hackfest UK 2014/Email Logging</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Hackfest_UK_2014/Email_Logging&amp;diff=44452"/>
		<updated>2014-04-17T11:46:17Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Message Logging and Reporting&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Contact Names: (please add name if interested)&lt;br /&gt;
*Larry Zoumas (larry.zoumas@xtractor.se)&lt;br /&gt;
*Martin Sandberg (martin.sandberg@xtractor.se)&lt;br /&gt;
*David Aylmer (davidaylmer(a)hotmail.com)&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
*This plugin will allow admins and teachers to search through messages sent to users. The purpose is to easily answer the question of whether or not a user was notified of an important event, such as a face-to-face session, quiz deadline, etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Notes:&#039;&#039;&#039;&lt;br /&gt;
*Not all emails go through the messaging system. This needs to be investigated and fixed.&lt;br /&gt;
*We might want to allow a place for developers to add hooks or decorate this functionality.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Capabilities&#039;&#039;&#039;:&lt;br /&gt;
*Can view own messages&lt;br /&gt;
*Can view other messages&lt;br /&gt;
*Can view messages in your courses (teacher)&lt;br /&gt;
*Can view message body&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Options&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
*Optionally log body of message&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Proposed Table Schema&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*from (user_id)&lt;br /&gt;
*from_address (email address or identifier when the message was sent)&lt;br /&gt;
*message_type (FK mdl_message_provider)&lt;br /&gt;
*moduleid&lt;br /&gt;
*courseid&lt;br /&gt;
*subject &lt;br /&gt;
*body_id&lt;br /&gt;
*time&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log_user&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*message_log_id (FK to messaging log)&lt;br /&gt;
*userid&lt;br /&gt;
*to_address (email address or identifier when the message was sent)&lt;br /&gt;
*time&lt;br /&gt;
*status&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;messaging_log_body&#039;&#039;&#039;&lt;br /&gt;
*id&lt;br /&gt;
*body_text&lt;br /&gt;
*message_attachment_id (FK to file)&lt;br /&gt;
*email_headers (if any)&lt;br /&gt;
[[Image:moodle_message_log.png|ER diagram of tables]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reporting&#039;&#039;&#039;&lt;br /&gt;
*Filter by course&lt;br /&gt;
*Filter by activity&lt;br /&gt;
*Filter by user&lt;br /&gt;
*Filter by message_type&lt;br /&gt;
*Filter by sent datetime&lt;br /&gt;
*Filter by subject&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Common_unit_test_problems&amp;diff=42149</id>
		<title>Common unit test problems</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Common_unit_test_problems&amp;diff=42149"/>
		<updated>2013-08-21T14:16:44Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: /* !!! Error reading from database !!!!! Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier. */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Unit tests are taking more than 10 mins to run ===&lt;br /&gt;
This problem is under investigation. We are hoping to find the soluton. On a typical system all tests complete in under 6 mins.--[[User:Dan Poltawski|Dan Poltawski]] 12:43, 15 May 2012 (WST)&lt;br /&gt;
&lt;br /&gt;
You maybe find much better performance on psql as a workaround for now if not doing DB dependent tests.&lt;br /&gt;
&lt;br /&gt;
If using linux on an EXT4 file system, disabling barriers by adding barrier=0 to the end of the options in /etc/fstab for the drive should offer HUGE speed improvements. Note that this is very dangerous for system stability and in the event of a power failure can cause permanent and irrecoverable data loss.&lt;br /&gt;
&lt;br /&gt;
=== dml_testcase::test_unique_index_collation_trouble===&lt;br /&gt;
&amp;quot;Unique index is accent insensitive, this may cause problems for non-ascii languages. This is usually caused by accent insensitive default collation.&amp;quot;&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your Database is incorrectly configured. You probably are running MySQL and need to switch to utf8_bin collation.&lt;br /&gt;
&lt;br /&gt;
=== dml_testcase::test_sql_binary_equal ===&lt;br /&gt;
&amp;quot;SQL operator &amp;quot;=&amp;quot; is expected to be case sensitive Failed asserting that 1 matches expected 2.&amp;quot;&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your Database is incorrectly configured. You probably are running MySQL and need to switch to utf8_bin collation.&lt;br /&gt;
&lt;br /&gt;
=== moodlesimplepie_testcase::test_getfeed ===&lt;br /&gt;
&amp;quot;Failed to load the sample RSS file. Please check your proxy settings in Moodle. %s&amp;quot;&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your moodle needs network connectivity, please check proxy settings.&lt;br /&gt;
&lt;br /&gt;
=== moodlesimplepie_testcase::test_redirect ===&lt;br /&gt;
Failed asserting that &#039;cURL Error: Operation timed out after 2000 milliseconds with 0 bytes received&#039; is null.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your moodle needs network connectivity, please check proxy settings&lt;br /&gt;
&lt;br /&gt;
=== collatorlib_testcase::test_asort_objects_by_method ===&lt;br /&gt;
Collation aware sorting not supported, PHP extension &amp;quot;intl&amp;quot; is not available.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Install php intl extension.&lt;br /&gt;
&lt;br /&gt;
Note that, on Windows, this extension does not seem to be included in the installer, but you can get it by downloading the zip, and copying the right DLLs across. If you Google, there are more detailed instructions on Stack Exchange.&lt;br /&gt;
&lt;br /&gt;
=== grading_manager_testcase::test_tokenize===&lt;br /&gt;
A test using UTF-8 characters has failed. Consider updating PHP and PHP&#039;s PCRE or INTL extensions (MDL-30494) Failed asserting that false is true.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your Database is incorrectly configured. You probably are running MySQL and need to switch to utf8_bin collation.&lt;br /&gt;
&lt;br /&gt;
===  moodlelib_testcase::test_fix_utf8 ===&lt;br /&gt;
Failed asserting that false is identical to &#039;aaabbb&#039;.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
This problem indicates buggy iconv. See [http://tracker.moodle.org/browse/MDL-33007] for discussion.  So this is a real problem, to be fixed in a future integration cycle&lt;br /&gt;
&lt;br /&gt;
=== Segfaults on Oracle ===&lt;br /&gt;
When I was running tests on oracle I was getting phpunit sefaulting.. --[[User:Dan Poltawski|Dan Poltawski]] 00:29, 16 May 2012 (WST)&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Set statement_cache_size in php.ini:&lt;br /&gt;
oci8.statement_cache_size = 0&lt;br /&gt;
&lt;br /&gt;
=== filestoragelib_testcase::test_get_file_preview ===&lt;br /&gt;
Failed asserting that false is an instance of class &amp;quot;stored_file&amp;quot;.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Unfortunately, the php GD extension is a requirement for this test (see MDL-36447).&lt;br /&gt;
&lt;br /&gt;
Go to your Moodle directory and type &#039;php admin/tool/phpunit/cli/util.php --drop&#039;, then reinitialise PHPunit and run the test again.&lt;br /&gt;
&lt;br /&gt;
=== PHP Warning: include_once(PHPUnit/Extensions/Database/Autoload.php): failed to open stream ===&lt;br /&gt;
This occurs on Mac installs from experience. The reason this occurs is because DBUnit was not installed during the PHPUnit installation via PEAR.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
In terminal type: sudo pear install -f phpunit/DbUnit&lt;br /&gt;
&lt;br /&gt;
=== !!! Error reading from database !!!!! Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier. ===&lt;br /&gt;
If running unit tests under FreeTDS, remember that without a valid FREETDS environment variable, PHP won&#039;t be able to find the freetds.conf file and will default to version 5.0 which has poor support for unicode collations.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Ensure a FREETDS environment variable is set prior to running the automated tests, which points to a valid path that contains a freetds.conf file. Also ensure the tds version element is set to a recent enough version (8.0)&lt;br /&gt;
Note: Another potential solution may be to set TDSVER (http://freetds.schemamania.org/userguide/freetdsconf.htm)&lt;br /&gt;
[[Category:Unit testing]]&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Common_unit_test_problems&amp;diff=42148</id>
		<title>Common unit test problems</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Common_unit_test_problems&amp;diff=42148"/>
		<updated>2013-08-21T14:10:44Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Unit tests are taking more than 10 mins to run ===&lt;br /&gt;
This problem is under investigation. We are hoping to find the soluton. On a typical system all tests complete in under 6 mins.--[[User:Dan Poltawski|Dan Poltawski]] 12:43, 15 May 2012 (WST)&lt;br /&gt;
&lt;br /&gt;
You maybe find much better performance on psql as a workaround for now if not doing DB dependent tests.&lt;br /&gt;
&lt;br /&gt;
If using linux on an EXT4 file system, disabling barriers by adding barrier=0 to the end of the options in /etc/fstab for the drive should offer HUGE speed improvements. Note that this is very dangerous for system stability and in the event of a power failure can cause permanent and irrecoverable data loss.&lt;br /&gt;
&lt;br /&gt;
=== dml_testcase::test_unique_index_collation_trouble===&lt;br /&gt;
&amp;quot;Unique index is accent insensitive, this may cause problems for non-ascii languages. This is usually caused by accent insensitive default collation.&amp;quot;&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your Database is incorrectly configured. You probably are running MySQL and need to switch to utf8_bin collation.&lt;br /&gt;
&lt;br /&gt;
=== dml_testcase::test_sql_binary_equal ===&lt;br /&gt;
&amp;quot;SQL operator &amp;quot;=&amp;quot; is expected to be case sensitive Failed asserting that 1 matches expected 2.&amp;quot;&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your Database is incorrectly configured. You probably are running MySQL and need to switch to utf8_bin collation.&lt;br /&gt;
&lt;br /&gt;
=== moodlesimplepie_testcase::test_getfeed ===&lt;br /&gt;
&amp;quot;Failed to load the sample RSS file. Please check your proxy settings in Moodle. %s&amp;quot;&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your moodle needs network connectivity, please check proxy settings.&lt;br /&gt;
&lt;br /&gt;
=== moodlesimplepie_testcase::test_redirect ===&lt;br /&gt;
Failed asserting that &#039;cURL Error: Operation timed out after 2000 milliseconds with 0 bytes received&#039; is null.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your moodle needs network connectivity, please check proxy settings&lt;br /&gt;
&lt;br /&gt;
=== collatorlib_testcase::test_asort_objects_by_method ===&lt;br /&gt;
Collation aware sorting not supported, PHP extension &amp;quot;intl&amp;quot; is not available.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Install php intl extension.&lt;br /&gt;
&lt;br /&gt;
Note that, on Windows, this extension does not seem to be included in the installer, but you can get it by downloading the zip, and copying the right DLLs across. If you Google, there are more detailed instructions on Stack Exchange.&lt;br /&gt;
&lt;br /&gt;
=== grading_manager_testcase::test_tokenize===&lt;br /&gt;
A test using UTF-8 characters has failed. Consider updating PHP and PHP&#039;s PCRE or INTL extensions (MDL-30494) Failed asserting that false is true.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Your Database is incorrectly configured. You probably are running MySQL and need to switch to utf8_bin collation.&lt;br /&gt;
&lt;br /&gt;
===  moodlelib_testcase::test_fix_utf8 ===&lt;br /&gt;
Failed asserting that false is identical to &#039;aaabbb&#039;.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
This problem indicates buggy iconv. See [http://tracker.moodle.org/browse/MDL-33007] for discussion.  So this is a real problem, to be fixed in a future integration cycle&lt;br /&gt;
&lt;br /&gt;
=== Segfaults on Oracle ===&lt;br /&gt;
When I was running tests on oracle I was getting phpunit sefaulting.. --[[User:Dan Poltawski|Dan Poltawski]] 00:29, 16 May 2012 (WST)&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Set statement_cache_size in php.ini:&lt;br /&gt;
oci8.statement_cache_size = 0&lt;br /&gt;
&lt;br /&gt;
=== filestoragelib_testcase::test_get_file_preview ===&lt;br /&gt;
Failed asserting that false is an instance of class &amp;quot;stored_file&amp;quot;.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Unfortunately, the php GD extension is a requirement for this test (see MDL-36447).&lt;br /&gt;
&lt;br /&gt;
Go to your Moodle directory and type &#039;php admin/tool/phpunit/cli/util.php --drop&#039;, then reinitialise PHPunit and run the test again.&lt;br /&gt;
&lt;br /&gt;
=== PHP Warning: include_once(PHPUnit/Extensions/Database/Autoload.php): failed to open stream ===&lt;br /&gt;
This occurs on Mac installs from experience. The reason this occurs is because DBUnit was not installed during the PHPUnit installation via PEAR.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
In terminal type: sudo pear install -f phpunit/DbUnit&lt;br /&gt;
&lt;br /&gt;
=== !!! Error reading from database !!!!! Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier. ===&lt;br /&gt;
If running unit tests under FreeTDS, remember that without a valid FREETDS environment variable, PHP won&#039;t be able to find the freetds.conf file and will default to version 3.7 which has poor support for unicode collations.&lt;br /&gt;
==== Solution ====&lt;br /&gt;
Ensure a FREETDS environment variable is set prior to running the automated tests, which points to a valid path that contains a freetds.conf file. Also ensure the tds version element is set to a recent enough version (8.0)&lt;br /&gt;
&lt;br /&gt;
[[Category:Unit testing]]&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Acceptance_testing&amp;diff=41669</id>
		<title>Acceptance testing</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Acceptance_testing&amp;diff=41669"/>
		<updated>2013-07-30T19:43:52Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: /* Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This page describes how we describe Moodle&#039;s functionalities and how we automatically test all of them.&lt;br /&gt;
&lt;br /&gt;
Behat is a behavioural driven development (BDD) tool written in PHP, it can parse a human-readable list of sentences (called steps) and execute actions in a browser using Selenium or other tools to simulate users interactions.&lt;br /&gt;
&lt;br /&gt;
For technical info: [[Behat integration]]&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
Behat parses and executes features files which describes Moodle&#039;s features (for example &#039;&#039;Post in a forum&#039;&#039;), each feature file is composed by many scenarios (for example &#039;&#039;Add a post to a discussion&#039;&#039; or &#039;&#039;Create a new discussion&#039;&#039;), and finally each scenario is composed by steps (for example  &#039;&#039;I press &amp;quot;Post to Forum&amp;quot;&#039;&#039; or &#039;&#039;I should see &amp;quot;My post title&amp;quot;&#039;&#039;). When the feature file is executed, every step internally is translated into an PHP method and is executed.&lt;br /&gt;
&lt;br /&gt;
This features are executed nightly in the HQ servers with all the supported databases (MySQL, PostgreSQL, MSSQL and Oracle) and with different browsers (Firefox, Internet Explorer, Safari and Chrome) to avoid regressions and test new functionalities.&lt;br /&gt;
&lt;br /&gt;
=== Examples ===&lt;br /&gt;
&lt;br /&gt;
* There is a closed list of steps to use in the features, a feature written with the basic (or low-level) steps looks like this:&lt;br /&gt;
  @auth&lt;br /&gt;
  &#039;&#039;&#039;Feature&#039;&#039;&#039;: Login&lt;br /&gt;
    In order to login&lt;br /&gt;
    As a moodle user&lt;br /&gt;
    I need to be able to validate the username and password against moodle&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Login as an existing user&lt;br /&gt;
      Given I am on &amp;quot;login/index.php&amp;quot;&lt;br /&gt;
      When I fill in &amp;quot;username&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
      And I fill in &amp;quot;password&amp;quot; with &amp;quot;moodle&amp;quot;&lt;br /&gt;
      And I press &amp;quot;loginbtn&amp;quot;&lt;br /&gt;
      Then I should see &amp;quot;Moodle 101: Course Name&amp;quot;&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Login as an unexisting user&lt;br /&gt;
      Given I am on &amp;quot;login/index.php&amp;quot;&lt;br /&gt;
      When I fill in &amp;quot;username&amp;quot; with &amp;quot;admin&amp;quot;&lt;br /&gt;
      And I fill in &amp;quot;password&amp;quot; with &amp;quot;moodle&amp;quot;&lt;br /&gt;
      And I press &amp;quot;loginbtn&amp;quot;&lt;br /&gt;
      Then I should see &amp;quot;Moodle 101: Course Name&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note that The 3 sentences below &#039;&#039;Feature: Login&#039;&#039; are only information about what we want to test.&lt;br /&gt;
&lt;br /&gt;
These are simple scenarios, but most of Moodle&#039;s functionalities would require a huge list of this steps to test a scenario, imagine a &#039;&#039;Add a post to a discussion&#039;&#039; scenario; you need to login, create a course, create a user and enrol it in the course... Most of this steps is not what we intend to test in a &#039;&#039;Post in a forum&#039;&#039; feature, Moodle provides extra steps to quickly set up the context required to test a Moodle feature, for example:&lt;br /&gt;
&lt;br /&gt;
  @mod @mod_forum&lt;br /&gt;
  &#039;&#039;&#039;Feature&#039;&#039;&#039;: Add forum activities and discussions&lt;br /&gt;
    In order to discuss topics with other users&lt;br /&gt;
    As a moodle teacher&lt;br /&gt;
    I need to add forum activities to moodle courses&lt;br /&gt;
    &lt;br /&gt;
    &#039;&#039;&#039;Scenario&#039;&#039;&#039;: Add a forum and a discussion&lt;br /&gt;
      &#039;&#039;&#039;Given&#039;&#039;&#039; the following &amp;quot;users&amp;quot; exists:&lt;br /&gt;
        | username | firstname | lastname | email |&lt;br /&gt;
        | teacher1 | Teacher | 1 | teacher1@asd.com |&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; the following &amp;quot;courses&amp;quot; exists:&lt;br /&gt;
        | fullname | shortname | category |&lt;br /&gt;
        | Course 1 | C1 | 0 |&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; the following &amp;quot;course enrolments&amp;quot; exists:&lt;br /&gt;
        | user | course | role |&lt;br /&gt;
        | teacher1 | C1 | editingteacher |&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; I log in as &amp;quot;teacher1&amp;quot;&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; I follow &amp;quot;Course 1&amp;quot;&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; I turn editing mode on&lt;br /&gt;
      &#039;&#039;&#039;And&#039;&#039;&#039; I add a &amp;quot;Forum&amp;quot; to section &amp;quot;1&amp;quot; and I fill the form with:&lt;br /&gt;
        | Forum name | Test forum name |&lt;br /&gt;
        | Forum type | Standard forum for general use |&lt;br /&gt;
        | Description | Test forum description |&lt;br /&gt;
      &#039;&#039;&#039;When&#039;&#039;&#039; I add a new discussion to &amp;quot;Test forum name&amp;quot; forum with:&lt;br /&gt;
        | Subject | Forum post subject |&lt;br /&gt;
        | Message | This is the body |&lt;br /&gt;
      &#039;&#039;&#039;Then&#039;&#039;&#039; I should see &amp;quot;Test forum name&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Note that:&lt;br /&gt;
&lt;br /&gt;
* Each scenario is executed in an isolated testing environment, so the first step begins with an empty moodle site and what you set up in an scenario (like the &#039;&#039;Test forum name&#039;&#039; forum in the example above) is cleaned up after the scenario execution&lt;br /&gt;
* The prefixes &amp;quot;Given&amp;quot;, &amp;quot;When&amp;quot; and &amp;quot;Then&amp;quot; are only informative and they are used to define the context (Given), specify the action (When) and check the results (Then), using them properly helps to understand what the scenario is testing.&lt;br /&gt;
&lt;br /&gt;
== Quick start ==&lt;br /&gt;
&lt;br /&gt;
This is a quick introduction to write a functional test (acceptance tests) using steps in a development/testing site, please DON&#039;T USE THIS IN A PRODUCTION SITE.&lt;br /&gt;
&lt;br /&gt;
To let you experience the pleasure of watching a feature file doing &amp;quot;your work&amp;quot; automatically in a real browser, this guide includes 2 optional steps to download Selenium and run it in another CLI.&lt;br /&gt;
&lt;br /&gt;
# Open a command line interface&lt;br /&gt;
# &#039;&#039;&#039;cd /to/your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
# Edit config.php adding the following lines before the lib/setup.php include&lt;br /&gt;
#: &amp;lt;code language=&amp;quot;text&amp;quot;&amp;gt;$CFG-&amp;gt;behat_prefix = &#039;b_&#039;;&lt;br /&gt;
$CFG-&amp;gt;behat_dataroot = &#039;/path/to/your/behat/dataroot/directory&#039;;&lt;br /&gt;
$CFG-&amp;gt;behat_switchcompletely = true;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;curl http://getcomposer.org/installer | php&#039;&#039;&#039; (In case you have problems read https://docs.moodle.org/dev/Acceptance_testing#Installation)&lt;br /&gt;
# &#039;&#039;&#039;php admin/tool/behat/cli/init.php&#039;&#039;&#039;&lt;br /&gt;
# Download selenium-server-standalone-2.NN.N.jar from http://seleniumhq.org/download/, under &amp;quot;Selenium server (formerly the Selenium RC Server)&amp;quot;&lt;br /&gt;
# Open another command line interface and run &#039;&#039;&#039;java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;vendor/bin/behat --config /path/to/your/behat/dataroot/directory/behat/behat.yml&#039;&#039;&#039;&lt;br /&gt;
# You just ran the current Moodle tests, now let&#039;s add your own test, add a blog entry for example&lt;br /&gt;
# Browse to your $CFG-&amp;gt;wwwroot, this is an empty test site and it is reset before each test (called scenario)&lt;br /&gt;
# From this point follow the steps you would follow to add manually a blog entry (login credentials are admin/admin)&lt;br /&gt;
# When you are done go to &#039;Site administration&#039; -&amp;gt; &#039;Development&#039; -&amp;gt; &#039;Acceptance testing&#039;, you will find the list of &amp;quot;actions&amp;quot; that can be run automatically, you can filter them to find what do you need to do (more steps can be added if you need, more info in https://docs.moodle.org/dev/Acceptance_testing#Adding_steps_definitions)&lt;br /&gt;
# To &#039;add a blog entry&#039; we need to:&lt;br /&gt;
## Log in the system as a valid user&lt;br /&gt;
## Expand &#039;My profile&#039; node of the navigation block&lt;br /&gt;
## Expand the &#039;Blogs&#039; node of the navigation block&lt;br /&gt;
## Follow he &#039;Add a new entry&#039; link&lt;br /&gt;
## Fill the moodle form with values for &#039;Entry title&#039; and &#039;Blog entry body&#039;&lt;br /&gt;
## Press the &#039;Save changes&#039; button&lt;br /&gt;
## Verify you see the values you entered in the form and verify you are not in the form page&lt;br /&gt;
# This translated to steps is:&lt;br /&gt;
#: &amp;lt;code language=&amp;quot;text&amp;quot;&amp;gt;Given I log in as &amp;quot;admin&amp;quot;&lt;br /&gt;
And I expand &amp;quot;My profile&amp;quot; node&lt;br /&gt;
And I expand &amp;quot;Blogs&amp;quot; node&lt;br /&gt;
And I follow &amp;quot;Add a new entry&amp;quot;&lt;br /&gt;
And I fill the moodle form with:&lt;br /&gt;
  | Entry title | I&#039;m the name |&lt;br /&gt;
  | Blog entry body | I&#039;m the description |&lt;br /&gt;
When I press &amp;quot;Save changes&amp;quot;&lt;br /&gt;
Then I should see &amp;quot;Blog entries&amp;quot;&lt;br /&gt;
And I should see &amp;quot;I&#039;m the description&amp;quot;&lt;br /&gt;
And I should not see &amp;quot;Required&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
# We need to wrap this steps following the behaviour driven development guidelines (more info in https://docs.moodle.org/dev/Acceptance_testing#Writing_features)&lt;br /&gt;
#: &amp;lt;code language=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
@core @core_blog&lt;br /&gt;
Feature: Add a blog entry&lt;br /&gt;
  In order to let the world know about me&lt;br /&gt;
  As a user&lt;br /&gt;
  I need to write blog entries&lt;br /&gt;
&lt;br /&gt;
  @javascript&lt;br /&gt;
  Scenario: Add a blog entry with valid data&lt;br /&gt;
    Given I log in as &amp;quot;admin&amp;quot;&lt;br /&gt;
    And I expand &amp;quot;My profile&amp;quot; node&lt;br /&gt;
    And I expand &amp;quot;Blogs&amp;quot; node&lt;br /&gt;
    And I follow &amp;quot;Add a new entry&amp;quot;&lt;br /&gt;
    And I fill the moodle form with:&lt;br /&gt;
      | Entry title | I&#039;m the name |&lt;br /&gt;
      | Blog entry body | I&#039;m the description |&lt;br /&gt;
    When I press &amp;quot;Save changes&amp;quot;&lt;br /&gt;
    Then I should see &amp;quot;View all of my entries&amp;quot;&lt;br /&gt;
    And I should see &amp;quot;I&#039;m a description&amp;quot;&lt;br /&gt;
    And I should not see &amp;quot;Required&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
# And save it into a file, in this case &#039;&#039;&#039;blog/tests/behat/add_entry.feature&#039;&#039;&#039;&lt;br /&gt;
# &#039;&#039;&#039;php admin/tool/behat/cli/util.php --enable&#039;&#039;&#039;  (This will update the available tests and steps definitions)&lt;br /&gt;
# &#039;&#039;&#039;vendor/bin/behat --config /path/to/your/behat/dataroot/directory/behat/behat.yml --tags @core_blog&#039;&#039;&#039;&lt;br /&gt;
# Selenium will open a browser (firefox by default) and you will see how the steps you have been writting are executed&lt;br /&gt;
&lt;br /&gt;
You can also try to expand non existing nodes or change the &#039;Then&#039; assertions to get a beautiful failure.&lt;br /&gt;
&lt;br /&gt;
For detailed steps and/or troubleshooting:&lt;br /&gt;
* https://docs.moodle.org/dev/Acceptance_testing#Running_tests&lt;br /&gt;
* https://docs.moodle.org/dev/Acceptance_testing#Writing_features&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
* PHP 5.4 (see https://docs.moodle.org/dev/Acceptance_testing#Advanced_usage for PHP 5.3, only for non-production sites)&lt;br /&gt;
* Other dependencies are managed by the composer installer&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
* Edit config.php&lt;br /&gt;
** Use $CFG-&amp;gt;behat_dataroot to set the directory where behat test environment dataroot will be stored, something like &#039;&#039;&#039;$CFG-&amp;gt;behat_dataroot = &#039;/your/directory/path&#039;;&#039;&#039;&#039;. Ensure the directory can be created or have write permissions&lt;br /&gt;
** Use $CFG-&amp;gt;behat_prefix to set the database prefix of the behat test environment database tables, something like &#039;&#039;&#039;$CFG-&amp;gt;behat_prefix = &#039;behat_&#039;;&#039;&#039;&#039;&lt;br /&gt;
* Download composer&lt;br /&gt;
** &#039;&#039;&#039;cd /your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;curl http://getcomposer.org/installer | php&#039;&#039;&#039;&lt;br /&gt;
*** If you don&#039;t have curl installed or you have problems running &#039;&#039;&#039;curl http://getcomposer.org/installer | php&#039;&#039;&#039;:&lt;br /&gt;
**** Download &#039;&#039;&#039;http://getcomposer.org/installer&#039;&#039;&#039;&lt;br /&gt;
**** Store it in /your/moodle/dirroot/composerinstaller.php for example&lt;br /&gt;
**** Run it from /your/moodle/dirroot with &#039;&#039;&#039;php composerinstaller.php&#039;&#039;&#039;, you can delete this file after running the next step (&#039;&#039;&#039;php composer.phar update --dev&#039;&#039;&#039;)&lt;br /&gt;
* Install behat dependencies and enable the test environment&lt;br /&gt;
** &#039;&#039;&#039;cd /your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;php admin/tool/behat/cli/init.php&#039;&#039;&#039;&lt;br /&gt;
* (Optional) If you want to run tests that involves Javascript (most of them) you will also need Selenium&lt;br /&gt;
** Download it from http://seleniumhq.org/download/, named &amp;quot;Selenium server (formerly the Selenium RC Server)&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Running tests ==&lt;br /&gt;
# Start the PHP built-in web server&lt;br /&gt;
#* Open a command line interface and &#039;&#039;&#039;cd /to/your/moodle/dirroot&#039;&#039;&#039;&lt;br /&gt;
#* &#039;&#039;&#039;php -S localhost:8000&#039;&#039;&#039; (This is the default address, if you want to use another one you can override it in config.php with $CFG-&amp;gt;behat_wwwroot attribute; more info in https://docs.moodle.org/dev/Acceptance_testing#Advanced_usage)&lt;br /&gt;
# (Optional) Start the Selenium server (in case you want to run tests that involves Javascript)&lt;br /&gt;
#* Open another command line interface and &#039;&#039;&#039;java -jar /path/to/your/selenium/server/selenium-server-standalone-2.NN.N.jar&#039;&#039;&#039;&lt;br /&gt;
# Run Behat&lt;br /&gt;
#* &#039;&#039;&#039;vendor/bin/behat --config /path/to/your/CFG_behat_dataroot/behat/behat.yml&#039;&#039;&#039; (For more options &#039;&#039;&#039;vendor/bin/behat --help&#039;&#039;&#039; or http://docs.behat.org/guides/6.cli.html)&lt;br /&gt;
#* In case you don&#039;t want to run Javascript tests use the Behat tags option to skip them, &#039;&#039;&#039;vendor/bin/behat --tags ~@javascript --config /path/to/your/CFG_behat_dataroot/behat/behat.yml&#039;&#039;&#039;&lt;br /&gt;
# (Optional) If you are adding new tests or steps definitions update the tests list:&lt;br /&gt;
#* &#039;&#039;&#039;php admin/tool/behat/cli/util.php --enable&#039;&#039;&#039;&lt;br /&gt;
# (Optional) Disable test environment (in case you want to use the PHP built-in web server for regular moodle environment)&lt;br /&gt;
#* &#039;&#039;&#039;php admin/tool/behat/cli/util.php --disable&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Tests filters ===&lt;br /&gt;
With the &#039;&#039;&#039;--tags&#039;&#039;&#039; or the &#039;&#039;&#039;-name&#039;&#039;&#039; Behat options you can filter which tests are going to run or which ones are going to be skipped. There are few tags that you might be interested in:&lt;br /&gt;
* &#039;&#039;&#039;@javascript&#039;&#039;&#039;: All the tests that runs in a browser using Javascript; they require Selenium to be running, otherwise an exception will be thrown.&lt;br /&gt;
* &#039;&#039;&#039;@_only_local&#039;&#039;&#039;: All the tests that involves file uploading or any OS feature that is not 100% part of the browser. They should only be executed when Selenium is running in the same machine where the tests are running.&lt;br /&gt;
* &#039;&#039;&#039;@_cross_browser&#039;&#039;&#039;: All the tests that should run against multiple combinations of browsers + OS in a regular basis. The features that are sensitive to different combinations of OS and browsers should be tagges as @_cross_browser.&lt;br /&gt;
* &#039;&#039;&#039;@componentname&#039;&#039;&#039;: Moodle features uses the [https://docs.moodle.org/dev/Frankenstyle Frankenstyle] component name to tag the features according to the Moodle subsystem they belong to.&lt;br /&gt;
&lt;br /&gt;
== Advanced usage ==&lt;br /&gt;
There are a few settings for advanced use of Behat and execution in continuous integration systems, by default all this options are disabled, use this settings only if you know what you are doing.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Different test server URL&#039;&#039;&#039;, by default the test web server only can be accessed in localhost. If for example your are interested in allowing accesses from your local network because your Jenkins server is there you can set $CFG-&amp;gt;behat_wwwroot to &#039;&#039;&#039;http://my.computer.local.ip:8000&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Behat configuration&#039;&#039;&#039;, Moodle writes a behat.yml config file with info about the available tests and steps definitions along with other Behat parameters, you can override the Behat parameters we set and add your new parameters, your parameters will be merged with the Moodle ones giving priority to your values in case of conflict. This is useful for an advanced use of Behat, with multiple profiles, output formats, integration with continuous servers... &lt;br /&gt;
* &#039;&#039;&#039;Running with a browser other than Firefox&#039;&#039;&#039;, by adding the following code to your config.php you can change the selected browser that is run when behat is invoked. In this case Chrome is selected, but internet explorer, firefox, iphone, android, chrome, htmlunit should be valid options. You will need to run &#039;&#039;&#039;php admin/tool/behat/cli/init.php&#039;&#039;&#039; for changes to take effect.&lt;br /&gt;
&amp;lt;code language=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
$CFG-&amp;gt;behat_config = array(&lt;br /&gt;
    &#039;default&#039; =&amp;gt; array(&lt;br /&gt;
        &#039;extensions&#039; =&amp;gt; array(&lt;br /&gt;
            &#039;Behat\MinkExtension\Extension&#039; =&amp;gt; array(&lt;br /&gt;
                &#039;selenium2&#039; =&amp;gt; array(&lt;br /&gt;
                    &#039;browser&#039; =&amp;gt; &#039;chrome&#039;&lt;br /&gt;
                )&lt;br /&gt;
            )&lt;br /&gt;
        )&lt;br /&gt;
    )&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
:Note that for Chrome, you will need the Selenium Chrome Driver (https://code.google.com/p/selenium/wiki/ChromeDriver), and it will need to be installed in the command search path.&lt;br /&gt;
* &#039;&#039;&#039;Switch completely to test environment&#039;&#039;&#039;, DON&#039;T USE THIS SETTING IN PRODUCTION SITES! all the site users would be using the test environment instead of the regular one with your courses and all your data and they wouldn&#039;t be able to login in your site; this setting should only be used in development/testing installations. It&#039;s purpose is to ease the integration with cloud-based continuous integration systems, another possible use is to allow acceptance testing in a development environment without PHP 5.4.&lt;br /&gt;
** Note that when using cloud-based systems that can make use of non-standard capabilities like Saucelabs, you might want to provide configuration attributes containing the &#039;&#039;&#039;&#039;-&#039;&#039;&#039;&#039; character, which is automatically converted to &#039;&#039;&#039;&#039;_&#039;&#039;&#039;&#039; by the Symfony configuration manager that Behat is making use of (@see Symfony\Component\Config\Definition\Processor::normalizeKeys()) a way to avoid this restriction is to, adding to the vars you set like &#039;&#039;&#039;&#039;max-duration&#039;&#039;&#039;&#039; add the same var replacing dashes for underscores, this way the configuration manager will maintain the attribute containing dashes.&lt;br /&gt;
You can find more info and examples of how to use this settings in the config-dist.php file included in the Moodle codebase.&lt;br /&gt;
&lt;br /&gt;
== Writing features ==&lt;br /&gt;
&lt;br /&gt;
All Moodle components and plugins (including 3rd party plugins) can specify their tests in .feature files using all the available steps.&lt;br /&gt;
&lt;br /&gt;
Once you decided which functionality you want to specify as a feature you should:&lt;br /&gt;
# Select the most appropriate Moodle component to include your test and create a COMPONENTNAME/tests/behat/FEATURENAME.feature file&lt;br /&gt;
# Add a tag with the component name in Frankenstyle format (https://docs.moodle.org/dev/Frankenstyle) on the first line along with the plugin type or @core if it&#039;s a core subsystem&lt;br /&gt;
# Begin writing the user story of the feature, including in the &#039;As a ...&#039; statement the main beneficiary of the feature:&lt;br /&gt;
#: &amp;lt;code lang=&amp;quot;text&amp;quot;&amp;gt;@plugintype @plugintype_pluginname&lt;br /&gt;
Feature: FEATURENAME&lt;br /&gt;
  In order to ...    // Why this feature is useful&lt;br /&gt;
  As ...    // It can be &#039;an admin&#039;, &#039;a teacher&#039;, &#039;a student&#039;, &#039;a guest&#039;, &#039;a user&#039;, &#039;a tests writer&#039; and &#039;a developer&#039;&lt;br /&gt;
  I need to ...      // The feature we want&amp;lt;/code&amp;gt;&lt;br /&gt;
# From the beneficiary point of view, think of different scenarios to ensure the feature works as expected&lt;br /&gt;
# For each scenario you thought:&lt;br /&gt;
## Think of the initial context you need, for example &#039;&#039;1 course with 2 students on it and an assignment&#039;&#039;, and which steps do you need to follow (interacting with the browser) to verify the scenario works as expected&lt;br /&gt;
## What you are testing requires Javascript? Think only on the feature you are testing (for example if you want to test that you can view your profile you don&#039;t need Javascript to click on a link and assert against plain HTML, but if you want to test something related with the course&#039;s gradebook you might want to test it with Javascript)&lt;br /&gt;
## Check the steps list (more info in https://docs.moodle.org/dev/Acceptance_testing#Available_steps) and set the initial context data (see https://docs.moodle.org/dev/Acceptance_testing#Fixtures for more info) and the steps to follow to verify all works as it should work. Remember to use &#039;&#039;Given&#039;&#039;, &#039;&#039;When&#039;&#039; and &#039;&#039;Then&#039;&#039; in a way that reflects what the scenario is testing&lt;br /&gt;
## Copy the list of steps to the .feature file with the Scenario header:&lt;br /&gt;
##: &amp;lt;code lang=&amp;quot;text&amp;quot;&amp;gt;Scenario: Short description of the scenario&lt;br /&gt;
  Given step 1&lt;br /&gt;
  And step 2&lt;br /&gt;
  And step 3&lt;br /&gt;
  When step 4&lt;br /&gt;
  And step 5&lt;br /&gt;
  Then step 6&amp;lt;/code&amp;gt;&lt;br /&gt;
## If the steps you are using requires Javascript add the @javascript tag above the &amp;quot;Scenario:&amp;quot; headline&lt;br /&gt;
##:    &amp;lt;code lang=&amp;quot;text&amp;quot;&amp;gt;@javascript&lt;br /&gt;
Scenario: Short description of the scenario&lt;br /&gt;
  ...&lt;br /&gt;
  ...&amp;lt;/code&amp;gt;&lt;br /&gt;
# Run the tests, when creating your new features/scenarios you can specify a &#039;@wip&#039; (work in progress) tag in both the line above the Scenario description and the tests runner (vendor/bin/behat) to execute only the new scenario instead of running the whole set of tests.&lt;br /&gt;
# Add extra tags to the scenario or the feature if required&lt;br /&gt;
#* If there are scenarios that includes files uploads they should be tagged as @_only_local&lt;br /&gt;
#* If there are scenarios that are likely to fail in some browser-OS combinations they can be tagged as @_cross_browser, they will be tested in different OS / browser combinations by Moodle HQ continuous integration servers&lt;br /&gt;
&lt;br /&gt;
=== Available steps ===&lt;br /&gt;
&lt;br /&gt;
Moodle provides a interface to list and filter the steps you can use when writing features. You can access it through the Administration block, following &#039;&#039;&#039;Site Administration&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Development&#039;&#039;&#039; -&amp;gt; &#039;&#039;&#039;Acceptance testing&#039;&#039;&#039;. It allows filtering by keyword, by the Moodle component or by the type of step:&lt;br /&gt;
* Processes to set up the environment&lt;br /&gt;
* Actions that provokes an event&lt;br /&gt;
* Checkings to ensure the outcomes are the expected ones&lt;br /&gt;
&lt;br /&gt;
[[File:Acceptance_testing_UI_2.5.png]]&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
* You can use a &#039;&#039;&#039;Background&#039;&#039;&#039; section before the &#039;&#039;&#039;Scenario&#039;&#039;&#039; sections, this steps will be executed before the steps of each scenario (http://docs.behat.org/guides/1.gherkin.html#backgrounds)&lt;br /&gt;
* You can use &#039;&#039;&#039;Scenario outlines&#039;&#039;&#039; if your scenarios are nearly the same and depends on a few vars; check out the link for an explicative example (http://docs.behat.org/guides/1.gherkin.html#scenario-outlines)&lt;br /&gt;
* Is better to test the outcomes against the given data than against language strings, which are depending on the selected language.&lt;br /&gt;
* In case you need to interact with popup windows you need to switch to the window you want to interact with after opening it using the &#039;&#039;&#039;I switch to &amp;quot;popupwindowname&amp;quot; window&#039;&#039;&#039;, close it when you finish interacting with it and return to the main window using &#039;&#039;&#039;I switch to main window&#039;&#039;&#039;&lt;br /&gt;
* The format of the .feature files is YAML which finds out the data hierarchy from the indentation of it&#039;s elements, so be sure that the elements are correctly nested and the indentation is correct using spaces when necessary&lt;br /&gt;
&lt;br /&gt;
=== Providing values to steps ===&lt;br /&gt;
Most of the steps requires values, there are four methods to provide values to steps, the method depends on the step specification, you can know when a steps requires a value because you will see a drop down menu with a closed list of options that the step accepts as argument or an upper case string between double quotes, something like &#039;&#039;&#039;I press &amp;quot;BUTTON_STRING&amp;quot;&#039;&#039;&#039; or it ends with a &#039;&#039;&#039;:&#039;&#039;&#039; . The three methods are:&lt;br /&gt;
* &#039;&#039;&#039;A string/text&#039;&#039;&#039;; is the most common case, the texts are wrapped between double quotes (&amp;quot; character) you have to replace the info about the expected value for your value; for example something like &#039;&#039;&#039;I press &amp;quot;BUTTON_STRING&amp;quot;&#039;&#039;&#039; should become &#039;&#039;&#039;I press &amp;quot;Save and return to course&amp;quot;&#039;&#039;&#039;. If you want to add a string which contains a &amp;quot; character, you can escape it with \&amp;quot;, for example &#039;&#039;&#039;I fill the &amp;quot;Name&amp;quot; field with &amp;quot;Alan alias \&amp;quot;the legend\&amp;quot;&amp;quot;&#039;&#039;&#039;. You can identify this steps because they ends with &#039;&#039;&#039;_STRING&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;A number&#039;&#039;&#039;; some steps requires numbers as values, to be more specific an undetermined number of digits from 0 to 9 (Natural numbers + 0) you can identify them because the expected value info string ends with &#039;&#039;&#039;_NUMBER&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;A table&#039;&#039;&#039;; is a relation between values, the most common use of it is to fill forms. The steps which requires tables are easily identifiable because they finish with &#039;&#039;&#039;:&#039;&#039;&#039; The steps description gives info about what the table columns must contain, for example &#039;&#039;&#039;Fills a moodle form with field/value data&#039;&#039;&#039;. Here you don&#039;t need to escape the double quotes if you want to include them as part of the value.&lt;br /&gt;
* &#039;&#039;&#039;A selector&#039;&#039;&#039;; there are steps that can be used with different kinds of elements, for example &#039;&#039;&#039;I click on &amp;quot;User Name&amp;quot; &amp;quot;link&amp;quot;&#039;&#039;&#039; or &#039;&#039;&#039;I click on &amp;quot;User Name&amp;quot; &amp;quot;button&amp;quot;&#039;&#039;&#039; this is a closed list of elements, in the &#039;Acceptance testing&#039; interface you can see a dropdown menu to select one of these options:&lt;br /&gt;
** field - for searching a field by its id, name, value or label&lt;br /&gt;
** fieldset - for searching a fieldset by it&#039;s id or legend&lt;br /&gt;
** link - for searching a link by its href, id, title, img alt or value&lt;br /&gt;
** button - for searching a button by its name, id, value, img alt or title&lt;br /&gt;
** link_or_button - for searching for both, links and buttons&lt;br /&gt;
** select - for searching a select field by its id, name or label&lt;br /&gt;
** checkbox - for searching a checkbox by its id, name, or label&lt;br /&gt;
** radio - for searching a radio button by its id, name, or label&lt;br /&gt;
** file - for searching a file input by its id, name, or label&lt;br /&gt;
** optgroup - for searching optgroup by its label&lt;br /&gt;
** option - for searching an option by its content&lt;br /&gt;
** table - for searching a table by its id or caption&lt;br /&gt;
** css_element - for searching an element by its CSS selector&lt;br /&gt;
** xpath_element - for searching an element by its XPath&lt;br /&gt;
&lt;br /&gt;
==== Uploading files ====&lt;br /&gt;
Note than some tests requires files to be uploaded, in this case&lt;br /&gt;
* The &#039;&#039;&#039;I upload &amp;quot;FILEPATH_STRING&amp;quot; file to &amp;quot;FILEPICKER_FIELD_STRING&amp;quot; filepicker&#039;&#039;&#039; step can be used when located in the form page&lt;br /&gt;
* The file to upload should be included along with the Moodle codebase in COMPONENTNAME/tests/fixtures/*&lt;br /&gt;
* The file to upload is specified by it&#039;s path, which should be relative to the codebase root (&#039;&#039;&#039;lib/tests/fixtures/users.csv&#039;&#039;&#039; for example) &lt;br /&gt;
* &#039;&#039;&#039;/&#039;&#039;&#039; should be used as directory separator and the file names can not include this &#039;&#039;&#039;/&#039;&#039;&#039; character as all of them would be converted to the OS-dependant directory separator to maintain the compatibility with Windows systems.&lt;br /&gt;
* The scenarios that includes files uploading should be tagged using the &#039;&#039;&#039;@_only_local&#039;&#039;&#039; tag&lt;br /&gt;
&lt;br /&gt;
=== Fixtures ===&lt;br /&gt;
&lt;br /&gt;
As seen in [[https://docs.moodle.org/dev/Acceptance_testing#Examples examples]] Moodle provides a way to quickly set up the contextual data (courses, users, enrolments...) that you need to properly test scenarios, this can be done using one of the site templates (TODO) or creating entities in the background section (common for all the steps) or in the &amp;quot;Given&amp;quot; part of your scenario. Note that this steps can only be used to set up the contextual data required to test the feature but they don&#039;t test what they are doing; for example, the &amp;quot;Given the following &amp;quot;users&amp;quot; exists&amp;quot; is not testing that Moodle is able to create a user, but to test that a user can add a blog entry you might want to use this step. For further info, acceptance tests are supposed to be black-boxed tests (the tester don&#039;t know about the internals of the application) and this steps are using internal Moodle data generators instead of running all the steps required to create a user or to create a course, which speeds up the test execution. There are other features to test that all this elements can be properly created.&lt;br /&gt;
&lt;br /&gt;
==== Available elements ====&lt;br /&gt;
Most of the available elements can only be created in relation to other elements, to hide the complexity of the Moodle internals (references by contexts, ids...) the references can be done using more human-friendly mappings. &lt;br /&gt;
&lt;br /&gt;
The examples below shows how to add elements referencing other elements, there are required fields to reference the elements, other attributes will be filled with random data if they are not specified.&lt;br /&gt;
&lt;br /&gt;
* Course categories&lt;br /&gt;
** The required field is idnumber&lt;br /&gt;
** References between parent/children by their idnumber, using the &amp;quot;category&amp;quot; field&lt;br /&gt;
  Given the following &amp;quot;categories&amp;quot; exists:&lt;br /&gt;
    | name       | category | idnumber |&lt;br /&gt;
    | Category 1 | 0        | CAT1     |&lt;br /&gt;
    | Category 2 | CAT1     | CAT2     |&lt;br /&gt;
&lt;br /&gt;
* Courses&lt;br /&gt;
** The required field is shortname&lt;br /&gt;
** Uses the category idnumber as category reference&lt;br /&gt;
  Given the following &amp;quot;courses&amp;quot; exists:&lt;br /&gt;
    | fullname | shortname | category | format | &lt;br /&gt;
    | Course 1 | COURSE1   | CAT1     | topics |&lt;br /&gt;
    | Course 2 | COURSE2   | CAT2     |        |&lt;br /&gt;
&lt;br /&gt;
* Groups&lt;br /&gt;
** The required fields are course and idnumber&lt;br /&gt;
** Uses the course shortname as course reference&lt;br /&gt;
  Given the following &amp;quot;groups&amp;quot; exists:&lt;br /&gt;
    | name    | description | course  | idnumber |&lt;br /&gt;
    | Group 1 | Anything    | COURSE1 | GROUP1   |&lt;br /&gt;
&lt;br /&gt;
* Groupings&lt;br /&gt;
** The required fields are course and idnumber&lt;br /&gt;
** Uses the course shortname as course reference&lt;br /&gt;
  Given the following &amp;quot;groupings&amp;quot; exists:&lt;br /&gt;
    | name       | course  | idnumber  |&lt;br /&gt;
    | Grouping 1 | COURSE1 | GROUPING1 |&lt;br /&gt;
    | Grouping 2 | COURSE1 | GROUPING2 |&lt;br /&gt;
&lt;br /&gt;
* Users&lt;br /&gt;
** The required field is username (if password is not set username value will be used as password too)&lt;br /&gt;
  Given the following &amp;quot;users&amp;quot; exists:&lt;br /&gt;
    | username | email       | firstname | lastname |&lt;br /&gt;
    | testuser | asd@asd.com | Test      | User     |&lt;br /&gt;
&lt;br /&gt;
* Course enrolments&lt;br /&gt;
** The required fields are user, course and role&lt;br /&gt;
** Uses the course shortname as course reference&lt;br /&gt;
** Uses the user username as user reference&lt;br /&gt;
** Uses the role shortname as role reference&lt;br /&gt;
** Uses the enrolment name as enrol reference&lt;br /&gt;
  Given the following &amp;quot;course enrolments&amp;quot; exists:&lt;br /&gt;
    | user     | course  | role           | enrol  |&lt;br /&gt;
    | testuser | COURSE1 | editingteacher | manual |&lt;br /&gt;
&lt;br /&gt;
* System role assigns&lt;br /&gt;
** The required fields are user and role&lt;br /&gt;
** Uses the user username as user reference&lt;br /&gt;
** Uses the role shortname as role reference&lt;br /&gt;
  Given the following &amp;quot;system role assigns&amp;quot; exists:&lt;br /&gt;
    | user     | role    |&lt;br /&gt;
    | testuser | manager |&lt;br /&gt;
&lt;br /&gt;
* Group members&lt;br /&gt;
** The required fields are user and group&lt;br /&gt;
** Uses the group idnumber as group reference&lt;br /&gt;
** Uses the user username as user reference&lt;br /&gt;
  Given the following &amp;quot;group members&amp;quot; exists:&lt;br /&gt;
    | user     | group  |&lt;br /&gt;
    | testuser | GROUP1 |&lt;br /&gt;
&lt;br /&gt;
* Grouping groups&lt;br /&gt;
** The required fields are grouping and group&lt;br /&gt;
** Uses the group idnumber as group reference&lt;br /&gt;
** Uses the grouping idnumber as grouping reference&lt;br /&gt;
  Given the following &amp;quot;grouping groups&amp;quot; exists:&lt;br /&gt;
    | grouping  | group  |&lt;br /&gt;
    | GROUPING1 | GROUP1 |&lt;br /&gt;
&lt;br /&gt;
* Cohorts&lt;br /&gt;
** The required field is idnumber&lt;br /&gt;
  Given the following &amp;quot;cohorts&amp;quot; exists:&lt;br /&gt;
    | name     | idnumber |&lt;br /&gt;
    | Cohort 1 | COHORT1  |&lt;br /&gt;
&lt;br /&gt;
=== Features check list ===&lt;br /&gt;
* It&#039;s a new feature or a new scenario of an existing feature&lt;br /&gt;
* Is using the &#039;&#039;&#039;Background&#039;&#039;&#039; section or &#039;&#039;&#039;Scenario Outlines&#039;&#039;&#039; instead of duplicating steps (only when applicable)&lt;br /&gt;
* Are using the appropriate Moodle component tag and includes @_only_local or @_cross_browser when required&lt;br /&gt;
* The user story of the feature includes a valid stakeholder and makes sense according to https://docs.moodle.org/dev/Acceptance_testing#Writing_features&lt;br /&gt;
* Covers both JS and non-JS environments&lt;br /&gt;
&lt;br /&gt;
== Adding steps definitions ==&lt;br /&gt;
&lt;br /&gt;
Each Moodle component and plugin (including 3rd party plugins) can add new steps definitions. If you are writing tests and you notice that you are repeating the same group of steps you might want to create a new step definition that allows you to substitute the group of steps for one single step, something like &#039;&#039;I add a forum post with &amp;quot;blablabla&amp;quot; as description&#039;&#039; for example; also you can create whole new steps using the APIs provided by Behat and Mink if what you need to do is not covered by any of the available steps.&lt;br /&gt;
&lt;br /&gt;
=== Example ===&lt;br /&gt;
&lt;br /&gt;
You can use this example below or any of the existing steps definitions as a template.&lt;br /&gt;
&lt;br /&gt;
* auth/tests/behat/behat_auth.php&lt;br /&gt;
  class behat_auth extends behat_base {&lt;br /&gt;
      /**&lt;br /&gt;
       * Logs in the user. There should exist a user with the same value as username and password&lt;br /&gt;
       *&lt;br /&gt;
       * @Given /^I log in as &amp;quot;(?P&amp;lt;username_string&amp;gt;(?:[^&amp;quot;]|\\&amp;quot;)*)&amp;quot;$/&lt;br /&gt;
       */&lt;br /&gt;
      public function i_log_in_as($username) {&lt;br /&gt;
          return array(new Given(&#039;I am on homepage&#039;),&lt;br /&gt;
              new Given(&#039;I follow &amp;quot;Login&amp;quot;&#039;),&lt;br /&gt;
              new Given(&#039;I fill in &amp;quot;Username&amp;quot; with &amp;quot;&#039;.$username.&#039;&amp;quot;&#039;),&lt;br /&gt;
              new Given(&#039;I fill in &amp;quot;Password&amp;quot; with &amp;quot;&#039;.$username.&#039;&amp;quot;&#039;),&lt;br /&gt;
              new Given(&#039;I press &amp;quot;Login&amp;quot;&#039;),&lt;br /&gt;
              new Given(&#039;I should see &amp;quot;You are logged in as&amp;quot;&#039;));&lt;br /&gt;
      }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
=== Tips ===&lt;br /&gt;
&lt;br /&gt;
If you are creating a completely new step definition there are also a few things to consider:&lt;br /&gt;
* Steps definitions should be compatible with both Javascript and non-Javascript tests, you can use $this-&amp;gt;running_javascript() to deal with both&lt;br /&gt;
* The definition code will be executed by Behat, not by Moodle, you have to keep this in mind for example when throwing exceptions, Behat exceptions will give more info to the user about where is the problem&lt;br /&gt;
** You can find these exceptions in &#039;&#039;&#039;vendor/behat/mink/src/Behat/Mink/Exception/*&#039;&#039;&#039;&lt;br /&gt;
* Selenium is fast, sometimes it tries to interact with DOM elements or tries to execute actions that requires JS that are not loaded or ready to used; this is why, sometimes and randomly, you can see an &amp;quot;element not found&amp;quot; failure&lt;br /&gt;
** The quickest way to solve this problem is using behat_base::find*() methods (where the * corresponds to &#039;&#039;&#039;&amp;lt;nowiki&amp;gt;&#039;&#039;&amp;lt;/nowiki&amp;gt;&#039;&#039;&#039;, &#039;&#039;&#039;_all&#039;&#039;&#039;, or to a named selector preceded by &#039;&#039;&#039;_&#039;&#039;&#039;, http://mink.behat.org/#named-selectors) which only requires the locator as argument. This methods will wait for the requested element to be ready or return an exception if the element is not found after the timeout value expires, you can also force the timeout value, which defaults to 6 seconds. An example of a named selector use is &#039;&#039;&#039;$button = $this-&amp;gt;find_button(&amp;quot;Save changes&amp;quot;);&#039;&#039;&#039; if you are not sure about the element being available you always can wrap the find*() call in a try &amp;amp; catch.&lt;br /&gt;
** For advanced usages, the spin method is defined in &#039;&#039;&#039;lib/behat/behat_base::spin&#039;&#039;&#039;, consider that all the contents of the closures passed to spin() can be executed more than once, so don&#039;t use irreversible actions that can invalidate the tests results (for example use find() methods but don&#039;t use click() methods)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If you create new steps definitions or tests you must run &#039;&#039;&#039;php admin/tool/behat/cli/util.php --enable&#039;&#039;&#039; to update the Behat config file before running &#039;&#039;&#039;vendor/bin/behat&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Check list ===&lt;br /&gt;
&lt;br /&gt;
New steps should be/have:&lt;br /&gt;
* Implemented as public methods of a PHP class whose name must begin with &#039;behat_&#039; prefix and with &#039;.php extension&lt;br /&gt;
* Using the class name as filename (adding the &#039;.php&#039; extension) and extending MOODLEDIRROOT/lib/behat/behat_base.php (or MOODLEDIRROOT/lib/behat/behat_files.php if it&#039;s a repository or is files-related)&lt;br /&gt;
* With a descriptive class name, for example the component name (it will be used when filtering steps definitions)&lt;br /&gt;
* Stored in COMPONENTNAME/tests/behat/ directory or lib/tests/behat/ if is not part of any other component&lt;br /&gt;
* Describe it&#039;s purpose in a single line inside the method doc comment, the size of the comment is not a problem&lt;br /&gt;
* Describe the regular expression with the most appropriate tag inside the method doc comment:&lt;br /&gt;
** &#039;&#039;&#039;@Given&#039;&#039;&#039; - A step to set up the initial context (for example &#039;&#039;the following &amp;quot;courses&amp;quot; exists&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;@When&#039;&#039;&#039; - An action that provokes an event (for example &#039;&#039;I press the button &amp;quot;buttonname&amp;quot;&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;@Then&#039;&#039;&#039; - Checkings to ensure the outcomes are the expected (for example &#039;&#039;I should see &amp;quot;whatever&amp;quot;&#039;&#039;)&lt;br /&gt;
* Depending on the inputs your definition expects you must use a different regular expression:&lt;br /&gt;
** &#039;&#039;&#039;If you expect a number:&#039;&#039;&#039; &amp;quot;(?P&amp;lt;info_about_what_you_expect_number&amp;gt;\d+)&amp;quot; (note that the regular expression is quoted between &#039;&#039;&#039;&amp;quot;&#039;&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;If you expect a string or a text:&#039;&#039;&#039; &amp;quot;(?P&amp;lt;info_about_what_you_expect_string&amp;gt;(?:[^&amp;quot;]|\\&amp;quot;)*)&amp;quot; Don&#039;t use &#039;&#039;&#039;text_selector_string&#039;&#039;&#039; and &#039;&#039;&#039;selector_string&#039;&#039;&#039; as info strings, they are reserved to selector types (note that the regular expression is quoted between &#039;&#039;&#039;&amp;quot;&#039;&#039;&#039;)&lt;br /&gt;
** &#039;&#039;&#039;If you expect a table with key/value pairs (for example to fill a form):&#039;&#039;&#039; Finish your regular expression with &#039;&#039;&#039;:&#039;&#039;&#039; and provide info in the description about the contents of the table&lt;br /&gt;
** &#039;&#039;&#039;If you expect a selector type:&#039;&#039;&#039; &amp;quot;(?P&amp;lt;selector_string&amp;gt;[^&amp;quot;]*)&amp;quot; or &amp;quot;(?P&amp;lt;text_selector_string&amp;gt;[^&amp;quot;]*)&amp;quot; depending on whether you want to use any selector or you want a text-based selector (more info about selectors in https://docs.moodle.org/dev/Acceptance_testing#Providing_values_to_steps)&lt;br /&gt;
* To make test writer&#039;s life better is good to include explicative info in the subexpressions of the regular expression about what the test writer is supposed to put in there (for example &#039;&#039;I expand &amp;quot;(?P&amp;lt;nodetext&amp;gt;(?:[^&amp;quot;]|\\&amp;quot;)*)&amp;quot; node&#039;&#039;)&lt;br /&gt;
* Is recommended to use the static part of the regular expression as the name of the method, using underscores instead of spaces (see current steps definitions)&lt;br /&gt;
&lt;br /&gt;
== Links == &lt;br /&gt;
* Technical info: [[Behat integration]]&lt;br /&gt;
* Behat CLI command options: http://docs.behat.org/guides/6.cli.html&lt;br /&gt;
* How to use selectors to interact with the site elements: http://mink.behat.org/#traverse-the-page-selectors&lt;br /&gt;
* See Also [https://tracker.moodle.org/browse/MDL-37046 MDL37046] for clear instruction&lt;br /&gt;
[[Category:Behat]][[Category:Quality Assurance]]&lt;br /&gt;
&lt;br /&gt;
[[es:Prueba de aceptación]]&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Compiling_FreeTDS_under_Windows&amp;diff=41605</id>
		<title>Compiling FreeTDS under Windows</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Compiling_FreeTDS_under_Windows&amp;diff=41605"/>
		<updated>2013-07-25T13:40:11Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: /* Building FreeTDS for PHP 5.5.x (VC11) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Requirements==&lt;br /&gt;
&lt;br /&gt;
* MSVC 6.0 (Microsoft Visual C++ 6.0) with Service Packs installed.&lt;br /&gt;
* February 2003 Platform SDK (must be February 2003, last supported platform SDK for VC6) [see [[FebruaryPlatformSDK]]]&lt;br /&gt;
* FreeTDS (tested with [http://ibiblio.org/pub/Linux/ALPHA/freetds/old/0.82/freetds-patched.tgz version 0.82+official patchset] - updated 2011-09-06).&lt;br /&gt;
* PHP source files (tested with [http://www.php.net/get/php-5.3.5.tar.gz/from/a/mirror version 5.3.5])&lt;br /&gt;
* These packages (non-debug):&lt;br /&gt;
** From http://pecl2.php.net/downloads/php-windows-builds/php-libs/ :&lt;br /&gt;
*** binary-tools.zip&lt;br /&gt;
** From http://pecl2.php.net/downloads/php-windows-builds/php-libs/VC6/x86/ :&lt;br /&gt;
*** bindlib&lt;br /&gt;
*** libiconv&lt;br /&gt;
*** libxml&lt;br /&gt;
*** libxslt&lt;br /&gt;
*** zlib&lt;br /&gt;
&lt;br /&gt;
==Build Steps==&lt;br /&gt;
&lt;br /&gt;
* Create c:\dev&lt;br /&gt;
* Create c:\dev\php-build&lt;br /&gt;
* Uncompress all the packages listed in requirements and PHP into c:\dev\php-build (replacing all when uncompressing). Make sure to extract the bin, lib, include folders without any top level directory contained within the archive.&lt;br /&gt;
* Copy uncompressed [http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-patched.tgz freetds] folder to C:\dev\php-build (rename it to, simply, &amp;quot;freetds&amp;quot;).&lt;br /&gt;
* Open the C:\dev\php-build\freetds\win32\msvc6\FreeTDS.dsw Project Workspace (it&#039;s really important to get this Workspace and not any of the individual projects!).&lt;br /&gt;
* In the &amp;quot;Build&amp;quot; menu, set the &amp;quot;Active Configuration&amp;quot; to  &amp;quot;dblib - Win32 Release&amp;quot; and then, in the same menu, &amp;quot;Rebuild All&amp;quot;. This should end with one dblib.lib library into C:\dev\php-build\freetd\win32\msvc6\db_Release&lt;br /&gt;
* Copy dblib.lib to C:\dev\php-build\lib&lt;br /&gt;
* Start CMD&lt;br /&gt;
* Create one C:\dev\prepare4php.bat file with contents below and execute it:&lt;br /&gt;
::@set PATH=C:\dev\php-build\bin;%PATH%&lt;br /&gt;
::@set INCLUDE=C:\dev\php-build\include;%INCLUDE%&lt;br /&gt;
::@set LIB=C:\dev\php-build\lib;%LIB%&lt;br /&gt;
::@set BISON_SIMPLE=C:\dev\php-build\bin\bison.simple&lt;br /&gt;
* Continue in CMD and change dir to C:\dev\php-build\php-x-x-x&lt;br /&gt;
* Execute this:&lt;br /&gt;
** buildconf&lt;br /&gt;
** cscript /nologo configure.js --disable-all --disable-ipv6 --enable-cli --enable-zts (--disable-zts)  --with-dblib=shared --enable-object-out-dir=c:\dev --with-extra-includes=c:\dev\php-build\freetds\include;c:\dev\php-build\freetds\win32&lt;br /&gt;
** nmake&lt;br /&gt;
* You should end with one C:\dev\Release_TS for the --enable-zts (or C:\dev\Release for the --disable-zts alternative)  dir, with your compiled FreeTDS PHP module ready at the root level of that dir. CLI was passed as a build option above because as of PHP v5.3.x you must specify one SAPI modile to get a build.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
* By using --enable-zts or --disable-zts you&#039;ll end with different thread safe/no safe versions of the extension. Use them depending of your environment thread safety.&lt;br /&gt;
* If you one use PHP 5.2 version to build the lib, the extensions generated are expected to work against any PHP 5.2.x version (but not against other releases of PHP, like 5.1 or 5.3).&lt;br /&gt;
* MSVC 6.0 is required because it&#039;s the official tool used to build PHP binary distributions. It seems that, with PHP 5.3 they will start using MSVC 9 or so... corresponding extensions should use the same.&lt;br /&gt;
* Feel free to fix and improve this document. TIA! &lt;br /&gt;
* For any comment related to this, please use MDL-14725 in the Moodle Tracker.&lt;br /&gt;
* And MDL-11810 has a related discussion.&lt;br /&gt;
&lt;br /&gt;
==Building FreeTDS for PHP 5.5.x (VC11)==&lt;br /&gt;
Build process&lt;br /&gt;
Building PHP 5.5.1 with FreeTDS 0.91.89 for moodle 2.5.1 under x86 vc11&lt;br /&gt;
&lt;br /&gt;
Requirements: &lt;br /&gt;
* Visual C 11 (Visual Studio 2012) (Free-to-download Express version OK) (Windows SDK not required)&lt;br /&gt;
* Current stable PHP source (http://php.net/downloads.php)&lt;br /&gt;
* Current stable FreeTDS source (ftp://ftp.freetds.org/pub/freetds/stable/)&lt;br /&gt;
* Most recent binary tools (http://windows.php.net/downloads/php-sdk/)&lt;br /&gt;
* PHP dependencies (http://windows.php.net/downloads/php-sdk/) &lt;br /&gt;
&lt;br /&gt;
(At time of writing... the binary tools haven&#039;t been updated since 2011... but its OK)&lt;br /&gt;
&lt;br /&gt;
Setup PHP environment by following guide: (follow the steps carefully)&lt;br /&gt;
https://wiki.php.net/internals/windows/stepbystepbuild&lt;br /&gt;
- In step 8, bin\phpsdk_buildtree.bat may not create a vc11 folder so I just copy the vc9 and rename.&lt;br /&gt;
&lt;br /&gt;
Ensure you can build PHP under this created environment using:&lt;br /&gt;
  buildconf&lt;br /&gt;
  configure --disable-all --enable-cli&lt;br /&gt;
  nmake&lt;br /&gt;
&lt;br /&gt;
Building FreeTDS&lt;br /&gt;
Discussion with FreeTDS source maintainers [http://permalink.gmane.org/gmane.comp.db.tds.freetds/11009 here] suggests that the visual studio project/solution/workspace files are not maintained. You may get mixed results from these files. Visual Studio 2012 is very good at upgrading solution files from previous versions.&lt;br /&gt;
&lt;br /&gt;
One method:&lt;br /&gt;
* If you have used the suggested paths then put the freetds source files here: C:\php-sdk\phpdev\vc11\x86\php-5.5.1-src\freetds&lt;br /&gt;
* Open the freetds\win32\msvc6\FreeTDS.dsw Project Workspace. Allow visual studio to upgrade. &lt;br /&gt;
* In the configuration manager, set the &amp;quot;Active Solution Configuration&amp;quot; to Release and platform to Win32&lt;br /&gt;
(you may not need to build all of the projects in the solution)&lt;br /&gt;
This should end with a dblib.lib library in one of the Release folders of freetds\win32\msvc6\&lt;br /&gt;
* Copy dblib.lib and libTDS.lib to C:\php-sdk\phpdev\vc11\x86\deps\lib&lt;br /&gt;
&lt;br /&gt;
If when attempting to build php_dblib.lib from source you get linking errors, it is probably because you are missing some source files in the projects/solutions. Doing a file search in the src folder for the symbol (without the preceding underscore) should highlight where the function definition comes from. Add the file to the project that won’t compile. Rinse and Repeat.&lt;br /&gt;
freetds\src\tds and freetds\src\replacements are good places to look.&lt;br /&gt;
&lt;br /&gt;
When php_dblib.lib is compilied and in the php lib folder in your build environment, the last thing is to configure the makefile appropriately. (You may also need to compile libTDS.lib from FreeTDS - I had to.).&lt;br /&gt;
&lt;br /&gt;
I used a number of different configurations while testing. This one worked:&lt;br /&gt;
  configure --disable-all --disable-zts --enable-cli --with-dblib=shared&lt;br /&gt;
    --with-extra-includes=C:\php-sdk\phpdev\vc11\x86\php-5.5.1-src\freetds\include;C:\php-sdk\phpdev\vc11\x86\php-5.5.1-src\freetds\win32&lt;br /&gt;
&lt;br /&gt;
Check the output from the configure call in case there any skipped dependencies. (like dblib!)&lt;br /&gt;
&lt;br /&gt;
“--with-dblib=shared” is the key line for actually telling make to create an external dll file and not just compile the functionality directly into PHP core.&lt;br /&gt;
&lt;br /&gt;
If while using nmake an unresolved external symbol linker error is reported: e.g. “error LNK2019: unresolved external symbol _tdsdump_log referenced in function _dblib_add_connection” you may need to add libTDS.lib to the libs statement in makefile and rerun make. http://enyby.blogspot.co.uk/2013/01/eliminate-errors-compile-freetds-on.html. I had to do this.&lt;br /&gt;
Sample LIBS declaration: &lt;br /&gt;
  LIBS=libTDS.lib kernel32.lib ole32.lib user32.lib advapi32.lib shell32.lib ws2_32.lib Dnsapi.lib &lt;br /&gt;
&lt;br /&gt;
Use “--enable-zts” or --disable-zts” for thread safety as mentioned.&lt;br /&gt;
&lt;br /&gt;
Then when php_dblib.dll is created put it in the ext folder in your run time environment and enable the extension in your php.ini and you’re good to go!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
	<entry>
		<id>https://docs.moodle.org/dev/index.php?title=Compiling_FreeTDS_under_Windows&amp;diff=41604</id>
		<title>Compiling FreeTDS under Windows</title>
		<link rel="alternate" type="text/html" href="https://docs.moodle.org/dev/index.php?title=Compiling_FreeTDS_under_Windows&amp;diff=41604"/>
		<updated>2013-07-25T13:11:41Z</updated>

		<summary type="html">&lt;p&gt;Davidaylmer: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Requirements==&lt;br /&gt;
&lt;br /&gt;
* MSVC 6.0 (Microsoft Visual C++ 6.0) with Service Packs installed.&lt;br /&gt;
* February 2003 Platform SDK (must be February 2003, last supported platform SDK for VC6) [see [[FebruaryPlatformSDK]]]&lt;br /&gt;
* FreeTDS (tested with [http://ibiblio.org/pub/Linux/ALPHA/freetds/old/0.82/freetds-patched.tgz version 0.82+official patchset] - updated 2011-09-06).&lt;br /&gt;
* PHP source files (tested with [http://www.php.net/get/php-5.3.5.tar.gz/from/a/mirror version 5.3.5])&lt;br /&gt;
* These packages (non-debug):&lt;br /&gt;
** From http://pecl2.php.net/downloads/php-windows-builds/php-libs/ :&lt;br /&gt;
*** binary-tools.zip&lt;br /&gt;
** From http://pecl2.php.net/downloads/php-windows-builds/php-libs/VC6/x86/ :&lt;br /&gt;
*** bindlib&lt;br /&gt;
*** libiconv&lt;br /&gt;
*** libxml&lt;br /&gt;
*** libxslt&lt;br /&gt;
*** zlib&lt;br /&gt;
&lt;br /&gt;
==Build Steps==&lt;br /&gt;
&lt;br /&gt;
* Create c:\dev&lt;br /&gt;
* Create c:\dev\php-build&lt;br /&gt;
* Uncompress all the packages listed in requirements and PHP into c:\dev\php-build (replacing all when uncompressing). Make sure to extract the bin, lib, include folders without any top level directory contained within the archive.&lt;br /&gt;
* Copy uncompressed [http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-patched.tgz freetds] folder to C:\dev\php-build (rename it to, simply, &amp;quot;freetds&amp;quot;).&lt;br /&gt;
* Open the C:\dev\php-build\freetds\win32\msvc6\FreeTDS.dsw Project Workspace (it&#039;s really important to get this Workspace and not any of the individual projects!).&lt;br /&gt;
* In the &amp;quot;Build&amp;quot; menu, set the &amp;quot;Active Configuration&amp;quot; to  &amp;quot;dblib - Win32 Release&amp;quot; and then, in the same menu, &amp;quot;Rebuild All&amp;quot;. This should end with one dblib.lib library into C:\dev\php-build\freetd\win32\msvc6\db_Release&lt;br /&gt;
* Copy dblib.lib to C:\dev\php-build\lib&lt;br /&gt;
* Start CMD&lt;br /&gt;
* Create one C:\dev\prepare4php.bat file with contents below and execute it:&lt;br /&gt;
::@set PATH=C:\dev\php-build\bin;%PATH%&lt;br /&gt;
::@set INCLUDE=C:\dev\php-build\include;%INCLUDE%&lt;br /&gt;
::@set LIB=C:\dev\php-build\lib;%LIB%&lt;br /&gt;
::@set BISON_SIMPLE=C:\dev\php-build\bin\bison.simple&lt;br /&gt;
* Continue in CMD and change dir to C:\dev\php-build\php-x-x-x&lt;br /&gt;
* Execute this:&lt;br /&gt;
** buildconf&lt;br /&gt;
** cscript /nologo configure.js --disable-all --disable-ipv6 --enable-cli --enable-zts (--disable-zts)  --with-dblib=shared --enable-object-out-dir=c:\dev --with-extra-includes=c:\dev\php-build\freetds\include;c:\dev\php-build\freetds\win32&lt;br /&gt;
** nmake&lt;br /&gt;
* You should end with one C:\dev\Release_TS for the --enable-zts (or C:\dev\Release for the --disable-zts alternative)  dir, with your compiled FreeTDS PHP module ready at the root level of that dir. CLI was passed as a build option above because as of PHP v5.3.x you must specify one SAPI modile to get a build.&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
* By using --enable-zts or --disable-zts you&#039;ll end with different thread safe/no safe versions of the extension. Use them depending of your environment thread safety.&lt;br /&gt;
* If you one use PHP 5.2 version to build the lib, the extensions generated are expected to work against any PHP 5.2.x version (but not against other releases of PHP, like 5.1 or 5.3).&lt;br /&gt;
* MSVC 6.0 is required because it&#039;s the official tool used to build PHP binary distributions. It seems that, with PHP 5.3 they will start using MSVC 9 or so... corresponding extensions should use the same.&lt;br /&gt;
* Feel free to fix and improve this document. TIA! &lt;br /&gt;
* For any comment related to this, please use MDL-14725 in the Moodle Tracker.&lt;br /&gt;
* And MDL-11810 has a related discussion.&lt;br /&gt;
&lt;br /&gt;
==Building FreeTDS for PHP 5.5.x (VC11)==&lt;br /&gt;
Build process&lt;br /&gt;
Building PHP 5.5.1 with FreeTDS 0.91.89 for moodle 2.5.1 under x86 vc11&lt;br /&gt;
&lt;br /&gt;
Requirements: &lt;br /&gt;
* Visual C 11 (Visual Studio 2012) (Free-to-download Express version OK) (Windows SDK not required)&lt;br /&gt;
* Current stable PHP source (http://php.net/downloads.php)&lt;br /&gt;
* Current stable FreeTDS source (ftp://ftp.freetds.org/pub/freetds/stable/)&lt;br /&gt;
* Most recent binary tools (http://windows.php.net/downloads/php-sdk/)&lt;br /&gt;
* PHP dependencies (http://windows.php.net/downloads/php-sdk/) &lt;br /&gt;
&lt;br /&gt;
(At time of writing... the binary tools haven&#039;t been updated since 2011... but its OK)&lt;br /&gt;
&lt;br /&gt;
Setup PHP environment by following guide: (follow the steps carefully)&lt;br /&gt;
https://wiki.php.net/internals/windows/stepbystepbuild&lt;br /&gt;
- In step 8, bin\phpsdk_buildtree.bat may not create a vc11 folder so I just copy the vc9 and rename.&lt;br /&gt;
&lt;br /&gt;
Ensure you can build PHP under this created environment using:&lt;br /&gt;
::buildconf&lt;br /&gt;
::configure --disable-all --enable-cli&lt;br /&gt;
::nmake&lt;br /&gt;
&lt;br /&gt;
Building FreeTDS&lt;br /&gt;
Discussion with FreeTDS source maintainers [http://permalink.gmane.org/gmane.comp.db.tds.freetds/11009 here] suggests that the visual studio project/solution/workspace files are not maintained. You may get mixed results from these files. Visual Studio 2012 is very good at upgrading solution files from previous versions.&lt;br /&gt;
&lt;br /&gt;
One method:&lt;br /&gt;
* If you have used the suggested paths then put the freetds source files here: C:\php-sdk\phpdev\vc11\x86\php-5.5.1-src\freetds&lt;br /&gt;
* Open the freetds\win32\msvc6\FreeTDS.dsw Project Workspace. Allow visual studio to upgrade. &lt;br /&gt;
* In the configuration manager, set the &amp;quot;Active Solution Configuration&amp;quot; to Release and platform to Win32&lt;br /&gt;
(you may not need to build all of the projects in the solution)&lt;br /&gt;
This should end with a dblib.lib library in one of the Release folders of freetds\win32\msvc6\&lt;br /&gt;
* Copy dblib.lib and libTDS.lib to C:\php-sdk\phpdev\vc11\x86\deps\lib&lt;br /&gt;
&lt;br /&gt;
If when attempting to build php_dblib.lib from source you get linking errors, it is probably because you are missing some source files in the projects/solutions. Doing a file search in the src folder for the symbol (without the preceding underscore) should highlight where the function definition comes from. Add the file to the project that won’t compile. Rinse and Repeat.&lt;br /&gt;
freetds\src\tds and freetds\src\replacements are good places to look.&lt;br /&gt;
&lt;br /&gt;
When php_dblib.lib is compilied and in the php lib folder in your build environment, the last thing is to configure the makefile appropriately. (You may also need to compile libTDS.lib from FreeTDS - I had to.).&lt;br /&gt;
&lt;br /&gt;
I used a number of different configurations while testing. This one worked:&lt;br /&gt;
::* configure --disable-all --disable-zts --enable-cli --with-dblib=shared --with-extra-includes=C:\php-sdk\phpdev\vc11\x86\php-5.5.1-src\freetds\include;C:\php-sdk\phpdev\vc11\x86\php-5.5.1-src\freetds\win32&lt;br /&gt;
&lt;br /&gt;
Check the output from the configure call in case there any skipped dependencies. (like dblib!)&lt;br /&gt;
&lt;br /&gt;
“--with-dblib=shared” is the key line for actually telling make to create an external dll file and not just compile the functionality directly into PHP core.&lt;br /&gt;
&lt;br /&gt;
If while using nmake an unresolved external symbol linker error is reported: e.g. “error LNK2019: unresolved external symbol _tdsdump_log referenced in function _dblib_add_connection” you may need to add libTDS.lib to the libs statement in makefile and rerun make. http://enyby.blogspot.co.uk/2013/01/eliminate-errors-compile-freetds-on.html. I had to do this.&lt;br /&gt;
Sample LIBS declaration: &lt;br /&gt;
::* LIBS=libTDS.lib kernel32.lib ole32.lib user32.lib advapi32.lib shell32.lib ws2_32.lib Dnsapi.lib &lt;br /&gt;
&lt;br /&gt;
Use “--enable-zts” or --disable-zts” for thread safety as mentioned.&lt;br /&gt;
&lt;br /&gt;
Then when php_dblib.dll is created put it in the ext folder in your run time environment and enable the extension in your php.ini and you’re good to go!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Installation]]&lt;br /&gt;
&lt;br /&gt;
[[Category:XMLDB]]&lt;br /&gt;
[[Category:DB]]&lt;/div&gt;</summary>
		<author><name>Davidaylmer</name></author>
	</entry>
</feed>