Need help getting started with unit testing extensions

Author Message

Eirik Alfstad Johansen

Friday 13 November 2009 11:47:14 am

Hi,

During the summer conference this year there was some discussion regarding unit testing which I found very interesting. I have, however, not been able to find enough information about this since then to get started unit testing our extensions. Here's what I've found so far:

1. A page at eZPedia (http://ezpedia.org/en/ez/testing_ez_publish_test_system) giving a brief introduction to how unit tests are implemented in eZ Publish, but with very little information about extensions in particular.

2. A few extensions which implement unit testing like ezfind. However, all the extensions I've come across so far seem to focus mostly on DB tests, and hence derive from the ezpDatabaseTestCase class as apposed to the ezpTestCase class mentioned at eZPedia.

Would it be possible for someone with experience in writing unit tests for extensions to give a brief introduction into how it's done (like Paul B. og Paul F.)? Or perhaps an article is in order?

Thanks in advance !

Sincerely,

Eirik Alfstad Johansen
http://www.netmaking.no/

Bertrand Dunogier

Friday 13 November 2009 3:40:31 pm

It's actually not very hard, you should be rock & rolling in no time.

One good starting extension is ezselection2. Paul (F) has written a good amount of unit tests for it already: http://svn.ez.no/svn/extensions/ezselection2/.

Now, most of what you'll find on ezpedia is right. The most important parts:

  • do not forget to generate the tests autoloads: ./bin/php/ezpgenerateautoloads.php -s
  • you can filter out your tests by adding extension/extension_name at the end of the command line

Globally, start by writing tests for the "helper" classes your extension(s) probably rely on. The convention would be to mirror your extension's class hierarchy in the tests folder:

extension/myext/datatypes/foo/footype.php
extension/myext/tests/datatypes/foo/footype_test.php
extension/myext/tests/datatypes/foo/footype_regression.php

It can be a bit tedious for large extensions, but well, standards are standards ;)

About the tests themselves, it is very likely they will inherit ezpDatabaseTestCase. Don't forget to inherit ezpDatabaseTestSuite. You can also add custom SQL scripts that will be automatically imported at suite startup by using the $sqlFiles array property in your class. Be very careful about the database driver specification... and don't forget to add an extra blank at the end of the SQL files. It's very easy to waste time on that.

If one of your tests doesn't use the database at all (network access class, file parsing, http stuff), just inherit ezpTestCase instead. $sqlFiles is one of the major differences, aside with the fixture.

You can also check the kernel tests. Most extensions will obey the same structure as kernel features, and how they can be implemented won't be that different.

Bertrand Dunogier
eZ Systems Engineering, Lyon
http://twitter.com/bdunogier
http://gplus.to/BertrandDunogier

Gaetano Giunta

Saturday 14 November 2009 7:43:20 am

Thanks for the tips Bertrand (even though it sounds too deeply technical for those who have not started with them yet).

One question I have is: what is the recommended way to introduce specific ini settings in the unit tests?

Eg. test this when ini x.y.z is set to A, then test it when it is set to B.

Principal Consultant International Business
Member of the Community Project Board

Bertrand Dunogier

Saturday 14 November 2009 12:25:22 pm

"

One question I have is: what is the recommended way to introduce specific ini settings in the unit tests?

Eg. test this when ini x.y.z is set to A, then test it when it is set to B.

"

Does anyone know how you can split the quote ? e.g. answer between lines... I haven't found a way on chrome or firefox yet.

I have the perfect answer to the INI question ! :)
Check this file: http://pubsvn.ez.no/nextgen/trunk/tests/toolkit/ezpinihelper.php

It's a helper class I've used to test some features where I needed forced values for INI settings (setting up the cluster environnement for instance). It is very simple:

// Set DatabaseSettings.DatabaseName to 'myotherdb' in site.ini
ezpINIHelper::setINISetting( 'site.ini', 'DatabaseSettings', 'DatabaseName', 'myotherdb' );

// bla bla bla, test stuff with DB

// Restore the previous settings
ezpINIHelper::restoreINISettings()

Bertrand Dunogier
eZ Systems Engineering, Lyon
http://twitter.com/bdunogier
http://gplus.to/BertrandDunogier

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.

eZ debug

Timing: Jan 18 2025 02:02:43
Script start
Timing: Jan 18 2025 02:02:43
Module start 'layout'
Timing: Jan 18 2025 02:02:43
Module start 'content'
Timing: Jan 18 2025 02:02:44
Module end 'content'
Timing: Jan 18 2025 02:02:44
Script end

Main resources:

Total runtime0.7717 sec
Peak memory usage4,096.0000 KB
Database Queries63

Timing points:

CheckpointStart (sec)Duration (sec)Memory at start (KB)Memory used (KB)
Script start 0.00000.0072 589.2891152.6563
Module start 'layout' 0.00720.0024 741.945339.4922
Module start 'content' 0.00960.7605 781.4375616.5547
Module end 'content' 0.77010.0016 1,397.992216.1250
Script end 0.7717  1,414.1172 

Time accumulators:

 Accumulator Duration (sec) Duration (%) Count Average (sec)
Ini load
Load cache0.00350.4509160.0002
Check MTime0.00140.1752160.0001
Mysql Total
Database connection0.00090.121810.0009
Mysqli_queries0.710092.0058630.0113
Looping result0.00060.0819610.0000
Template Total0.744396.420.3721
Template load0.00210.269320.0010
Template processing0.742296.177220.3711
Template load and register function0.00010.013110.0001
states
state_id_array0.00040.056610.0004
state_identifier_array0.00150.195620.0008
Override
Cache load0.00180.2302400.0000
Sytem overhead
Fetch class attribute can translate value0.00060.083730.0002
Fetch class attribute name0.00130.166970.0002
XML
Image XML parsing0.00140.187430.0005
class_abstraction
Instantiating content class attribute0.00000.001980.0000
General
dbfile0.00210.2714280.0001
String conversion0.00000.000840.0000
Note: percentages do not add up to 100% because some accumulators overlap

Templates used to render the page:

UsageRequested templateTemplateTemplate loadedEditOverride
1node/view/full.tplfull/forum_topic.tplextension/sevenx/design/simple/override/templates/full/forum_topic.tplEdit templateOverride template
4content/datatype/view/ezimage.tpl<No override>extension/sevenx/design/simple/templates/content/datatype/view/ezimage.tplEdit templateOverride template
4content/datatype/view/ezxmltext.tpl<No override>extension/community_design/design/suncana/templates/content/datatype/view/ezxmltext.tplEdit templateOverride template
9content/datatype/view/ezxmltags/paragraph.tpl<No override>extension/ezwebin/design/ezwebin/templates/content/datatype/view/ezxmltags/paragraph.tplEdit templateOverride template
1content/datatype/view/ezxmltags/link.tpl<No override>design/standard/templates/content/datatype/view/ezxmltags/link.tplEdit templateOverride template
1content/datatype/view/ezxmltags/li.tpl<No override>design/standard/templates/content/datatype/view/ezxmltags/li.tplEdit templateOverride template
1content/datatype/view/ezxmltags/ul.tpl<No override>design/standard/templates/content/datatype/view/ezxmltags/ul.tplEdit templateOverride template
2content/datatype/view/ezxmltags/literal.tpl<No override>extension/community/design/standard/templates/content/datatype/view/ezxmltags/literal.tplEdit templateOverride template
1content/datatype/view/ezxmltags/quote.tpldatatype/ezxmltext/quote.tplextension/ezwebin/design/ezwebin/override/templates/datatype/ezxmltext/quote.tplEdit templateOverride template
1content/datatype/view/ezxmltags/line.tpl<No override>design/standard/templates/content/datatype/view/ezxmltags/line.tplEdit templateOverride template
1print_pagelayout.tpl<No override>extension/community/design/community/templates/print_pagelayout.tplEdit templateOverride template
 Number of times templates used: 26
 Number of unique templates used: 11

Time used to render debug report: 0.0001 secs