Your SlideShare is downloading. ×
Phactory
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Phactory

1,339

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,339
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. A Database Factory for PHP http://phactory.org Chris Kite Sr. Web Engineer at Offers.com© 2009 Vertive, Inc.Proprietary and Confidential @chriskite
  • 2. Who are we? Chris Kite » B.S. in Computer Science from UT Austin » Senior Web Engineer at Offers.com » Creator of Phactory » Likes martial arts, sushi Josh Butts » B.A. in Computer Science from UT Austin » Director of Web Development at Offers.com » Likes fast cars, plain burgers © 2009 Vertive, Inc. Proprietary and Confidential
  • 3. Phactory: What is it?Alternative to database fixtures for unit testsDefine and create objects in codeProvides a lightweight ORMWorks with MySQL, SQLite, and MongoDB © 2009 Vertive, Inc. Proprietary and Confidential
  • 4. Phactory is developed and used at Offers.com
  • 5. Databases in Unit Testing © 2009 Vertive, Inc. Proprietary and Confidential
  • 6. Database FixturesA fixture is a statically defined set of dataEach test can have its own datasetPHPUnit provides support for loading fixtures: class DatabaseTest extends PHPUnit_Extensions_Database_TestCase { protected function getConnection() { $pdo = new PDO(mysql:host=localhost;dbname=testdb, root, ); return $this->createDefaultDBConnection($pdo, testdb); } protected function getDataSet() { return $this->createFlatXMLDataSet(dirname(__FILE__)./_files/bank-account-seed.xml); } } © 2009 Vertive, Inc. Proprietary and Confidential
  • 7. Database Fixtures<?xml version="1.0" encoding="UTF-8" ?><dataset> <post post_id="1" title="My First Post" date_created="2008-12-01 12:30:29" contents="This is my first post" rating="5" /> <post post_id="2" title="My Second Post" date_created="2008-12-04 15:35:25" contents="This is my second post" /></dataset> Vertive, Inc. © 2009 Proprietary and Confidential Example from http://www.phpunit.de/manual/current/en/database.html
  • 8. Database FixturesDrawbacks: » Typically in an unfriendly format like XML » You are left to your own devices to retrieve and manipulate data in your test » Can’t dynamically create objects » No concept of associations © 2009 Vertive, Inc. Proprietary and Confidential
  • 9. Database FactoriesDefine database test data in code, not flat filesCreate objects dynamically, rather than loading them all at onceDefine associations between objectsCan integrate with or provide ORM functionality © 2009 Vertive, Inc. Proprietary and Confidential
  • 10. Database FactoriesPhactory Example<?Phactory::setConnection(new PDO(sqlite:test.db));Phactory::define(user, array(name => Test User, email => user@example.com));$user = Phactory::create(user); // creates a row in the users tableprint("Hello, {$user->name}!"); // prints "Hello, Test User!" © 2009 Vertive, Inc. Proprietary and Confidential
  • 11. Using Phactory © 2009 Vertive, Inc. Proprietary and Confidential
  • 12. Connecting to the DatabasePhactory supports MySQL, SQLite, and MongoDBUses PDO for SQL databases<?require_once Phactory/lib/Phactory.php;$pdo = new PDO(mysql:host=127.0.0.1; dbname=testdb, user, password);Phactory::setConnection($pdo); © 2009 Vertive, Inc. Proprietary and Confidential
  • 13. Defining Table BlueprintsA blueprint defines default values for objects created in a particular table<?Phactory::define(user, array(name => test_user, age => 20));Phactory::define(post, array(text => This is a post, created_at => 1296663323)); © 2009 Vertive, Inc. Proprietary and Confidential
  • 14. Creating ObjectsWhen creating an object with Phactory, you can: » Specify values for fields that weren’t in the blueprint definition » Override any of the default values » Associate with other objects © 2009 Vertive, Inc. Proprietary and Confidential
  • 15. Creating ObjectsPhactory::define(user, array(name => test_user, age => 20));$john = Phactory::create(user, array(name => John Doe));$joe = Phactory::create(user, array(name => Joe Smith, activated => 1));$anon = Phactory::create(user);// $john looks like this:$john->id == 1;$john->name == John Doe;$john->activated == 0;// $joe looks like this:$joe->id == 2;$joe->name == Joe Smith;$joe->activated == 1;// $anon looks like this:$anon->id == 3;$anon->name == test_user;$anon->activated == 0; © 2009 Vertive, Inc. Proprietary and Confidential
  • 16. Retrieving ObjectsBasic ORM functionality allows you to retrieve Phactory objects from the databaseUses a simple get() method which takes an array of columns to match$joe = Phactory::get(user, array(id => 2));$joe = Phactory::get(user, array(age => 20, activated => 1)); © 2009 Vertive, Inc. Proprietary and Confidential
  • 17. AssociationsFor SQL databases, Phactory provides many-to-one and many-to-many associationsForeign key columns and join tables are filled in automatically when creating an object with associations © 2009 Vertive, Inc. Proprietary and Confidential
  • 18. AssociationsPhactory::define(author);Phactory::define(book, array(name => Test Book), array(primary_author => Phactory::manyToOne(author)));$twain = Phactory::create(author, array(name => Mark Twain));$book = Phactory::createWithAssociations(book, array(primary_author=> $twain));$book->author_id == $twain->getId(); © 2009 Vertive, Inc. Proprietary and Confidential
  • 19. SequencesDefine blueprints with automatically incrementing values » Include ‘$n’ in the definition » Sequence starts at 0, and is incremented each time an object is createdPhactory::define(user, array(name => user$n, age => $n));$user0 = Phactory::create(user); // name == user0, age == 0$user1 = Phactory::create(user); // name == user1, age == 1$user2 = Phactory::create(user); // name == user2, age == 2 © 2009 Vertive, Inc. Proprietary and Confidential
  • 20. Phactory and PHPUnit © 2009 Vertive, Inc. Proprietary and Confidential
  • 21. Basic Test Setuprequire_once Phactory/lib/Phactory.php;class ExampleTest extends PHPUnit_Framework_TestCase{ public static function setUpBeforeClass() { // create a db connection and tell Phactory to use it $pdo = new PDO("sqlite:test.db"); Phactory::setConnection($pdo); // reset any existing blueprints and empty any tables Phactory has used Phactory::reset(); // define default values for each user we will create Phactory::define(user, array(name => Test User $n, age => 18)); } public static function tearDownAfterClass() { Phactory::reset(); } public function tearDown() { // delete all objects from defined tables, but do not erase blueprints Phactory::recall(); } © 2009 Vertive, Inc. Proprietary and Confidential
  • 22. Structuring Shared DefinitionsUsually many of the test classes in your suite will need to use the same tablesDefine blueprints in one place, share them among many tests » Can include() a file of definitions, put definitions in a static class, etc. © 2009 Vertive, Inc. Proprietary and Confidential
  • 23. Structuring Shared DefinitionsSharedDefinitions.php<?Phactory::define(tag, array(name => Tag $n));Phactory::define(post, array(name => Test Blog Post, content => Test Content), array(tag => Phactory::manyToMany(tag, posts_tags)));ExampleTest.phpclass ExampleTest extends PHPUnit_Framework_TestCase{ public static function setUpBeforeClass() { $pdo = new PDO("sqlite:test.db"); Phactory::setConnection($pdo); Phactory::reset(); // include definitions common to several tests include(SharedDefinitions.php); }} © 2009 Vertive, Inc. Proprietary and Confidential
  • 24. Dynamic ObjectsRecall that with fixtures, your test data is all loaded at the start of the testWith Phactory, you can create or change test data during a test © 2009 Vertive, Inc. Proprietary and Confidential
  • 25. Dynamic Objectsclass MyPostClass { public static function countTagsForPost($post_id) { $stmt = $pdo->prepare("SELECT COUNT(*) AS num_tags FROM `posts_tags` WHERE `post_id` = ?"); $stmt->execute(array($post_id)); $result = $stmt->fetch(); return $result[num_tags]; }}Phactory::define(tag, array(name => Tag $n), array(post => Phactory::manyToMany(post, posts_tags)));Phactory::define(post, array(name => Test Blog Post, content => Test Content), array(tag => Phactory::manyToMany(tag, posts_tags)));$post = Phactory::create(post);$this->assertEquals(0, MyPostClass::countTagsForPost($post->getId()));$tag = Phactory::createWithAssociations(tag, array(post => $post)); © 2009 Vertive, Inc.$this->assertEquals(1, MyPostClass::countTagsForPost($post->getId())); Proprietary and Confidential
  • 26. Using Phactory with MongoDB require_once Phactory/lib/PhactoryMongo.php; Uses the Mongo PHP driver Almost exactly the same as regular SQL Phactory, except: » Documents returned as arrays rather than Phactory_Row objects » Phactory::get() supports all Mongo queries » Associations: embedsOne and embedsMany http://phactory.org/mongodb-guide/ © 2009 Vertive, Inc. Proprietary and Confidential
  • 27. QUESTIONS © 2009 Vertive, Inc. Proprietary and Confidential
  • 28. Were Hiring!Offers.com is hiring PHP Developers and Software Engineers in Austin, TXhttp://www.vertive.com/careers © 2009 Vertive, Inc. Proprietary and Confidential
  • 29. Thank You!These slides are online at http://slidesha.re/phactoryContact us on Twitter: @chriskite and @jimbojsbVisit http://phactory.org to download and for more information © 2009 Vertive, Inc. Proprietary and Confidential

×