DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

Trending

  • How To Check IP Addresses for Known Threats and Tor Exit Node Servers in Java
  • Auditing Tools for Kubernetes
  • The SPACE Framework for Developer Productivity
  • Logging Best Practices Revisited [Video]
  1. DZone
  2. Coding
  3. Languages
  4. Practical PHP Testing Patterns: Testcase Class Per Class

Practical PHP Testing Patterns: Testcase Class Per Class

Giorgio Sironi user avatar by
Giorgio Sironi
·
Apr. 13, 11 · Interview
Like (0)
Save
Tweet
Share
811 Views

Join the DZone community and get the full member experience.

Join For Free

We have many, many tests in our suites. Each of them is a single method, starting with the 'test' prefix. But where do we put them? In several Testcase Classes.

There are several alternatives for choosing how to name the Testcase Classes and how many should be created. These patterns can be used in different parts of your suite, and today we will see the most natural one: Testcase Class per Class.

"When" is the right question

According to this pattern, you should create a Testcase Class for each class in the production code that you want to test. The tests in this class will exercise the production code class, as much as possible by maintaining an object in isolation, and inserting Test Double where necessary.

This pattern requires a clear correspondence between tests and classes: thus it is "adapt" for unit tests and less for functional and integration one. For end-to-end tests or acceptance tests written in the domain language, the simmetry is often lost.

For example, when you're testing a model class, it's likely that you can find test scenarios that works well on an object of the class in isolation. When you're testing the user interface instead, you do not have a strict correspondence between test scenarios and production classes (although a loose correspondence can be made with controllers in MVC frameworks).

Implementation

Usually the naming convention followed for this pattern on a medium/large scale is to replicate the hierarchical structure of the production code:
library/
    My/
        CoolClass.php
tests/
    My/
        CoolClassTest.php

CoolClassTest contains in this case a My_CoolClassTest (or My\CoolClassTest if you use namespaces) class extending PHPUnit_Framework_TestCase or a subclass of it.

This simple convention aids you in mapping from one test class to the related production one, and vice versa; even when thousands of classes are involved the mapping remain straightforwards, ans we can say it is O(1). Zend Framework 1 for example mostly uses this pattern and this convention.

If you have always used this pattern, you probably think that this is the norm. It is, but there are alternatives which trades off the simmetry of code and tests in order to build more cohesive tests (for example when a Testcase Class grows too much, it can be broken down in smaller classes which do not corresponde anymore to different production classes.)

Example

In this series, we presented mostly examples as unit tests, since they are the simplest to setup and transport to your computer for running. As so, most of the various pieces of code follows the convention of Testcase Class per Class.

Thus the sample code of today is more related to the structure of the tests than to their content. The folder contains two parallel trees of production code classes and test cases. For each class:

<?php
class MyClass
{
}

you have a Testcase similarly named:

<?php
// in reality this would be done via autoloading and bootstrap file
require_once __DIR__ . '/../classes/MyClass.php';

class MyClassTest extends PHPUnit_Framework_TestCase
{
    public function testCanInstanceAnObjectOfTheClassUnderTest()
    {
        $object = new MyClass;
        $this->assertTrue($object instanceof MyClass);
    }
}

And if the class is under a hierarchy:

<?php
class Component_OtherClass
{
}

the Testcase follows the same hierarchy in order to be found easily:

<?php
// in reality this would be done via autoloading and bootstrap file
require_once __DIR__ . '/../../classes/Component/OtherClass.php';

class Component_OtherClassTest extends PHPUnit_Framework_TestCase
{
    public function testCanInstanceAnObjectOfTheClassUnderTest()
    {
        $object = new Component_OtherClass;
        $this->assertTrue($object instanceof Component_OtherClass);
    }
}

You can take a look at the Github repository to see the folder structure.

unit test PHP

Opinions expressed by DZone contributors are their own.

Trending

  • How To Check IP Addresses for Known Threats and Tor Exit Node Servers in Java
  • Auditing Tools for Kubernetes
  • The SPACE Framework for Developer Productivity
  • Logging Best Practices Revisited [Video]

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: