Web Development

Archive for February 2007

Post Index

Problem

————————————————————————————-

  • Created a root folder named projectserver for storing all the test cases.
  • Created a test case named TestOfConnection to test the connection to the directory server. This test case is placed in a sub-folder called connection within the projectserver folder.
  • Created a test case named TestOfLoginProcess to test the authentication mechanism. This is placed in folder called auth in projectserver folder.

The servers sends responses in XML format. So We have a class that parses these responses into php objects for further usage. The possible responses from server are success xml, failure xml and information xml.

  • Created a test case named TestOfResponseParser to test the response parser class. This is placed in a folder called responseparser within the projectserver folder. This test case consists of various passes that feed xml strings to the parser and assert the return values for expected output.

Now we start testing the actual business logic. I called the class for project management as ProjectMgmt. We need to test the various usage scenarios of this class. Following is the initial set of methods I added to the test case TestOfProjects.

testGetAllProjects

testProjectExists

testAddProject

testUserAssignedToProject

testAssignUsersToProject

testGetAllSubProjects

testSubProjectExists

testAddSubProject

testUserAssignedToSubProject

testAssignUsersToSubProject

While developing these cases I felt that I was moving in bits and pieces and made sure that everything is working fine. But when the variety of cases started to rise I sensed a flaw in this order of test passes. Before I explain what I felt wrong with the above ordering let me put forward the reasoning behind why I laid them out that way.

I actually wanted to test the create project scenario first. I wanted to check that the project is successfully created in the directory server. I created the method testAddProject and saw that it failed because the method to create a project did not exist. Then I create a method to create a project. Now, while coding the logic for this method I realized I need to first check if the project already existed, may be a projectExists method. So I felt I should test the projectExists method first before createProject method. Similarly, due to the limitation of the server to check for a single project I had to get all the projects first to check if a particular project exists or not. So I felt I need to check getAllProjects first before testing projectExists. [well, this could be an absurd approach but this is how I naturally felt to develop]. So this is how I justify the ordering of first three passes above.

While I was pondering over the correctness of this approach I also refactored the project management classes when I was half through the test cases. I immediately saw the benefits. After modifying the code I rerun the tests and saw some of them failing. I fixed them and saw the green signal and proceeded for further test cases.

Now this is why I felt the ordering of the passes was wrong. The test cases always work on dummy information. Here I tested projectExists before createProject because I didn’t want to use projectExists inside createProject without testing it. I manually create a project in the directory server and check that the projectExists function works fine. Then I proceed to createProject method. Suppose I finished all test cases and put the test aside. After somedays may be I will need to rerun the tests. Suppose the dummy information that I manually fed into the directory server to test projectExists has been removed before I rerun the scripts the related test pass will fail. Should it fail in the absense of such information? I feel It shouldn’t because removing manually entered data doesn’t show any flaw in the method body (the unit to test). So I felt, its better to make the entire testcase atomic.

To make the test case atomic means that the test case will leave the external systems like the directory server in the same state as it was before it had begun to run. For this to happen, there shouldn’t be any manual intervension. There is a tradeoff here. To accomplish this atomicity, while coding the createProject method I should have had to put a projectExists method without first testing it. Any better way to do this?

I felt that by ordering the test passes in such a way that Creation methods are tested first, then querying methods, then modifying methods and finally deleting methods we can maintain the directory server in the state that it was before the test was run. The entire test case will use the project that was created by itself and delete it at the end.

How (im)proper is this approach? Any flaws in the approach?

Advertisements
Tags: ,

Problem: [The further postings would be based on this problem description.]

There are Projects, Sub-projects, users who can be assigned to projects and subset of those users can be assigned to sub-projects. I tried developing a solution for this using the test first approach.

Tools: PHP, SimpleTest, LDAP, Server(it talks to the LDAP server and operates over it)

Tags: ,

What a refreshful read that was!! While browsing I stumbled upon this exceptionally simple and pellucid description of Pointers and Memory. We learned these topics in college curriculum. But when I read this topic after a gap of around 3 years I find my self rejuvenated. Being engrossed in web development using a language like PHP that is so easy to use, I really lost touch of the basics of a language like C. While developing professional web applications we work at such an abstracted level that we seldom mull over what’s happening inside. After such a dry span of time reading something like this is really refreshing.

This work covers topics like Pointers, their allocation, deallocation, dereferencing, lexical scoping, local block semantics, shallow/deep copying, bad pointers, call stack, return address, heap memory and memory leaks to name a few.

A short, sweet and straightforward explanation indeed. Hats off to the writer!!

Wait! Wait!. Don’t miss this one

This approach to software development wherein we begin by writing tests is diametrical to the popular notion of the process. Popular view drives us to develop first and test later. TDD or the Test First Approach motivates us to write the tests first, watch them fail, develop only so much as is needed to see the test pass and repeat the cycle until the requirement is fulfilled and you are satisfied with your art. In case you are not satisfied with your art, refactor it and repeat the cycle. This seems to be tedius but only until we start doing it along with an insight on what we are getting out of it.

I’ve never been satisfied with the way I develop in PHP. Especially when a friend of mine, while talking about his experience with TDD, stated emphatically that he feels confident about his code with pre-written tests to prove his point. I never had that confidence. I thrive to craft my application well but there are other grave concerns than crafting the code. What if our assumptions while development change, what if the application environment has changed? How do we make sure that all parts of the system are working properly after the introduction of such changes. Do we manually browse all parts of the sytem to check that? How exhaustive is the manual approach? TDD answers these questions.

TDD enables us to visualize what we want to code. The tests that we develop is a kind of system flow, a flow that can be automatically executed. To ensure that it is exhaustive we should proceed minimally by coding only that much as is required to realize our current vision of the task. The moment we deviate from this minimalistic approach we miss some parts of the system, we start assuming and a little introspection would justify how dangerous our assumptions could be.

While I am learing TDD I hold a client’s (the client code in the application) view of the system. I try to develop test cases by forseeing on how I would be using that piece of code while working on other parts of the application. For e.g. If I am developing a class to parse some custom XML format for the application I would develop tests by first thinking about how I will be using this parser, various scenarios that employ this class to parse the format. My test will also include straight-forward cases to check output for particular set of inputs to an operation.

Proceeding in this way I sometimes feel that I’ve not structured the application correctly, probably I need to move the code to another component for better reusability, may be I can combine some common tasks into an utility class. When I feel so, I implement the changes and rerun the tests and see where it breaks, fix those bugs and move ahead.

The process appears to be slow but in reality if consider we the time we spend on hunting for bugs and resolve them at later stages we will be convinced that the test first approach is infact more productive. In his interview with Bill Venners, Martin Fowler says “There’s an impossible-to-express quality about test-first design that gives you a sense of unhurriedness. You are actually moving very quickly, but there’s an unhurriedness because you are creating little micro-goals for yourself and satisfying them“. He named this process of focusing on single aspect at a time as Monological Thinking.

Tags: