Category Archives: Strategy

Test the Test

Just a recommendation and a “best practise” coming from my current daily work on Test First Development. I wanted to introduce a new ValueObject, thus I started to write the Unit Test for it. It looked like this in my IDE (Eclipse; pseudo code used):

Bildschirmfoto vom 2014-12-17 21:43:52This is the source code:

class MyTest {
    public function checkDefaultValues() {
        $myValueObject = $this->createValueObject();
        $this->assertInstanceOf(Tx_Extbase_DomainObject_AbstractValueObject, $myValueObject, 'ValueObject does not implement AbstractValueObject');
        $this->assertABC(/*...*/);
    }

    /**
     * @test
     */
    public function checkSetAndGetPropertyA() {
        // ...
    }

    /**
     * @test
     */
    public function checkSetAndGetPropertyB() {
        // ...
    }
}

After i wrote the test like quoted above I tended to implement the ValueObject without any prior test run, because I was just very sure about what’s to be done and it was quite abvious that the test will fail very fast without any testable class in place. Fortunately I controled my feelings and had a break. I just started the test and did the implementation step by step based on the upcoming error messages. I was astonished! Why? Read on…

The very first test run failed, because no ValueObject class was available at all. That’s no rocket sience. So I did the first very, very basic implementation of “ValueObject”. It looked like this:

class ValueObject {
}

Simple. Important: I did not extend the ValueObject from the base class Tx_Extbase_DomainObject_AbstractValueObject on purpose to find out, if the “assertInstanceOf” of my test (highlighted in line #4 of the test case implementation) would fire an assertion failure. Surprise: It didn’t!

Why? Because “checkDefaultValues” was never executed at all. And that is, because I forgot to add the “@test” annotation for this test. I wasn’t aware of this bug, because the annotations were minimised in my IDE view (have a look at the screenshot on top of this post).

If I would have implemented the ValueObject in the usual way using a copy&paste of another value object or by adding the extension in the very first implementation, I wouldn’t have seen this flaw in the test.

Outcome: “Test First Development” means also: “Implementation driven by test defects.” This will test your tests and will let you have better tests and better software. The only thing on your side: You have to be disciplined… Right after this experience I won’t do it differently any more. 😀

Check in

Before we proceed to the repository, let’s just recap about version control and combine this information with the Test First Approach. There is a general principle, a de-facto or best practice rule, how to deal with the version control system. It simply says: “Check in, if all tests are successful.”

If you think this over there are some consequences coming out of this general statement:

  1. Don’t check in, if / as long tests fail.
  2. Try to check in as soon as possible. To achieve this, don’t reduce the tests, but improve the application.
  3. If you write new tests, you might even check the empty test class in into the version control system. Especially if you work in a team, you might use this approach to share just the information that this test (and it’s folder structure) is present and who is working on it.
  4. (or better 3b) I recommend (esp. in teams) to use the check-in-as-soon-as-possible-approach while adding single test cases to a test file (and of course adding the corresponding functionality to the application).

Complete the Domain Model

Now it’s simple to go on and add test cases for the remaining domain model entities. And afterwards just make it “all green” again by implementing the entity objects. But… I remember a recommendation in the book I read. It says: Use a lightweight controller and put most of the business functionality into the model. So if you just think of simple getters and setters, step back, wait a little moment and rethink. If there is any additional functionality inside the domain model, anything that defines / organizes / changes the internal structure of the entities, add a test and implement it afterwards.

This was just “finger exercising” to get familiar with the basic folder structure and the Test First Development. Now it’s getting a little bit more complicated. I start to implement the test for the entity’s repository and I have to consider that the actual domain model does not fit to the database table naming: The table names and the column names are different because of the former table definition, I don’t want to change right now. That is the point where the decision took place to write this blog, because now we extend the basic information given by the book. We have to combine a specific extension setting for the database mappings with the unit tests. Here is where the challenges actually start.

Finger Exercise #2 – Unit Tests of the Domain Model

Let’s start implementing the first unit tests. Of course I do this in the first place, because I want to start with the tests first and do the actual implementation of the domain model’s functionality later on – driven by these tests.

But… This is a refactoring project and it looks like I am setting up a domain model from scratch. Is this refactoring?! Well, yes and no. The older (quick and dirty) implementation didn’t use any domain model classes at all. Everything was included in just one pi1-PHP file and the domain model was just a set of arrays containing data of database tables. Thus there is no specific part of the original software we can use as a reference. The only thing we can use as a reference is the database and it’s structure. If we find a domain model that meets the database model and if it reads and writes any data correctly from/to the database, the refactoring is successful. To achieve this, two steps are necessary. First implement a simple getter-setter-entity-classes domain model. Secondly add the corresponding repository to do the database communication.

Nevertheless the Test First Development forces us to do the tests for the domain model without the repository first. When these tests and the domain model implementation are set up and tested successfully, we will start to do the same for the repository as well. Unfortunately we have to wait for the refactoring result until this is done. But on the other side of the medal we can be sure that the domain model is working even before we start implementing the repository.

Thinking different: Cleaning up the domain model

You already know about the domain model. If you did – like I did – your development some years ago without thinking of the domain model in detail, you may find out now that your old database model does not fit to the actual domain model of your current destination. In case of my extension csevents I found out that the domain model e.g. contains a set of Appointments represented by various instances of the class “Appointment”. Some years ago when I set up the database, I called it “tx_csevents_apptointments”, where at least the last “s” is wrong, because it stores Appointment-objects and not Appointments-objects. Of course I don’t want to do the mistake twice, thus I will call it “Appointment” in my model as well as in my implementation and I have to map the “Appointment” model to the (wrongly named) database “tx_csevents_appointments”. This does not meet the extbase framework’s requirements, but it is a 1:1 refactoring for the old (DB-)model. We can think of and implement the database merge later on.

Why not doing it now, but knowing that we are doing something that has to be remodeled later on? – Just to keep it as small and simple as possible. First think of the PHP implementation and the extbase framework. Think of a database change including merge scripts for existing databases and documentation for users/admins later on. Divide et impera! It’s complex enough to do the PHP, testing and extbase topics for the beginning.

Ok, now we have to setup four test classes for the four domain model classes “Appointment”, “Description”, “Price” and “Category”. They are located at [extkey]/Tests/Unit/Domain/Model. The file “AppointmentTest.php” contains the class “Tx_Csevents_Tests_Unit_Domain_Model_AppointmentTest”. This will change in Typo3 6.2 when namespaces are introduced. For now and here with Typo3 4.5 namespaces are not available, thus we need to fall back to the Very_Long_Classname_Containing_The_Full_Path_Of_The_Namespace. (And accordingly the same for all four domain model objects.)

The Test FilesIn the next step let’s have a look at the first unit test implementation.

Refacoring – Avoiding the Frustration

The most annoying and frustrating thing on refactoring is that you loose track midway in the process. Right after you start refactoring you usually face a tremendously growing bunch of open topics and you struggle with a lot of things to keep in mind and/or to predict. How shall I do the basic structure? How do I split up the responsibilities within my software? How do I put this all together in the aftermath? And the most fearful question: Will it all work like before? Or even more pessimistic: How long will it take to test it, to find and to fix all defects? How will I be sure that everything fits together in the end?

Unfortunately in much too much cases this leads to a dead end where you capitulate heavily frustrated, roll back all development and a) never touch it again or b) start from scratch with the same problems.

How to avoid this frustrating situation

You can avoid the dead-end-situation by answering the questions above in advance to your refactoring. Instead of starting as fast as possible with chopping down your running sourcecode with an axe, step back for a second and invest one to two hours in planning your approach. This will safe a lot of time and frustration in the actual development process. So let’s start and answer some of the questions above:

  1. “How to keep track of all open topics?”
    Technical support #1: Use a task tracker that is integrated into your IDE. For Eclipse the best solution at hand is MyLyn with a task tracker like Bugzilla or Jira. In order to relieve your mind from tracking all open topics, you must add every single idea, every question and every open topic to this task tracker.
    Technical support #2: Use a version control system. Here I use Subversion. This will give you all opportunities to roll back, work on different paths / branches of the software, find out about the changes already done etc.
    Strategy and Mindset: There are lots of references on the Web how to set up the technical support noted above properly, but the most important success factor is that you use it as frequently as possible adding all little sparks and hints rushing through your mind to the task tracker and adding every single successful development to the version control. Whenever there is a new idea, question or open topic while you are actually developing part of your software, put it into the task tracker to safe it for the future and to get rid of it while you are developing. Whenever there is some development done (even an intermediate work-around), check it in into your version control system to fix it for the future and to get rid of checked-out-and-changed files while you are working on the next topic.
    Thus “divide et impera” is very important. Chop your big project down in small ideas and small steps. You don’t know how? Read on.
  2. “How to structure my approach even if I’m not sure about all details?”
    Make use of a framework (in this case: extbase). It provides you a structure and it can also provide you a route to setup the structure and develop your software step by step. Make yourself familiar with the basic principles of this framework. This means that you have to do some research work on the Web or in some books. While you are reading this, you are actually doing exactly what I am talking about right now. This blog is exactly the result of a process like this: Research, get ideas, structure your ideas, find out about the challenges in the real world of development. Start with simple questions / tasks where you know the background quite well (e.g. the domain model) and proceed to the complex topics (error handling on the GUI) at the end. Be sure: The project’s complexity will increase with every step you take, but your experience will increase as well to solve this. Don’t let the project’s complexity rule your way of working, do it the other way around. Use the tools and small steps noted above to keep control of the project and of the complexity.
  3. “How do I know, if everything will fit together / if I am on the right way?”
    It is not a good idea to refactor for weeks, do a big-bang deployment, start testing and getting frustrated by a not-at-all-working software. Refactoring actually means small steps in each of these development steps: Small changes, small deployments, small tests leading to small and easy-to-find defects. This leads to a very large amount of very small and easy (even trivial) tests. Doing a lot of trivial tests a lot of times is not a very satisfying job, so let’s make the computer do this annoying job. This means: Automatic unit testing. And to do it right, you shall (I strongly recommend this!!!) do it in the first place. I.e. “Test Driven Development” or “Test First Approach”. Start by writing the unit test and do the actual functionality inside the software afterwards. Yes, I know that developers want to develop functionality and don’t want to develop stupid tests telling them stupidly that the stupid implementation wasn’t done right now. And a developer doesn’t want to write a test for a stupid getter or setter method at all. That’s annoying stuff for a well trained developer’s mind. But take it the other way around: Whenever you run all these simple tests, they provide you the very good feeling that everything works like expected. This is the most important feeling while you are refactoring a software. This lets you be sure that you are on the right track. And be sure as well: Tests will be more complex and meaningful while you are progressing your refactoring job. The better the test, the more stable your software, the less annoying search for the root cause of complex defects. You will see the effect in the later posts while I am using the Test-First-Approach on my project as well. And please keep in mind: If you start with the test first, you also start with thinking of your expectation / requirements before you start developing the software. That keeps things simple: You will define what you want to achieve by developing a test and afterwards you will just invest as much effort es really necessary in implementing the solution to meet these requirements. That’s efficient and it reduces the complexity of your project, because you don’t implement functionalities that you might use in the future, but that you are not sure about in the moment. There is no test for it, thus you don’t implement it.

Now you’ve got it all together to do a successful refactoring: Small steps handled by a task tracker under full version control, a framework to structure your software and your mind and a Test Driven Development to reduce complexity and to be sure about the correct result. Got it!

“Check in on successful test”

I strongly recommend to “check in” into the version control system only, if all tests are “green” (i.e. successful). In a lot of software projects this is a basic rule for all developers in order to ensure, that at least everything is consistently running in the test environment. This is a very basic requirement, I totally support, even if you are – like me – working on the project completely alone.

This requirement works in both directions:

  • Don’t check in as long as at least one test is failing.
  • Check in as soon as all tests are successful.

There is a prerequisite to do a successful collaboration using these rules: Do proper tests! (See topic 3 above.) This reduces the risk of unusable software tremendously. It will result in a) a lot of check-ins b) small changes within each check-in. And this is good, because it reduces complexity and supports your (and your team’s) understanding of each iteration. “Keep it small and simple” is the basic rule to avoid frustration. 😉

To automatically “build” my extension, I use Ant to do this job for me, because it’s a boring every-time-the-same-steps-to-do job, that a technical automation can do better, faster and more reliable than me. In this case it’s a clean-up/delete-and-copy job. Here is the build.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project name="csevents" default="deployFromDev" basedir=".">
    <description>
        Buildfile to deploy the development version of the Typo3
        extension csevents to the local testing system.
    </description>
    <property name="ExtensionName" value="csevents"/>
    <property name="SourceDirectory" location="${basedir}/${ExtensionName}"/>
    <property name="TargetDirectory" location="${basedir}/../.sandbox/${ExtensionName}"/>

    <target name="deployFromDev" depends="clean">
        <copy todir="${TargetDirectory}">
            <fileset dir="${SourceDirectory}"/>
        </copy>
    </target>

    <target name="clean" description="Clean up the local testing directory">
        <delete dir="${TargetDirectory}"/>
    </target>
</project>

Lines 7-9 just define all properties, i.e. folders and files to handle.

In line 11 you find the copy-job which calls “clean” first. “clean” is located in line 17 simply deleting the complete target directory.

The only thing you have to consider: The developer has to have write-access to the ${TargetDirectory}’s parent directory in order to delete and re-create (copy) the target directory. If you use a ‘.sandbox’ directory (or something similar) in your on ‘home’ or ‘workspace’ directory (like I described in “I am lazy (The Server Architecture)“), this is obviously done out of the box.

If you want to learn more about how to add this to the Eclipse IDE and make it run as comfortable as possible, please refer to the next post auto-ant-ing.

I am lazy (The Server Architecture)

This is about my server setup and the way how the IDE, test environment and version control (Subversion) work together. Image first, explanation afterwards…

ServerArchitectureLet’s have a look at the connections:

  1. The webserver Apache links the URL of my localhost to the ‘cms’ directory. (Actually it is “http://localhost/cms/” in my case, because I use some other stuff on the root level.
  2. The ‘cms’ subdirectory of my local web presence is a soft link to a dummy installation of Typo3 in the same directory. The link depends on the Typo3 version I just use. Thus I can switch from e.g. 4.5.32 (dotted line) to 4.5.37 (solid line) just by redefining the soft link.
  3. The Typo3 dummy installation contains a ‘typo3_src’ soft link to the Typo3 core system, which is located at ‘/opt/typo3_src_4.5.xx’ (where ‘xx’ is ’32’ or ’37’ in this case). This is recommended by the Typo3 installation guide in order to split the Typo3 installation into the local system for one web presence and the core. It’s not 100% necessary in this configuration, but it is more flexible, if I want to use the core for some other sites on this server as well.
  4. All 4.5.xx versions of Typo3 use the same DB-connection to a local MySQL database. As long as the DB structure does not change between patches, this is valid. Thus the content of the web site stays the same, no matter if I use the 4.5.32 or 4.5.37 link at 2.
  5. No matter if I use the 4.5.32 or 4.5.37 installation, I just want to make sure that my developed extension is exactly the same in both installations. And in order to update the extension with the latest developed version as easy as possible, I want to have full access rights (esp. write) to the extension directory. Thus I use a central ‘.sandbox’ directory inside my Eclipse workspace, which holds the last deployment. Both Typo3 installations link the typo3conf/ext/csevents directory to this sandbox directory. Now all access rights inside the Typo3 installation stay on wwwrun level and I have full access on the sandbox directory, which is located inside my home directory (underneath ‘workspace’). Eclipse allows to generate all subdirectories despite of ‘.metadata’, thus this is a valid directory.
  6. Inside the Eclipse workspace there is a project directory ‘csevents’ holding the complete Eclipse project with all meta data, additional project data and resources. The ‘.sandbox’ directory stores the deployed version of the extension only. Thus there is no meta data, no additional files etc. The ‘deployment’ is a simple copy job performed by an Ant script. We will have a look at this ant script in the next post. This structure and the deployment process separate the development version from the current testing version, thus I can test on the last deployed version while I’m already changing the code in the development environment.
  7. Finally there is a Subversion connection managed by Eclipse to store all project changes directly to the version control system. My policy is: Check in exactly when (and only when) all tests are successful.

Consequences:

  1. Testing and development can be done separately. The Typo3 extension directory (i.e. the ‘.sandbox’) gets the source code only. There won’t be any SVN files, Eclipse project files or any other administrative development stuff. Thus this is a copy of the “real world”. Good.
  2. It’s well prepared to use it for “Deployment from SVN” later on, if I need to switch back to an older version of the extension in the Typo3 environment, but don’t want to change my current development environment on Eclipse. This would be a direct copy from Subversion to the ‘.sandbox’ directory bypassing Eclipse’s workspace development directory. Very Good.
  3. I can use multiple Typo3 versions for testing (in this case 4.5.32 and 4.5.37). I can access them directly (‘http://localhost/dummy-4.5.32/’) or the current one simply by using the ‘http://localhost/cms/’ shortcut.
  4. I don’t have to build up the content for each installation separatly, because all installations use the same DB connection (as long as table structures are not changed).

Step 6 – the “deployment” from the Eclipse workspace to the sandbox – is the most important one, because it’s used most frequently while developing / testing. Thus it is very important to make this step reliable, fast and easy to use. Because it’s just a lightweight “build” process, let’s use the one-and-only-build-tool-for-Eclipse. That is ant. Yep, I added a very simple ant build script to the project. The only thing it does, is to copy all relevant files from my Eclipse workspace to the ‘.sandbox’ folder. Because this is now the default build script, I can just use Eclipse’ build hotkey (Ctrl+B) to copy all files to the test environment. Simple, fast, easy to remember, efficient. Good! (And I use this instead of a ‘bash cp’, because I am lazy!)

You could ask: Is it the correct way, just to copy the files into the Typo3 extension folder? Isn’t it better to uninstall and re-install the complete extension inside Typo3 ExtManager? The answer is: Yes and no.
If you do severe changes to your extension (adding DB tables, columns etc.), it’s always recommended to use the official extension installation process via the Typo3 backend. I’m sure, somebody can build an ant script for this as well, but I haven’t done this ’til now, because there was no reason to do so.
As long as you do just some simple PHP programming inside your source code, a simple copy process is just enough. You don’t even need to reset the Typo3 caches. While you are working on a new feature or on reengineering (like I do here), you spent much more than 90% of your time on writing just PHP code. Therefor this is a very simple and efficient solution.

So please have a look at the next post to find out about the ant script I use to do the PHP “build” process (just by copying files).