PHP Machinist Presentation
-
Upload
adam-englander -
Category
Technology
-
view
3.378 -
download
1
description
Transcript of PHP Machinist Presentation
PHP MachinistTesting Object Factory
Primary Contributors
Stephan Soileau● Former Employee● Current lead developer on
Cassandra 3.0● Testing evangelist and BDD guru
Adam Englander● Selling Source Employee● Current lead developer for CMG● Famously rode on the shirt tails
of Stephan to BDD fame and glory
Why PHP Machinist Was Created
● Behat, a Cucumber port is born.○ Factory Girl/Machinist port for handling relational
data as Gherkin tables is needed.● DBUnit, a PHP port of DBUnit is just as
terrible as DBUnit.○ XML data structure too verbose○ Large relational datasets are unmanageable
● Phactory is almost good enough but would not handle compound primary keys.○ Phactory blueprints are very similar but does not
handle compound keys.○ Only supports PDO data sources
Connecting to Your Data
PHP Machinist provides a standard interface with the following provided implementations:● PDO
○ SQLite○ MySQL
● Doctrine ORM● Experimental NoSQL available in doctrine-
mongodb branch● Doctrine MongoDB● MongoDB
Connection Example: PDO SQLite
Easy way:
$pdo = new PDO("sqlite::memory:");\machinist\Machinist::Store(SqlStore::fromPdo($pdo));
Hard way:
$pdo = new PDO("sqlite::memory:");$store = new \machinist\driver\Sqlite($pdo);\machinist\Machinist::Store($store);
Blueprints Define Data Structures
Blueprints define the data structure by:● Defining tables with aliases● Define default values● Define relationships● Useable in PHPUnit tests and Behat context
Blueprints ExampleCreate a blueprint called "cardboardbox" on table "box" and default the "type" to "cardboard"$cbBox = Machinist::Blueprint("cardboardbox", "box", array("type" => "cardboard"));
Create a blueprint called "plasticbox" on table "box" and default the "type" to "plastic"$plBox = Machinist::Blueprint("plasticbox", "box", array("type" => "plastic"));
Create a blueprint called "crayon" on table "stuff" with "name" defaulted to "crayon" and a relationship called box that references the the "box_id" column in the "stuff" table. If foreign method is not called, the primary key for the foreign key is assumed.Machinist::Blueprint("crayon", "stuff" array( "name" => "crayon", "box" => Machinist::Relationship($cbBox)->local("box_id"), ));
make() Stores Data
● Make stores data in the tables.● It will use default data.● It will override the default data with data
provided in the make call.● Relationship data, if provided will be
associated or added if it does not exist.● Relationship data will use defaults for data
not provided in the make call.
make() Example: Save Data$cbBox = Machinist::Blueprint("cardboardbox", "box", array("type" => "cardboard"));$plBox = Machinist::Blueprint("plasticbox", "box", array("type" => "plastic"));
Machinist::Blueprint("crayon", "stuff" array( "name" => "crayon" "box" => Machinist::Relationship($cbBox)->local("box_id"), ));
Make a crayon with the "name" defaulted to "crayon"Machinist::Blueprint("crayon")->make();
Make a crayon with the "name"of "red crayon" and "color" of "red"Machinist::Blueprint("crayon")->make(array(
"name" => "red crayon", "color" => "red"
);
make() Example: Save Related Data$cbBox = Machinist::Blueprint("cardboardbox", "box", array("type" => "cardboard"));$plBox = Machinist::Blueprint("plasticbox", "box", array("type" => "plastic"));Machinist::Blueprint("crayon", "stuff" array( "name" => "crayon" "box" => Machinist::Relationship($cbBox)->local("box_id"), ));
Make a crayon with the no associated boxMachinist::Blueprint("crayon")->make();
Make a crayon with a box and create the box as none existsMachinist::Blueprint("crayon")->make(array("box" => array("type" => "new type")));
Make a new crayon with a box and use the same box as it existsMachinist::Blueprint("crayon")->make(array("box" => array("type" => "new type")));
find() Retrieves Data dataFind finds all rows by criteria.FindOne finds one row by criteriaFindOrCreate finds one row by criteria or creates a row using the criteria as data.Find retrieves data by:● Primary key● Column/Value array● Foreign key relationship dataFind populates relationship data if relational data exists.Machine objects are returned by Find*
find() Example$cbBox = Machinist::Blueprint("cardboardbox", "box", array("type" => "cardboard"));$plBox = Machinist::Blueprint("plasticbox", "box", array("type" => "plastic"));Machinist::Blueprint("crayon", "stuff" array( "name" => "crayon" "box" => Machinist::Relationship($cbBox)->local("box_id"), ));Machinist::Blueprint("crayon")->make();Machinist::Blueprint("crayon")->make(array("box" => array()));$boxes = Machinist::Blueprint("crayon")->find("name" => "crayon")->toArray();
Resultarray(
array("name" => "crayon", ...) ,array("name" => "crayon", "box" => array("type" => "cardboard",...),...)
)
wipe() Cleans Up Test Data
● Wipe is available at two levels:○ Blueprints can perform a wipe to remove all data in
the related table.○ Machinist instance method can clean up data for
tables related to all defined machines.○ Machinst static method can clean up data for one or
more machines.● Wipe can delete data or truncate tables if the
Store implentation supports the feature.● Machinist level wipe can specify exclusions
as an array of blueprint names
wipe() Examples
Truncate the "crayon" blueprint's table
machinist\Machinist::wipe("crayon", true);machinist\Machinist::Blueprint("crayon", true);
Truncate all blueprints tables but the "cbBox" blueprint's table
machinist\Machinist::wipe(null, true, array("cbBox"));machinist\Machinist::instance()->wipe(true, array("cbBox"));
Behat Usage
PHP Machinist is designed to be utilized within Behat features with little to no additional work. It supplies:● Feature context that can be added to the
default feature context● Steps for populating data as well as
validating data● Easy Gherkin table interface
Behat Example: Feature Contextclass FeatureContext extends BehatContext implements ClosuredContextInterface { public function __construct(array $parameters) { $config = array( "database" => array( "default" => array("dsn" => "sqlite::memory:") ) );
$context = new \machinist\behat\MachinistContext($config); $this->useContext('machinist', $this->getMachinistContext()); }
Behat ExampleFeature: Cardboard Box As a crayon I should be able to have a cardboard box Background: Given there are no machines And the following crayons exists: | color | box | | red | type: plastic |
● Performed a wipe on all Blueprints● Performed a make on the "crayon" blueprint with the
"color" column set to red● Performed a findOrCreate on the blueprint in the "box"
association, "cbBox", with a type of plastic