Automated Testing Using Zend Framework

Tags: web-development, unit testing, zend framework

Автоматизированное тестирование с использованием Zend Framework Автоматизированное тестирование с использованием Zend Framework
Автоматизоване тестування з використанням Zend Framework Автоматизоване тестування з використанням Zend Framework

Automated testing for your web applications is an important step in having the confidence to make changes to your application, and still be confident you’re delivering a quality, regression-free product. With Zend Framework’s testing framework (built with PHPUnit), you can build a thorough suite of test cases for your web application with very little hassle.
This article will give you all of the basic information you need to start writing automated tests for your Zend Framework applications.

Lets get right to it.
For the examples below, I will be using an actual controller from one of my projects. This controller handles account activies, such as logins, logouts, registrations, and confirmations. We’ll be using a test database with a schema that clones our production database, and Doctrine to manage ORM (Sorry Zend_Db :(). I’ll assume that you’re using the prescribed Zend Framework (1.6+) project layout, and that you’re somewhat familiar with Zend_Config and using an Initializer controller plugin (created by default if you’re using Zend Studio for Eclipse 6.1).

Preparing Your Application
The first step to setting up automated testing is to prepare your application’s environment and settings appropriately. Depending on your setup, this can involve setting global variables, changing database connections, or reconfiguring paths. Fortunately for us, this capability is easy using Zend_Config and an Initializer controller plugin.
Zend_Config allows you to specify “sections”, which can inherit from another section. This allows you to modify configuration for different environments without duplicating settings across different files (and thereby helping us ensure we don’t forget to set something!). In our example project, we’ll need only to modify our database connection string, so we’re using the test database.
Hide code highlighting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<config>
 
<production>
  <db>
    <dsn>mysql://dbowner:password@localhost/maindb</dsn>
    <attributes>
        <model_loading>conservative</model_loading>
    </attributes>
  </db>
</production>
<test extends="production">
  <db>
    <dsn>mysql://dbowner:password@localhost/maindb_test</dsn>
  </db>
</test>
</config>

Notice how we can even inherit child attributes: Even though we specified a node, we didn’t have to specify everything below the node
Now that we have our configurations in order, we need something to manage this configuration for us and switch off based on the environment we’re running in. That’s the role of our Initializer plugin, which accepts the environment to initialize as a constructor parameter. Showing the source of an Initializer is outside the scope of this article, but here’s a pastie for the curious.

A Basic Example
Lets start with the basic framework of a controller test. If you’re using Zend Studio for Eclipse, you can easily create this structure by right-clicking on your controller in PHP Explorer and selecting New > Zend Framework Item, and then selecting Zend Controller Test Case. Then, simply make sure the controller you want to test is chosen, and click finish.
Hide code highlighting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';
require_once 'application/Initializer.php';
require_once 'application/default/controllers/IndexController.php';
 
class AccountControllerTest extends Zend_Test_PHPUnit_ControllerTestCase {
 
    /**
     * Prepares the environment before running a test.
     */
    protected function setUp() {
        $this->bootstrap = array ($this, 'appBootstrap' );
        parent::setUp ();
        // TODO Auto-generated FooControllerTest::setUp()
    }
 
    /**
     * Prepares the environment before running a test.
     */
    public function appBootstrap() {
        $this->frontController->registerPlugin ( new Initializer( 'test' ) );
    }
 
    /**
     * Cleans up the environment after running a test.
     */
    protected function tearDown() {
        // TODO Auto-generated FooControllerTest::tearDown()
        parent::tearDown ();
    }
 
    /**
     * Constructs the test case.
     */
    public function __construct() {
        // TODO Auto-generated constructor
    }
 
    /**
     * Tests FooController->barAction()
     */
    public function testIndexAction() {
        // TODO Auto-generated FooControllerTest->testBarAction()
        $this->dispatch ( '/index/index' );
        $this->assertController ( 'index' );
        $this->assertAction ( 'index' );
    }
}

You’ll see on line 21 where we’re using our initializer to setup the test environment before we run the tests. Before each test metod is run, PHPUnit will call our setup() method, which has been programmed to call our appBootstrap method. This ensures us that we’re using a clean configuration and environment before each test, as if each test was a separate process. When each test case is done, the tearDown() method is called. tearDown() is the place to put any code for removing resources or resetting any persistable changes that tests might make. We’ll make use of this in our advanced examples later.
Line 44 contains a bare-bones test case, which will ensure that dispatching to ‘/index/index’ results in the controller named ‘index’ and an action called ‘index’ are the last to be executed. This might seem trivial, but it helps detect errors with your controllers. If an uncaught exception is thrown, the controller assertion will fail, since your controller will be the last executed.

Running Your Tests
To keep this article focused, I’ve decided to remove this section and cover only writing the tests. If you need help creating Test Suites and running tests from the command line, check out PHPUnit Documentation, specifically the sections on the Command Line Test Runner and Organizing Test Suites. If you have any specific questions, feel free to shoot me an email.

Extending the Testing Functionality
Now that we covered the basics, let’s get to fully testing our Accounts controllers. There are a couple of “outside the box” requirements we have for testing our accounts controller. First off, we need a way to test the full account creation process, as if a user was actually registering. When we’re done with a test, we want to get rid of that data whenever possible, so we can run tests as many times as we want and not worry about growing our test database. Secondly, We need a way to simulate an authenticated user, as well as checking for whether a user has been authenticated or not.
Because these operations are pretty general and an opportunity for reuse exists, Lets put our supporting logic in a parent class and let our test cases inherit them.

Disposable Testing Models
There are two ways to ensure the data you’re creating during a test is deleted once a test is complete. Some choose to create the database on the fly using seed data. Since I’m using Doctrine for my projects and working directly with models (no raw queries) in the tests, I decided that just deleting the data was the best approach. To do this, all we need to do is “schedule” our model for deletion after it has been created (or loaded).
Hide code highlighting
1
2
3
4
5
<?php
protected function _setDisposable( Doctrine_Record $model )
{
    $this->_disposables[] = $model;
}

This function simply takes a reference to a model, and stores it in array, which will be handled by our tearDown() function later:
Hide code highlighting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
    protected function tearDown()
 
 
    {
        parent::tearDown();
 
        foreach ( $this->_disposables as $model ) {
            if ( $model instanceof Doctrine_Record ) {
                $model->delete();
            }
            unset( $model );
        }
    }

We simply loop through all of our “scheduled” models and delete them. This must be done in tearDown() and not inside of any test method because it’s the only way to ensure it happens. Once an assertion fails or an unexpected exception occurs in a test, that method stops executing. IF we were to try to dispose our models after an assertion, it may never happen1. Similarly, we obviously can’t dispose of a model before an assertion if that model is needed for the assertion (and why would it exist if you didn’t need it?).

Authentication Support
There are 3 things we must be able to do in order to fully test authentication.
* Create a fake identity
* Set our environment to a state equivalent to a user being logged in.
* Assert whether the environment has been changed to a logged in state.

Our example controller uses a database adapter for authentication and identity retrieval2, so generating a fake identity for us means creating (or loading) a record in our accounts table, and returning the identity data we would normally get.
Hide code highlighting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
/**
 * Generates a fake identity, usefull for simulating a logged in user
 *
 * @return StdClass an identity
 */
protected function _generateFakeIdentity()
{
    $identity = new stdClass();
 
        $account = new Account();
        $account->username     = 'AutoTest' . time();
        $account->emailAddress = 'autotest@example.org';
        $account->password     = md5( 'password' );
        $account->confirmed    = true;
        $account->enabled      = true;
        $account->save();
        $this->_setDisposable( $account );
 
    foreach( $account->toArray() as $key => $val ) {
            $identity->$key = $val;
    }
    unset( $identity->password );
 
    return $identity;
}

Account is our model, a Doctrine_Record type. We’re just simply creating a random account, and returning its data as our identity. Notice that we’re also scheduling this model for disposal (as we covered above). Now, we just need a way to set our environment to the “logged in state” as this fake user.
Hide code highlighting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
/**
 * Sets the current state as if there is a logged in user
 *
 * @param object $identity the idenity to use, otherwise one is generated
 * @return void
 */
protected  function _doLogin( $identity = null )
{
    if ( $identity === null ) {
        $identity = $this->_generateFakeIdentity();
    }
    Zend_Auth::getInstance()->getStorage()->write( $identity );
}

In our example application, if Zend_Auth has an identity, a user must be logged in. Therefore, all we have to do is store an identity in Zend_Auth’s storage adapter, and call ourselves logged in. That makes asserting login as simple as checking for an identity.
Hide code highlighting
1
2
3
4
5
6
7
8
9
10
<?php
public function assertNotLoggedIn()
{
    $this->assertFalse( Zend_Auth::getInstance()->hasIdentity(), 'Login assertion failed' );
}
 
public function assertLoggedIn()
{
    $this->assertTrue( Zend_Auth::getInstance()->hasIdentity(), 'Login assertion failed' );
}

These simple assertions 3 ensure that we’re logged in (or not logged in)

Putting It All Together
Putting it all together, we now have a base class which provides all of our test cases with the functionality we need.
Hide code highlighting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?php 
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';
 
class BaseControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{
 
    /**
     * Contains models which should be destroyed on tear down
     *
     * @var array
     */
    protected $_disposables = array();
 
 
    protected function tearDown()
    {
        parent::tearDown();
 
        foreach ( $this->_disposables as $model ) {
            if ( $model instanceof Doctrine_Record ) {
                $model->delete();
            }
            unset( $model );
        }
    }
 
    /**
     * Sets a model as disposable, so teardown automatically deletes it
     *
     * @param Doctrine_record $model
     */
    protected function _setDisposable( Doctrine_record $model )
    {
        $this->_disposables[] = $model;
    }
 
    /**
     * Sets the current state as if there is a logged in user
     *
     * @param object $identity the idenity to use, otherwise one is generated
     * @return void
     */
    protected function _doLogin( $identity = null )
    {
        if ( $identity === null ) {
            $identity = $this->_generateFakeIdentity();
        }
 
        Zend_Auth::getInstance()->getStorage()->write( $identity );
    }
 
    /**
     * Generates a fake identity, usefull for simulating a logged in user
     *
     * @param boolean $unique
     * @return StdClass an identity
     */
    protected function _generateFakeIdentity( $unique = false )
    {
        $identity = new stdClass();
 
        $account = new Account();
            $account->username     = 'AutoTest' . time();
            $account->emailAddress = 'autotest' . time() . '@example.org';
            $account->password     = md5( 'password' );
            $account->confirmed    = true;
            $account->enabled      = true;
            $account->save();
            $this->_setDisposable( $account );
 
            foreach( $account->toArray() as $key => $val ) {
                $identity->$key = $val;
            }
            unset( $identity->password );
 
            return $identity;
    }
 
    public function assertNotLoggedIn()
    {
        $this->assertFalse( Zend_Auth::getInstance()->hasIdentity(), 'Login assertion failed' );
    }
 
    public function assertLoggedIn()
    {
        $this->assertTrue( Zend_Auth::getInstance()->hasIdentity(), 'Login assertion failed' );
    }
 
}

Writing Our Controller Test
Now that our groundwork has been laid, we can finally start writing our controller test.
Our first set of test cases cover the requirement “when a user registers, they must confirm their email address before they can access their account”. To do this, we need to simulate a user posting their valid registration details to our controller, and verify that the account created is not set as confirmed. We then need to test that submitting login information for a non-confirmed account to our login action does not result in an authenticated user.
Hide code highlighting
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
public function testRegisterCreatesNewUnconfirmedAccount()
{
    $email = 'autotest' . time() . '@example.org';
    $data = array(
        'emailAddress'    => $email,
        'password'          => 'testpassw0rd',
        'passwordconfirm' => 'testpassw0rd'
    );
 
    $_POST = $data;
 
    $this->dispatch( '/account/register' );
    //try to find the account record
    $table = Doctrine_Table::create( 'Account' ) ;
    $account = $table->findOneByEmailAddress( $email );
    $this->_setDisposable( $account );
    $this->assertNotNull( $account );
    $this->assertFalse( $account->confirmed, 'Account was not marked as unconfirmed' );
}
 
/**
 * Asserts that a user that hasn't been confirmed cannot login
 *
 */
public function testUnconfirmedUserCannotLogin()
{
    $email = 'autotest' . time() . '@example.org';
 
    $account = new Account();
    $account->username     = $email;
    $account->password     = md5( 'password' );
    $account->emailAddress = $email;
    $account->confirmed    = false;
    $account->enabled      = true;
    $account->save();
 
    $this->_setDisposable( $account );
 
    $_POST['username'] = $email;
    $_POST['password'] = 'password';
 
 
 
 
    $this->dispatch( '/account/login' );
    $this->assertFalse( Zend_Auth::getInstance()->hasIdentity() );
    $this->assertNotRedirect();
}

Our first test simply uses the $_POST global variable to simulate submitting our registration form with some test data. After dispatch(), we use Doctrine_Table to find the model created by AccountController::registerAction(), then assert that the record was found and that it was not marked as confirmed.
The second test works by manually inserting a record that’s not confirmed, and making sure no user is authorized when attempting to login with that user’s account information. As an added bonus, we also use assertNotRedirect() to make sure our controller didn’t redirect. Our controller should only redirect if login was successful, otherwise it would be confusing to a user.

Original: Automated Testing Using Zend Framework

Rating: 12345   << Please, rate this article


Related articles:
   6 Tools To Be An Effective Web Developer
   Understanding scope in object oriented JavaScript
   An Introduction to the Art of Unit Testing in PHP
   Integrating FCKeditor with Zend_Form
   A caching pattern for models


Comments of article:

 
巨人倍増 [2016-01-06]
媚薬:http://www.xxkanpo.com/
d10媚薬:http://xn--d10-hl9e441q.xxkanpo.com/
女性催情剤:http://d10媚薬.xxkanpo.com/< br /> 威哥王:http://www.xxkanpo.com/product/440.h tml
紅蜘蛛:http://www.xxkanpo.com/product/43.ht ml
花痴:http://www.xxkanpo.com/product/237.html
三體牛鞭:http://www.xxkanpo.com/product/41 1.html
三体牛鞭:http://www.xxkanpo.com/product/41 1.html
巨人倍増:http://www.xxkanpo.com/product/38 .html
新一粒神:http://www.xxkanpo.com/product/46 5.html
蟻王:http://www.xxkanpo.com/product/126.html
アリ王:http://www.xxkanpo.com/product/126.h tml
夜夜堅:http://www.xxkanpo.com/product/33.ht ml
男宝:http://www.xxkanpo.com/product/409.html
SEX DROPS:http://www.xxkanpo.com/product/224.html
媚薬カプセル:http://www.xxkanpo.com/Char ming/18.html
五便宝:http://www.xxkanpo.com/product/41.ht ml
d10媚薬:http://xxkanpo.com/product/366.html< br /> 勃動力三體牛鞭:http://www.xxkanpo.com/p roduct/411.html
蟻力神:http://www.xxkanpo.com/product/23.ht ml
狼1号:http://www.xxkanpo.com/product/62.html
狼一号:http://www.xxkanpo.com/product/62.ht ml
蔵八宝:http://www.xxkanpo.com/product/464.h tml
ビグレックス:http://www.xxkanpo.com/prod uct/22.html
壮天根:http://www.xxkanpo.com/product/54.ht ml
紅蜘蛛:http://www.xxkanpo.com/product/43.ht ml
淫インモラル:http://www.xxkanpo.com/prod uct/477.html
三便宝:http://www.xxkanpo.com/product/28.ht ml
美人豹:http://www.xxkanpo.com/product/389.h tml
催淫カプセル:http://www.xxkanpo.com/prod uct/391.html
縮陰膏:http://www.xxkanpo.com/product/249.h tml
催情剤:http://www.xxkanpo.com/Charming/17.h tml
絶對高潮:http://www.xxkanpo.com/product/25 9.html
D8 催情剤:http://www.xxkanpo.com/product/404.html< br /> 催情丹:http://www.xxkanpo.com/product/460.h tml
粉劑媚薬:http://www.xxkanpo.com/Charming/1 6.html

巨人倍増:http://www.xxkanpo.com/product/12 .html
三体牛鞭:http://www.xxkanpo.com/product/41 1.html
三體牛鞭:http://www.xxkanpo.com/product/41 1.html
D5原液:http://www.xxkanpo.com/product/231.ht ml
花之欲:http://www.xxkanpo.com/product/291.h tml
催淫通販:http://www.xxkanpo.com/product/10 .html
終極痩身:http://www.xxkanpo.com/product/19 3.html
d9催情剤:http://www.xxkanpo.com/product/236 .html
精力剤:http://www.xxkanpo.com/Energy/Energy .html
媚薬 通販:http://www.xxkanpo.com/Charming/Charming-me dicine.html
魔根:http://www.xxkanpo.com/product/436.html
殺精剤:http://www.xxkanpo.com/product/468.h tml
潤滑剤:http://www.xxkanpo.com/Charming/15.h tml
三鞭粒:http://www.xxkanpo.com/product/437.h tml
蔵鞭王:http://www.xxkanpo.com/product/658.h tml
即効性精力剤:http://www.xxkanpo.com/Ener gy/14.html
夜狼神:http://www.xxkanpo.com/product/571.h tml
催淫カプセル:http://www.xxkanpo.com/prod uct/391.html
徳国公牛:http://www.xxkanpo.com/product/65 7.html
kkk超強力催情水:http://www.xxkanpo.com/p roduct/586.html
催情丹:http://www.xxkanpo.com/product/460.h tml
男根増長素:http://www.xxkanpo.com/product /463.html
D6 催情剤:http://www.xxkanpo.com/product/238.html< br /> 韓国痩身1号:http://www.xxkanpo.com/produc t/367.html
曲美:http://www.xxkanpo.com/product/476.html
天天素:http://www.xxkanpo.com/product/17.ht ml
精力剤:http://www.xxkanpo.com/Energy/Energy .html
滋養強壮:http://www.xxkanpo.com/Energy/13. html
媚薬 通販:http://www.xxkanpo.com/Charming/Charming-me dicine.html
V26:http://www.xxkanpo.com/product/189.html
街頭覇王:http://www.xxkanpo.com/product/65 2.html
徳国公牛:http://www.xxkanpo.com/product/65 7.html
蔵鞭王:http://www.xxkanpo.com/product/658.h tml
日本性素:http://www.xxkanpo.com/product/60 2.html
婦科千金片:http://www.xxkanpo.com/product /424.html
V26:http://www.xxkanpo.com/product/189.html
淫インモラル:http://www.xxkanpo.com/prod uct/477.html
終極痩身:http://www.xxkanpo.com/product/19 3.html
催情水:http://www.xxkanpo.com/product/586.h tml
催情粉:http://www.xxkanpo.com/product/261.h tml


夜夜堅 [2016-01-06]
D5原液:http://www.hellokanpo.com/view/FLYD5yuan. html
蒼蝿水:http://www.hellokanpo.com/view/FLY-D 5.html
紅蜘蛛:http://www.hellokanpo.com/view/hong- zhi-zhu.html
美人豹:http://www.hellokanpo.com/view/meire nbao.html
催情丹:http://www.hellokanpo.com/view/cuiqi ngdan.html
蟻王:http://www.hellokanpo.com/view/antking. html
大印象ダイエット茶:http://www.helloka npo.com/view/dayinxiang.html
RU486:http://www.hellokanpo.com/view/beijing-r u486.html
アリ王:http://www.hellokanpo.com/view/antki ng.html
SEX DROPS:http://www.hellokanpo.com/view/sex-drops.htm l
セフラジン:http://www.hellokanpo.com/view /kangshengwuzhi.html
夜夜堅:http://www.hellokanpo.com/view/yey ejian1200.html
RU486:http://www.xn--fiqs66igffqph3re.com
威哥王:http://www.xn--ogr73cd8ge4qn7n.com 妖姫:http://youhi.hellokanpo.com
淫インモラル:http://immoral.hellokanpo.c om
黒倍王:http://www.hellokanpo.com/view/heibe iwang.html
D10催情剤:http://www.hellokanpo.com/view/D1 0-meiyao.html
夜夜堅:http://www.hellokanpo.com/view/yeyej ian1200.html
消渇丸:http://www.hellokanpo.com/view/xiaok ewan.html
新一粒神:http://www.hellokanpo.com/view/xi nyilishen.html
魔根:http://www.hellokanpo.com/view/muogen.h tml
勃動力三體牛鞭:http://www.hellokanpo.co m/view/santiniubian.html
男宝:http://www.hellokanpo.com/view/nanbao.h tml
巨人倍増:http://www.hellokanpo.com/view/ju renbeiceng.html
三體牛鞭:http://www.hellokanpo.com/view/sa ntiniubian.html
三体牛鞭:http://www.hellokanpo.com/view/sa ntiniubian.html
威哥王:http://www.hellokanpo.com/view/weige wang.html
狼1号:http://www.hellokanpo.com/view/langyih ao.html
狼一号:http://www.hellokanpo.com/view/langy ihao.html
三便宝:http://www.hellokanpo.com/view/satib o-capsules.html
蟻力神:http://www.hellokanpo.com/view/yilis hen.html
淫インモラル:http://immoral.hellokanpo.c om
妖姫:http://youhi.hellokanpo.com
D10媚薬:http://www.hellokanpo.com/view/D10-m eiyao.html
D10催情剤:http://www.hellokanpo.com/view/D1 0-meiyao.html
花痴:http://www.hellokanpo.com/view/huachi.h tml
D8 催情剤:http://www.hellokanpo.com/view/SpanishFl iegeD8.html
FLY D5:http://www.hellokanpo.com/view/fly-d5.html
韓国痩身一号:http://www.hellokanpo.com/v iew/hanguoshou-575.html
媚薬 通販:http://www.xn--b3ss6gtv8bq3f3re.com
媚薬通販店:http://www.xn--b3ss6gtv8bq3f3r e.com
媚薬 販売:http://www.hellokanpo.com/
女性用媚薬:http://www.hellokanpo.com
三鞭粒:http://www.hellokanpo.com/view/wei.h tml
韓国痩身1号:http://www.hellokanpo.com/vie w/hanguoshou-575.html
媚薬 淫インモラル:http://immoral.hellokanpo.com 媚薬 インモラル:http://immoral.hellokanpo.com
媚薬:http://www.hellokanpo.com/meiyao
催情剤:http://www.hellokanpo.com/view/D10-m eiyao.html
催情:http://www.hellokanpo.com/view/D10-meiy ao.html
催情粉:http://www.hellokanpo.com/view/hongz hizhu1.html
媚薬 妖姫:http://youhi.hellokanpo.com
妖姫 効果:http://youhi.hellokanpo.com
妖姫 販売:http://youhi.hellokanpo.com
催淫剤:http://www.hellokanpo.com/view/juedu igaochao.html
淫インモラル 販売:http://immoral.hellokanpo.com
壮天根:http://www.hellokanpo.com/view/ZTG.h tml
蔵八宝:http://www.hellokanpo.com/view/zhang babao.html
五便宝:http://www.hellokanpo.com/view/wodib o-capsules.html
曲美:http://www.hellokanpo.com/view/xinqum ei.html
絶對高潮:http://www.hellokanpo.com/view/ju edui.html
D10:http://www.hellokanpo.com/view/D10-meiyao. html
絶對高潮カプセル:http://www.hellokanpo .com/view/juedui.html
d9催情:http://www.hellokanpo.com/view/D9-INV ERMA.html


巨人倍増 [2016-01-06]
巨人倍増:http://www.chinakanpo.com/product/j rbz.html
五便宝:http://www.chinakanpo.com/product/ wubianbao.html
狼一号:http://www.chinakanpo.com/product/ langyihao.html
狼1号:http://www.chinakanpo.com/product/la ngyihao.html
威哥王:http://www.chinakanpo.com/product/we igwang.html
妖姫:http://www.chinakanpo.com/product/yah oji3.html
威哥王:http://www.威哥王通販.com/
威哥王:http://www.威哥王通販.net/
紅蜘蛛:http://www.紅蜘蛛通販.net/
紅蜘蛛:http://www.紅蜘蛛通販.com/
妖姫:http://www.妖姫.net/
妖姫:http://www.妖姫.com/
三便宝:http://www.三便宝.com/
三便宝:http://www.三便宝.net/
花痴:http://www.花痴.net/
RU486:http://www.中絶薬.com/
淫インモラル:http://www.immoralsale.com/
インモラル:http://www.immoralsale.com/
狼一号:http://www.狼一号.com/
狼1号:http://www.狼一号.com/
淫インモラル:http://www.immoralsale.com/
巨人倍増:http://www.巨人倍増.net/
狼一号:http://www.xn--4gq48lvu4a.com/
紅蜘蛛:http://www.chinakanpo.com/product/ hzhzyd.html
花痴:http://www.chinakanpo.com/product/hua chi.html
三体牛鞭:http://www.chinakanpo.com/produ ct/santiniubian.html
三體牛鞭:http://www.chinakanpo.com/produ ct/stnb.html
蟻力神:http://www.chinakanpo.com/product/ irishinhachi.html
男宝:http://www.chinakanpo.com/product/nan bao.html
新一粒神:http://www.chinakanpo.com/produ ct/product/xyls.html
夜夜堅:http://www.chinakanpo.com/product/ yyj.html
黒倍王:http://www.chinakanpo.com/product/ heibeiwang.html
淫インモラル:http://www.chinakanpo.com /product/immoral.html
RU486:http://www.chinakanpo.com/product/zjyr ubjzz.html
RU486中絶薬:http://www.中絶薬.com/
中絶薬RU486:http://www.中絶薬.com/
RU486激安:http://www.中絶薬.com/
ru486 通販:http://www.中絶薬.com/
妖姫 媚薬:http://www.妖姫.com/
妖姫 販売:http://www.妖姫.com/
妖姫 通販:http://www.妖姫.com/
妖姫 効果:http://www.妖姫.com/
妖姫 媚薬:http://www.妖姫.net/
妖姫 販売:http://www.妖姫.net/
妖姫 通販:http://www.妖姫.net/
妖姫 効果:http://www.妖姫.net/
粉剤媚薬:http://www.chinakanpo.com/produ ct/cangyf.html
V26:http://www.chinakanpo.com/product/sxjf.h tml
碧生源:http://www.chinakanpo.com/product/ bishengyuan.html
中絶薬:http://www.chinakanpo.com/product/ zjyrubjzz.html
曲美:http://www.chinakanpo.com/product/qum ei.html
催淫薬:http://www.chinakanpo.com/catalog/ 63.html
勃起促進:http://www.chinakanpo.com/catal og/16.html
媚薬:http://www.女性用媚薬.com/
勃起促進:http://www.chinakanpo.com/catal og/16.html
中絶薬:http://www.chinakanpo.com/catalog/ 25.html
曲美:http://www.chinakanpo.com/catalog/25. html
媚薬:http://www.chinakanpo.com/catalog/60. html
催淫薬:http://www.chinakanpo.com/catalog/ 63.html
D10媚薬:http://www.chinakanpo.com/product/ meiyao.html
蔵八宝:http://www.chinakanpo.com/product/ zbb.html
壮天根:http://www.chinakanpo.com/product/ ztg.html
魔根:http://www.chinakanpo.com/product/mgj zc.html
FLY D5:http://www.chinakanpo.com/product/cys.html
蒼蝿水:http://www.chinakanpo.com/product/ cangyshui.html
片仔廣:http://www.chinakanpo.com/product/ pzhnhjdp.html
消渇丸:http://www.chinakanpo.com/product/ xiaokewan.html
天天素:http://www.chinakanpo.com/product/ tts.html
韓国痩身一号:http://www.chinakanpo.com /product/hgssyhmtx.html


三体牛鞭 [2016-01-06]
催淫カプセル:http://www.okkanpo.com/Produc t/245.html
ok漢方:http://www.okkanpo.com/
アフリカ超人:http://www.okkanpo.com/Prod uct/571.html
街頭覇王睾丸素カプセル:http://www.o kkanpo.com/Product/652.html
徳国公牛:http://www.okkanpo.com/Product/65 7.html
壮根精華素:http://www.okkanpo.com/Product /336.html
壮根精華素 6錠入り:http://www.okkanpo.com/Product/158.html
超強 黒倍王:http://www.okkanpo.com/Product/187.html< br /> リドスプレー :http://www.okkanpo.com/Product/155.html
精力剤:http://www.okkanpo.com/catalog/energ y.html
漢方薬:http://www.okkanpo.com/catalog/kanpo u.html
中絶-避妊薬:http://www.okkanpo.com/catalo g/hininn.html
紅蜘蛛:http://www.okkanpo.com/product/167.h tml

威哥王:http://www.okkanpo.com/product/8.htm l
三體牛鞭:http://www.okkanpo.com/product/43 7.html
V26:http://www.okkanpo.com/product/324.html
勃起促進:http://www.okkanpo.com/catalog/pe nis-erectile.html
五便宝:http://www.okkanpo.com/product/222.h tml
天天素:http://www.okkanpo.com/product/360.h tml
淫インモラル:http://www.okkanpo.com/Pr oduct/495.html
インモラル:http://www.okkanpo.com/Produ ct/477.html
蔵八宝:http://www.okkanpo.com/Product/445 .html
新一粒神:http://www.okkanpo.com/product/44 4.html
SEX DROPS:http://www.okkanpo.com/product/88.html
女性用媚薬:http://www.okkanpo.com/catalog /Aphrodisiac.html
女用媚薬:http://www.okkanpo.com/catalog/Ap hrodisiac.html
RU486:http://www.okkanpo.com/Product/398.html< br /> 三体牛鞭:http://www.okkanpo.com/product/43 7.html
妖姫:http://www.okkanpo.com/Product/479.html

D5原液:http://www.okkanpo.com/product/63.htm l
三體牛鞭:http://www.okkanpo.com/product/43 7.html
三便宝:http://www.okkanpo.com/Product/395.h tml
セックスドロップ:http://www.okkanpo.co m/product/277.html
曲美:http://www.okkanpo.com/product/371.html
精力剤:http://www.okkanpo.com/catalog/energ y.html
中絶薬:http://www.okkanpo.com/catalog/Inter ruption.html
滋養強壮:http://www.okkanpo.com/catalog/Nu trition.html
ペニス増大:http://www.okkanpo.com/catalog /Penis-increase.html
プロコミルスプレー:http://www.okkanpo .com/product/191.html
蟻力神:http://www.okkanpo.com/product/159.h tml
巨人倍増:http://www.okkanpo.com/product/13 3.html
絶對高潮:http://www.okkanpo.com/product/24 5.html
リドスプレー:http://www.okkanpo.com/prod uct/155.html
紅蜘蛛:http://www.okkanpo.com/product/167.h tml
狼1号:http://www.okkanpo.com/Product/99.ht ml
三鞭粒:http://www.okkanpo.com/product/436.h tml
狼1号:http://www.okkanpo.com/Product/99.ht ml
男宝:http://www.okkanpo.com/Product/237.ht ml
夜夜堅:http://www.okkanpo.com/Product/35. html
壮天根:http://www.okkanpo.com/Product/194 .html


wxm [2016-03-23]
air huarache
air max shoes
air max
coach factory
coach outlet
mcm backpack outlet
michael kors outlet
michael kors outlet online
beats headphones
nike air jordan
north face outlet
supra footwear
uggs on sale
abercrombie and fitch
abercrombie and fitch
abercrombie fitch
abercrombie and fitch
abercrombie
abercrombie kids
adidas
adidas
adidas
adidas schuhe
adidas shoes
adidas
adidas
air huarache
nike huarache
air jordans
nike air
air max 2015
air max 90
asics
asics gel
babyliss
barbour jackets
barbour jacket outlet
basketball shoes
bcbg max
bcbg max azria
beats by dre
dre beats
beats headphones
beats by dr dre
bebe clothing
bottega veneta
bottega bags
burberry outlet online
burberry handbags
burberry outlet
burberry
burberry online shop
burberry outlet
burberry sale
burberry outlet
burberry sale
burberry handbags
burberry outlet online
burberry outlet store
burberry outlet online
calvin klein underwear
canada gooses outlet
gooses jackets
celine bags
chanel handbags
chanel bags
softball bats
nfl jerseys
cheap nfl jerseys
air jordan shoes
michael kors outlet
michael kors
nike shoes
oakley vault
oakley vault
oakley sunglasses
ray bans
ray ban outlet
shoes outlet
uggs
chi hair
chi flat iron
louboutin shoes
louboutin shoes
red bottom shoes
christian louboutin
christian louboutin
christian louboutin shoes
louboutin shoes
coach factory outlet
coach factory
coach factory outlet online
coach factory
coach outlet
coach outlet online
coach outlet store online
coach outlet online
coach purses outlet online
coach factory outlet
chanel
chanel purses
converse
converse sneakers
converse outlet
converse shoes
purses and handbags
designer handbags
ed hardy
cheap eyeglasses
eyeglasses frames
womens clothing
ferragamo
ferragamo shoes
hair straightener
giuseppe zanotti
giuseppe shoes
gucci shoes outlet
gucci belts
gucci mens shoes
gucci handbags
gucci outlet
gucci shoes
gucci shoes
gucci
designer handbags
harrods london
hermes bags
hermes outlet
hermes birkin
hogan
hollister clothing store
abercrombie
hollister co
hollister
hollister online shop deutschland
hollister kids
rolex
insanity calendar
instyler ionic styler
iphone 4s cases
jimmy choo
jimmy choo
jordans for sale
air jordans
air jordan retro
juicy couture clothings
juicy couture
kate spade outlet online
kate spade outlet
kate spade
ralph lauren
levis outlet store
long champ
longchamp taschen
longchamp
longchamp handbags
longchamp handbags
longchamp
longchamp outlet
louboutin shoes
louis vuitton outlet stores
vuitton handbags
louis vuitton handbags
louis vuitton australia
louis vuitton purses
louis vuitton
louis vuitton
louis vuitton outlet
louis vuitton bags
louis vuitton taschen
lululemon australia
lululemon canada
lulu lemon
mac cosmetics
mac cosmetics
marc jacobs
mcm bags
mcm handbags
mcm backpack
mcm backpack outlet
jordan
michael kors
michael kors outlet
michael kors
michael kors
cheap michael kors
michael kors purses
cheap michael kors
michael kors
michael kors handbags
michael kors canada
michael kors bags
michael kors outlet online
cheap michael kors
michael kors bags
michael kors handbags
michaelkors.com
michael kors outlet
michael kors bags
michael kors taschen
michael kors handbags
mizuno running
michael kors handbags
michael kors outlet
moncler jackets
moncler jackets outlet
mont blanc
new balance canada
new balance
new balance outlet
new balance
new balance shoes
coach purses factory
cheap jerseys
nike
air force
air max
nike air max
air max
air max
air max
nike air max 2014
nike outlet
nike free run 5.0
nike free
nike free run
free run
huarache
nike mercurial
roshe run
nike roche run
nike roshe
roshe runs
nike
nike.com
nike canada
nike outlet
nike shoes
nike
nike
nike.com
nike factory
north face jackets
oakley
gafas oakley
oakley outlet online
oakley sunglasses cheap
cheap oakley sunglasses
oakley sunglasses
oakley
cheap oakley sunglasses
oakley sunglasses
oakley sunglasses cheap
oakley sunglasses
relojes
replica watches
burberry outlet
p90x3
pandora charms
pandora charms
pandora canada
pandora jewellery australia
pandora bracelet
polo outlet store
ralph lauren outlet
polo ralph lauren
ralph lauren outlet online
prada
prada outlet
prada handbags
prada shoes
prada outlet
pandora
puma online shop
puma shoes
ralph lauren
ralph lauren factory store
ralph lauren online shop
ralph lauren
polo ralph lauren outlet
polo ralph lauren
ralph lauren
ralph lauren outlet
polo ralph
polo ralph lauren outlet online
ralph lauren
ralph lauren polo
rayban
ray ban zonnebril
ray ban
ray ban
ray ban outlet
ray bans
ray ban sunglasses outlet
ray ban sunglasses
ray-ban sunglasses
ray ban wayfarer
reebok
replica handbags
replica watches
retro jordans
rolex watches
rolex watches
watches
rolex watches for sale
roshe run
roshe runs
salomon
salvatore ferragamo
soccer shoes
softball bats
supra shoes
swarovski
swarovski canada
swarovski jewelry
swarovski crystal
swarovski online
swarovski jewelry
michael kors outlet online
north face
northface
the north face
the north face outlet
north face
north face jackets
north face backpacks
thomas sabo
thomas sabo uk
tiffany and co australia
tiffany jewelry
tiffany and co
tiffany and co
tiffany und co
timberland shoes
timberland outlet
the north face outlet
coach outlet store
www.tommyhilfiger.nl
hilfiger online shop
tommy hilfiger outlet
tommy hilfiger
tommy hilfiger online
tommy hilfiger outlet stores
tommy hilfiger outlet stores
toms outlet
toms outlet
toms shoes
toms outlet
toms shoes outlet
toms shoes outlet
toms outlet
toms.com
tory burch sale
tory burch handbags
tory burch
tory burch sale
true religion outlet
true religion jeans outlet
cheap true religion
true religion jeans women
ugg boots
uggs canada
uggs
ugg boots clearance
uggs outlet
ugg australia
ugg
ugg australia
uggs on sale
uggs outlet
ugg australia
ugg boots
uggs boots
uhren shop
vans
vans
vans shoes
bride dresses
wedding dress
woolrich outlet
yoga pants
lulu lemon
coach bags outlet


 

Leave a comment:

Name


E-mail


Message