Getting Started with PHPUnit TDD

Source: Internet
Author: User
Tags add object command line constructor php class return variable
Start with a bank account and assume you have PHPUnit installed.   We begin to understand the idea of TDD (test-driven-development) from an example of a simple bank account.   In the engineering directory to establish two directories, SRC and test, under SRC to establish a file bankaccount.php, in the test directory to establish a file bankaccounttest.php.   According to TDD, we first write the test, then write the production code, so bankaccount.php blank, we first write bankaccounttest.php.   <?php class BankAccountTest extends Phpunit_framework_testcase {}?> now let's run and see the results. The command line running PHPUnit is as follows:   phpunit--bootstrap src/bankaccount.php test/bankaccounttest.php--bootstrap src/ Bankaccount.php is to load src/bankaccount.php before running the test code, and the test code to run is test/bankaccounttest.php.   If no specific test file is specified and only the directory is given, PHPUnit will run all file names matching *test.php files under the directory. Because only one file is bankaccounttest.php in the test directory, execution   phpunit--bootstrap src/bankaccount.php test will get the same result.   There is 1 failure:   1) Warning No tests found in class "BankAccountTest".   failures! Tests:1, assertions:0, failures:1. A warning error because there are no tests.   Account instantiation Below we add a test. Note that TDD is a design method that can help you design a module from the bottom up. When we write the test, we need to start from the user's point of view. If the user uses our BankAccount class, what does he do first? Must be an instance of a new bankaccount. Then our firstA test is a test for instantiation.   Public Function Testnewaccount () {    $account 1 = new BankAccount (), running PHPUnit, is expected to fail.   PHP Fatal Error:  class ' BankAccount ' not found in/home/wuchen/projects/jolly-code-snippets/php/phpunit/ Test/bankaccounttest.php on line 5 did not find the definition of the BankAccount class, we will write the production code below. Make the test pass. In src/bankaccount.php (hereafter referred to as source file), enter the following:   <?php class BankAccount {}?> run PHPUnit, test passed.   OK (1 test, 0 assertions) Next, we want to increase the test to make the test fail. If you create a new account, the balance of the account should be 0. So we added an Assert statement:   Public Function Testnewaccount () {    $account 1 = new BankAccount ();     $th Is->assertequals (0, $account 1->value ()); Note that value () is a member function of BankAccount, of course this function is not yet defined, and as a user we want BankAccount to provide this function.   Run PHPUnit, the results are as follows:   PHP Fatal error:  call to undefined method Bankaccount::value () In/home/wuchen/project S/jolly-code-snippets/php/phpunit/test/bankaccounttest.php on line 6 results tell us that BankAccount does not have the value () of this member function. Add Production Code:   class BankAccount {    PUBlic function Value () {        return 0;    }} Why do you want value () to go straight back to 0 because the test code expects value () to return 0. The principle of TDD is to not write redundant production code, just let the test pass.   Account access to run PHPUnit, we first assume that BankAccount instantiation has met the requirements, next, how users want to use BankAccount? You're going to want to deposit it in there. BankAccount has a deposit function that can be added to the account by calling the function. So we added the next test.   Public Function Testdeposit () {    $account = new BankAccount ()     $account->deposit (10);     $this->assertequals ($account->value ()); The initial balance of the account is 0, we deposit 10 yuan, the balance of the account should be 10. Run PHPUnit, the test fails because the deposit function is not yet defined:  . PHP Fatal error:  call to undefined method BankAccount::d eposit () in/home/wuchen/projects/jolly-code-snippets/php /phpunit/test/bankaccounttest.php on line 11 Next add deposit function in source file:   Public Function Deposit ($ammount) {} run again PHPUnit , the results are as follows:   1 bankaccounttest::testdeposit Failed asserting that 0 matches expected 10. Because we do not have the operating account balance in the deposit function, the balance initial value is still 0 after the 0,deposit function is executed, not the behavior that the user expects. We should increase the number of user deposits to the balance.   In order to operate the balance, the balance should be a bankaccountA member variable. This variable is not allowed to be arbitrarily changed, so it is defined as a private variable. Here we add the private variable $value to the production code, and the value function should return the $value values.   class BankAccount {    private $value          Public Function value () {        return $this->value;    }       Public Function deposit ($ammount) {        $this->value = 10;    } to run PHPUnit, test passed. Next, we think, what else does the user need? Yes, take the money. When the money is taken, the balance of the account should be deducted from this value. If you pass a negative number to the deposit function, it is the equivalent of taking money. So we added two lines of code to the Testdeposit function of the test code.   $account->deposit (-5); $this->assertequals (5, $account->value ()); Run PHPUnit again and the test fails.   1) Bankaccounttest::testdeposit Failed asserting that matches expected 5. This is because in the production code we simply set the $value to 10 results. Improve the production code.   Public Function deposit ($ammount) {    $this->value + = $ammount;} run PHPUnit again, test passed.   New constructors Next, I think that the user may need a different constructor, and when creating the BankAccount object, you can pass in a value as the account balance. So we added this instantiation test to the Testnewaccount.   Public Function Testnewaccount () {    $account 1 = new BanKaccount ();     $this->assertequals (0, $account 1->value ());     $account 2 = new BankAccount (10);     $this->assertequals ($account 2->value ()); Run PHPUnit, the result is:   1 bankaccounttest::testnewaccount Failed asserting that null matches expected 10. Because BankAccount does not have a constructor with parameters, the new BankAccount (10) Returns an empty object, and the value () function of the null object returns NULL. To pass the test, we add the constructor with the parameter in the production code.   Public Function __construct ($n) {    $this->value = $n;} Run test again:   1) BANKACCOUNTTEST::TESTNEWACC Ount Missing Argument 1 for Bankaccount::__construct (), called in/home/wuchen/projects/jolly-code-snippets/php/ Phpunit/test/bankaccounttest.php on line 5 and defined  /home/wuchen/projects/jolly-code-snippets/php/phpunit/ Src/bankaccount.php:5/home/wuchen/projects/jolly-code-snippets/php/phpunit/test/bankaccounttest.php:5   2) Bankaccounttest::testdeposit Missing Argument 1 for Bankaccount::__construct (), called in/home/wuchen/projects/ Jolly-code-snippets/phP/phpunit/test/bankaccounttest.php on line and defined  /home/wuchen/projects/jolly-code-snippets/php/ Phpunit/src/bankaccount.php:5/home/wuchen/projects/jolly-code-snippets/php/phpunit/test/bankaccounttest.php:12 Two calls to new BankAccount () have reported errors, added constructors with parameters, and constructors with no arguments. The students from C++/java immediately think of adding a default constructor:   Public Function __construct () {    $this->value = 0;} But that's not going to work because PHP doesn't Supports function overloading, so you cannot have more than one constructor. What about  ? By the right, we can add a default value for the parameter. Modify the constructor as:   Public function __construct ($n = 0) {    $this->value = $n;} calling New BankAccount () is equivalent to passing 0 To the constructor, satisfies the requirement. PHPUnit run the following test pass.   At this time, our production code is:   <?php class BankAccount {    private $value;           & nbsp Default to 0       public function __construct ($n = 0) {        $this->value = $n ;    }          Public Function value () {        $this->va Lue    } &NBSp     Public Function deposit ($ammount) {        $this->value + = $ammount;    } ?> Summary Although our code is not much, but each step is written with confidence, this is the benefits of TDD. Even if you're not sure about PHP's syntax (like me), you can be confident in your own code. Another advantage of   writing programs in TDD is that they don't need to be carefully designed for individual modules before they can be designed for writing tests. This developed module can meet the needs of users, and will not be redundant. More usage of phpunit will be covered later in  .

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.