WorkHabit Blogs

WORKHABIT LABS

Mock Datasource Testing in Drupal: An Approach

by Aaron Stewart Published: May 22nd, 2007
Tagged:

So one of the biggest things I've run into in drupal-land is that it's virtually impossible to test database interactivity without actually touching the data on a live site. I started kicking around some ideas last night and came up with a half-way solution that may solve at least the first round of headaches with this.

The Criteria

Ideally, I wanted a solution that:

1. does not rely on requests to the database to test a certain component.
2. preserves existing data
3. allows me to test certain conditions based on the way the data should be returned.

In TDD circles this is defined as "testing in isolation."

The components

database.chaindb.inc

This is essentially a datasource that allows one to chain multiple database elements together.. Ideally this is a case of "try this db engine first.. barring that, run the query against this next one."

database.testdb.inc

This is a datasource that returns a result based on a globally set hashtable. In order to be compatible with drupal's existing db_query, it mocks up the db's resultset resource as a stdclass and returns that. In this way, it can be passed around and not break anything that depends on it.

testdrupal.module

This is a custom module that needs to be written that creates and invokes _testdrupal and _testdrupal_init hooks on all modules. In this way we can run multiple tests and in the order that drupal would normally invoke modules. It also makes it easy to determine which modules do not have tests.

The Process

The following should (ideally) remain true:

  • Each module defines its own tests
  • Each module should not depend on functionality available in other modules while in test mode. (since it's not possible to override modules, this may be limited to defining return data using testdb)
  • Each module should not invoke tests for other modules

Taking that a step further:

  • Each module should provide a set of apis for creating mock objects.

code please

hey, this is great stuff. lets get the code in the open and discuss some more. I’m wondering specifically how you mock up an object like a database result object.

Let's definitely talk

Moshe,

Absolutely.

This was just cited as an approach, no code has been written yet, but I'd love to collaborate with you on it if you're interested.

The beauty of this approach is that you don't really have to mock up the result resource. it gets handed as an argument to dbfetcharray, and since we can override that for the mock datasource, it may not actually be needed. The only exception to this is when one has multiple resources active at the same time, but I don't think I've seen that in any of the code I've looked at. Worst case we can give each resource a unique identifier within the current page context and use that as a lookup.

I'll hop on #drupal.. look me up there.

Part of AutoPilot

Moshe:

Important to bear in mind some of what you’re seeing on this blog is the results of us trying to get test driven Drupal working.

If you’re looking for an update, check out the results of Aaron, Boris, Earnest, Adrian and myself’s chat the other day here on Bryght’s wiki.

I’m going to be opening this up to the larger Drupal community and posting the code for public review shortly. Earnest should have a full unit test for core working with 5.1 tonight - he’s on AutoPilot all day today.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • You can use Markdown syntax to format and style the text.

More information about formatting options

Papernote
Papernote