| |||||||||||||||||||||||||||||||
|
![]() Spelling of automatic tests and environment{Wednesday} phpUnit Introduction The main task of the professional php-developer - cozdanie in maximum short term of the software, completely satisfying customer. Scripts should do{make} what from them expect. - the form of feedback which on pressing the button under condition of correct filling fields sends a mail or writes down the most simple example given in the table of a DB. If she has not made it, abundantly clearly, that in the program the mistake has crept in. So, testing - the activity directed on such revealing of discrepancies between expected and valid. Revealing discrepancies, incorrect behaviour on stages of development, the developer meaningly and systematically reduces probability of that it is necessary to collide{face} it to the user. To test programs (in particular php-scripts) it is quite possible and manually. By the example of the form of feedback, understandably what to test her it is very simple. To start a browser, to go on necessary url, to fill in fields, to press on "Ok", then to go in base and to check up, whether has appeared there sootvetstvujuhhaja recording. Fine, but after any change of a script it is impossible to be confident his serviceability. It is possible to count at random and to not check, whether the script after the next updating works whether or not, but remember, that if it{he} will be not not tested by you, it will be made by the customer during delivery of the project or the end user during operation. In the first case it threatens you with financial instability, and in the second your image will suffer. To not test manually (it is long, complex and demanding special), it is possible to write process to assiduity the program testing other programs or to create the automated tests. In any modern methodology of development ON testing is an integral part of process, and the importance of his spelling is not lower than the importance of a spelling of a code. The professional developer is obliged to create sets of a various kind of the automated tests (more in detail about kinds of tests, their rules imenovanija, etc. it is possible to read in Cyril Maksimova's clause{article} " the Organization and imenovanie the automated tests "). Despite of obvious utility and accent{stress} metodologij on process of testing, personal experience of authors testifies to the following disorder of opinions of web-programmers about the automated testing own scripts: * " Nobody writes, why I should write " * " To me do not allocate time specially for a spelling of tests though it would be useful " * " I for a long time write tests and I do not understand, how it is possible to live without it " The automated tests and web-programming Everyday lives of a great bulk of web-developers - a choice of the good server for accommodation of a site. It is difficult to find the hosting - provider (php+mysql for reasonable money) which would arrange at once on 100 %, and pereezd on the new server even for interpretive language, koim is my hotly liked PHP, can become "fatal". Even in documentation on Java - the language initially focused on krossplatformennost`, it is written, that the price of bearableness is never equal to zero. These people know, that speak. After crossing{moving} to scripts fine organized and stably working earlier can appear warning'¿, and any programs will cease to work absolutely: ways, libraries, the version itself php have exchanged. In a result, having a set of tests to move much easier. It is necessary to copy scripts, to start a set of tests, to see those tests which have come to the end unsuccessfully, to understand, correct, start a set of tests once again. All. Instead of leaving the "half-dead" project on a new hosting, "is superficial" proklikav in a browser under links, we receive stably working site on the new server without special a headache. The automated testing finally raises quality of a code, and, taking into account specificity of web-programming, simplifies process of crossing{moving} from the server on the server. After the decision to test, there comes necessity somehow to organize this process. For example, to allocate for test scripts a separate directory, to create the program which will start all scripts and depending on their outcome will write "OK" or "Error." it is quite possible to do it " from zero ", but there are ready test infrastructures (auxiliary programs) which unite groups of tests " on subjects ", uniformly they are saved, start and deduce results. Cozdanie tests in phpUnit Basically because of enthusiasm for methodology XP authors are familiar with test infrastructure JUnit, accordingly, for php their choice has fallen on phpUnit, as on port of the created by enthusiasts " senior brother ". For today there are some various versions of port JUnit on php. At least 3 variants c phpUnit and port php_simpletest. are on a regular basis updated by the name version PEAR:: PHPUnit (Sebastian Bergmann). Php_simpletest is in a status of the first bety, others phpUnit'HH were updated one year ago (phpUnit project) and two years ago (phpunit-1.0.0) accordingly. All examples of modular tests considered below are written with use PEAR:: PHPUnit. Let's create a set of tests for class Message which formats and checks the message for subsequent his sending on e-mail. The designer of a class receives 3 parameters (a name of the sender, it e-mail adres and a body of the message). The method format_message () formats the message before sending, and is_valid () checks an opportunity of sending of the message (whether fields are filled, and whether it is correctly entered S-mail). An initial code of class Message - here "Heart" of testing is class PHPUnit which starts TestSuite (a set of tests) and returns object TestResult (result of the test). To write the minimal set of tests, using phpUnit, it is necessary: 1. To connect library PHPUnit.php 2. To create a subclass of base class TestCase 3. To add in him any quantity{amount} of testing methods which names begin with "test". In our case it "test_empty_input", "test_email_invalid", "test_valid_input". In them methods testiruemogo class Message will be caused. On an input{entrance} beforehand known parameters will move, and the result is compared with reference by means of family of functions Assert, inherited by our test class from TestCase (the method assertEquals checks the expected and really received result on equality, assertTrue checks, whether has the sent parameter value "true", etc.) 4. Cozdat` class PHPUnit_TestSuite, having passed him as parameter the name of a class with a set of tests 5. To start a set of tests and to deduce{remove} result Let's create a set of tests for a class, following the resulted instruction. We shall test the following aspects of job of class Message: his reaction to the empty message, and incorrect e-mail, and also we compare formatted by object of a class the message with reference. We create the message, we submit on an input{entrance} of the designer incorrect e-mail, we expect, that the method of a class is_valid (), responsible{crucial} for his check, will return ' false '. <? php function test_email_invalid () { $m = new Message (' name ',' invalid ',' body '); /* We expect, that m-> is_valid () returns false */ $this-> assertFalse ($m-> is_valid ()); } We create the message, we submit on an input{entrance} of the designer empty lines, we expect, that a method of a class is_valid () the same as and last time, will return false. <? php function test_empty_input () { $m = new Message (",", "); /* We expect, that m-> is_valid () returns false */ $this-> assertFalse ($m-> is_valid ()); } And, at last, we submit on an input{entrance} correctly generated message and it is expected, that a class of it it is correct sformatiruet <? php function test_valid_input () { $m = new Message (' name ', invalid@mail.ru ', body '); $this-> assertTrue ($m-> is_valid ()); $valid_string = <<<EOL from: name (invalid@mail.ru) body EOL; /* We expect, that the reference line and result of job as_string () will coincide */ $this-> assertEquals ($valid_string, $m-> as_string ()); } } We start a set of tests (the full version testmessage.php - here) and the following result is received: <? php TestCase messagetest-> test_email_invalid () passed TestCase messagetest-> test_empty_input () passed TestCase messagetest-> test_valid_input () passed All tests have come to the end successfully. Now it is possible to continue escalating of functionality of class Message, being confident, that after the next updating he correctly works (certainly provided that have worked all tests). Development of class Message and development Message c not so strongly differ with a set of tests on time, but in the second case we have powerful "support" on the future, above each function we reflect at least twice, and we can define{determine} easily serviceability of a script on a new hardware-software configuration later. The application: an initial code message.inc.php <? php class Message { var $email; var $name; var $body; var $message; function Message ($n, $from, $b) { $this-> email = $from; $this-> name = $n; $this-> body = $b; $this-> message = null; } function is_valid () { if (strpos ($this-> email, ' ') === false) return false; if (! strlen ($this-> name)) return false; if (! strlen ($this-> body)) return false; return true; } function as_string () { if ($this-> message == null) $this-> format_message (); return $this-> message; } function format_message () { $this-> message = ' from: '. $ this-> name; $this-> message. = ' ('. $ this-> email. ") nn "; $this-> message. = $this-> body; } } ?> The application: an initial code testmessage.php.txt <? php require_once ' PHPUnit.php '; /* We connect phpUnit and a file with a tested class */ require_once (' class_message.inc.php '); /* We inherit from PHPUnit_TestCase and it is added testing methods test<... */ class MessageTest extends PHPUnit_TestCase { function test_email_invalid () { $m = new Message (' name ',' invalid ',' body '); /* We expect, that m-> is_valid () returns false */ $this-> assertFalse ($m-> is_valid ()); } function test_empty_input () { $m = new Message (",", "); /* We expect, that m-> is_valid () returns false */ $this-> assertFalse ($m-> is_valid ()); } function test_valid_input () { $m = new Message (' name ', invalid@mail.ru ', body '); $this-> assertTrue ($m-> is_valid ()); $valid_string = <<<EOL from: name (invalid@mail.ru) body EOL; /* We expect, that the reference line and result of job as_string () will coincide */ $this-> assertEquals ($valid_string, $m-> as_string ()); } } /* We start a set of tests and we deduce{remove} result */ $suite = new PHPUnit_TestSuite (' MessageTest '); $result = PHPUnit:: run ($suite); echo $result-> toHTML (); ?> |
|
|||||||||||||||||||||||||||||