debuggable

 
Contact Us
 
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34

Testing Models in CakePHP - Now let's get rid of the unnecessary ModelTest classes !

Posted on 30/7/08 by Tim Koschützki

Hey folks,

today I committed some stuff that will make a bigger impact on your Unit Testing development in CakePHP. It's a much cleaner way of how you are able to test models. Up until now there was always a need to create a so-called test model that extends your model-under-test in order to overwrite its $useDbConfig setting to be 'test_suite'. By that you ensured that your models run with the test_suite datasource when the tests are run.

Nate proposed ClassRegistry::config(), which allows you to tell the ClassRegistry class which datasource it shall use when
ClassRegistry::init() is used the next time (and thereby a model is instantiated). So what we are doing now in the testsuite is telling the ClassRegistry to use the test_suite db config whenever a new model is instantiated via ClassRegistry::init(). Doesn't make sense to you? Well, let's look at an example.

The following code is directly taken from the CookBook and shows the old way of doing things:

App::import('Model', 'Article');

class ArticleTest extends Article {
  var $name = 'ArticleTest';
  var $useDbConfig = 'test_suite';
}

class ArticleTestCase extends CakeTestCase {
  var $fixtures = array('app.article_test');

  function testPublished() {
    $this->ArticleTest =& new ArticleTest();

    $result = $this->ArticleTest->published(array('id', 'title'));
    $expected = array(
      array('ArticleTest' => array( 'id' => 1, 'title' => 'First Article' )),
      array('ArticleTest' => array( 'id' => 2, 'title' => 'Second Article' )),
      array('ArticleTest' => array( 'id' => 3, 'title' => 'Third Article' ))
      );

    $this->assertEqual($result, $expected);
  }
}

So far so good. The ArticleTest model extends the imported Article model to overwrite the datasource setting. Then it loads the ArticleTest fixture to use its data throughout the test. The drawback: A whole class that does practically nothing. In a bigger system with plenty of models and plenty of tests this can contribute to your hair loss - especially when you forget to name your fixture properly or provide the $name property in the Test Model.

With the new code in place, this will just work as well:

App::import('Model', 'Article');
class ArticleTestCase extends CakeTestCase {
  var $fixtures = array('app.article');

  function testPublished() {
    $this->Article =& ClassRegistry::init('Article');

    $result = $this->Article->published(array('id', 'title'));
    $expected = array(
      array('Article' => array( 'id' => 1, 'title' => 'First Article' )),
      array('Article' => array( 'id' => 2, 'title' => 'Second Article' )),
      array('Article' => array( 'id' => 3, 'title' => 'Third Article' ))
    );

    $this->assertEqual($result, $expected);
  }
}

So we got rid of the ArticleTest class and can now use the normal ArticleFixture that we probably use throughout the system anyway to provide some standard data for the application. Via the $test_suite setting in your database.php file you can control where and how the test data is imported.

The only change to your code: Instantiate the subject under test via ClassRegistry::init() instead of instantiating directly via the new operator.

To me this seems like the proper way to do it. No need for further unnecessary classes. Everything clean and controllable. Do you agree?

-- Tim Koschuetzki aka DarkAngelBGE

PS: Kudos again to Nate for ClassRegistry::config() !

 

CakePHP Workshop in Raleigh, NC (Sep 6-7)

Posted on 29/7/08 by Felix Geisendörfer

Hey folks,

Tim and I are very thrilled to announce the very first two-day workshop for everybody who is interested in mastering the CakePHP framework. The event is a collaboration between Debuggable Limited and the Cake Software foundation.

Special thanks goes to Credit Risk Management L.L.C. for sponsoring the rooms and catering!

Overview

  • Event Info: Raleigh, NC (4140 Parklake Ave)
  • Date: September 6 + 7 (Saturday + Sunday)
  • Seats: max 25
  • Costs: 600 USD / seat (Students pay 100 USD less)
  • Signup: Signup page

Speakers

  • Garrett J. Woodworth (President of the Cake Software Foundation)
  • Nate Abele (Cake Lead Developer)
  • Felix Geisendörfer (Cake Core Developer)
  • Tim Koschützki (Cake Core Contributor)

What to expect

This workshop is going to be very different from standard programming workshops. There will be two tracks in two different rooms. The main track will teach you everything you need to know in order to build great applications in CakePHP. You will be introduced to the MVC Pattern, learn how to setup CakePHP projects and watch a full application being put together over the course of two days. All sessions are delivered by the core developers of CakePHP so the information you get will be top quality and allow you to do things right from the beginning. This way you will save lots of time and money in the long run.

The second track is the most unique however. Instead of having a fixed schedule and sessions you will have the opportunity to directly pick the brains of the people who wrote CakePHP in a personal and informal manner. There is also a good amount of topics we are prepared to speak on like: git, javascript, cake internals and project management - just let us know what you want to learn and we will deliver : ).

In the second track you will also find out about some secret cutting edge things all of us are working on, including some early insights into Cake 2.0 and other unreleased additions to the cake core.

So all in all you get two days full of talks and chatting with the core developers that will be worth your while, including lots of fun in the evenings.

Schedule

Saturday, September 6th, 2008

Time Speaker Session Session Description
9:00 am -
10:00 am
Garrett Introduction
10:00 am -
10:30 am
coffee break
10:30 am -
11:30 am
Felix First steps in the kitchen
11:30 am -
12:30 pm
Nate MVC Introduction
12:30 pm -
1:30 pm
lunch break
1:30 pm -
2:30 pm
Nate Using CakePHP Models
2:30 pm -
3:30 pm
Tim Controllers in CakePHP
3:30 pm -
4:00 pm
coffee break
4:00 pm -
5:00 pm
Garrett Kitchen tools (CakePHP's Console)

Sunday, September 7th, 2008

Time Speaker Session Session Description
9:00 am -
10:00 am
Tim Keeping things yummy (Validation)
10:00 am -
10:30 am
coffee break
10:30 am -
11:30 am
Tim Unit testing in CakePHP
11:30 am -
12:30 pm
Felix Advanced Model usage
12:30 pm -
1:30 pm
lunch break
1:30 pm -
2:30 pm
Felix Ajaxifying your Cake Site
2:30 pm -
3:30 pm
Garrett Kitchen helpers
3:30 pm -
4:00 pm
coffee break
4:00 pm -
5:00 pm
Nate Auth System (ACL)

Come and join us!

If the above sounds interesting to you, we are looking forward to see you in Raleigh:

Sign up for the Raleigh workshop on September 6-7

Questions

If you have any questions, please feel free to email us at workshops@debuggable.com.

-- Felix Geisendörfer aka the_undefined

 

Debuggable Scraps on GitHub

Posted on 29/7/08 by Felix Geisendörfer

Hey folks,

Tim and I finally found a good way to share all the code we have been publishing on this blog in a central place as well as making it easy for people to contribute own changes to it. The solution is GitHub, a truly great application when it comes to hosting git repositories in a collaborative manner.

How is this better than a svn project? Well, first of all the distributed nature of git makes it very easy for people to 'fork' any given project, making their own changes to it and then asking the maintainer of the original project to 'merge' their changes. Another very neat thing is a feature by Github itself that allows to display the contents of documentation files directly in the repository browser.

So here is the link to the Debuggable Scraps Repository.

At this point we've only added the Google Analytics API / data source as well as a jQuery plugin called Expandable that we wrote today and that will be demonstrated in an upcoming post. But over the next 2-3 days we'll try to add all missing projects as well as a bunch of other previously unreleased snippets.

Hope some of you guys like the idea and will help by forking the project and contributing some changes : ).

-- Felix Geisendörfer aka the_undefined

PS: The name 'debuggable scraps' was chosen because all of the code in the repository is too trivial to make for an own repository yet may sometimes need some debugging ; ).

 

If you have a web company in DC, I'm doing you a huge favor

Posted on 14/7/08 by Nate Abele

Hey y'all, big news:

My good friend Jesse Kochis is moving from Boston down to DC this October, and is looking for a company (or companies, if you can talk him into it) to work with. Aside from being a great guy, Jesse is far and away one of the most talented and capable developers I've ever had the pleasure of working with. On top of being an adept developer and architect, his front-end skills are virtually unparalleled.

In fact, Jesse and I met about the same time I was working on some new features that would come to form the basis for Cake 1.2. He and his team of developers has been writing apps on top of Cake 1.2 since the very beginning, and his work has been influential in several aspects of 1.2's design.

I've never endorsed anybody like this before, but as far as I'm concerned, this isn't so much an endorsement as it is a favor to any Washington DC-based internet companies. If you can afford to hire someone in a senior position, you'd be crazy not to; and if you can't afford it, you need to interview him, and then re-examine your budget.

 

Programming Psychology II: Private methods

Posted on 7/7/08 by Felix Geisendörfer

Hey folks,

my previous posts about code that is easy to write vs code that is easy to read and why XHTML is a joke spawned a fair amount of criticism. This time I am afraid very few people are going to agree with me at all:

Private / protected methods and properties are one of the most stupid concepts of OOP.

This is a thought I first shared at CakeFest Orlando this year, but could not explain properly at the time.

Here is the typical excuse for why any language should implement such a terrible concept:

class BankAccount{
  private $balance = 0.00;

  public function set($newBalance) {
    if (!is_numeric($newBalance)) {
      $this->error = 'And I will strike down upon thee with great vengeance
              and furious anger those who would attempt to poison and
              destroy my bank account. [...]'
;
      return false;
    }
    $this->balance = $newBalance;
    return true;
  }
 
  public function get() {
    return $this->balance;
  }
 
  public function save() {
    // Great, I can now always blindly trust the value of $this->balance!
    return file_put_contents('balance', $this->balance);
  }
}

Awesome! Now nobody can mess with the balance of this account class and you don't even have to communicate the rules for using it to other programmers!

If you think you can manage programmers or enforce API policies with a few keywords of your programming language ... think again!

If somebody does not understand why he is not supposed to modify the balance property - he will find ways around it. And it won't be pretty, trust me. He'll directly write his values to the database and reload the object. He'll simply change your source code without warning. He'll extend the class and overwrite the set method.

Programmers will do just about anything to restore power you are trying to take away from them.

Now you might think: "But it really makes sense to use a private property here, nobody would ever want to work around this?". Well maybe. And thats a big maybe. Predicting what other programmers will want to do with your code is like playing number guessing with uuids.

So why not try to make the other programmers your allies? Show them what you are trying to accomplish in a semantic fashion:

class BankAccount{
  public $balance = 0.00;

  public function validates() {
    if (!is_numeric($this->balance)) {
      $this->error = 'And I will strike down upon thee with great vengeance
              and furious anger those who would attempt to poison and
              destroy my bank account. [...]'
;
      return false;
    }
    return true;
  }

  public function save() {
    // Lets just make sure that nothing has gone wrong before saving
    if (!$this->validates()) {
      return false;
    }
    return file_put_contents('balance', $this->balance);
  }
}

This approach has many advantages:

  • It gets rid of the useless overhead from setter / getter functions.
  • It communicates that you need to validate certain things before saving a record.
  • It embraces open architectures and others can work with it right away.
  • It makes your class more flexible since you can temporarily feed it with invalid values.
  • It exposes a new useful method.

Is that it?

Despite the fact that I think that private / protected are a stupid idea to begin with, I have an even bigger issue with them:

The concept of private / protected properties and methods seems to be the most popular recipe for producing crappy code.

I think it's safe to say that all of us were following at least one of the patterns listed below at one point:

  • Not sure where this code goes - I'll put it in a private method for now.
  • Oh, I will refactor this later, so I temporarely put it in a private method.
  • This is just a helper function, no need to clutter the API with it.
  • I am sure no other class will need to access this property ... lets make it private.

Now ask yourself how many times those decisions have lead to code you are proud of? I cannot recall a single occasion in my work as a programmer where using private / protected has helped me to write better code. In fact, these days I even judge other peoples code by it:

When I see more than 2-3 private / protected methods in a class I know the code I'm looking at is in poor shape.

This may sound like a big simplification, but it holds true. I've almost never seen people use private / protected in the proper (yet stupid) way they are supposed to be used.

The psychology behind this is simple. Give people a way to ignore things they don't want to deal with and they will. Private / protected were not meant for that purpose, but unfortunately they encourage the worst habits in us programmers and I therefor highly recommend against using them.

-- Felix Geisendörfer aka the_undefined

PS: Even if you "just" use the CakePHP convention of prefixing functions with one or two underscores to indicate scope visibility you'll end up writing messy code.

 
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34