7 Strategies for Unit Testing DAOs and other Database Code

I don't care what all the tutorials say, unit testing in the real world is tough. Well, let me rephrase that. Creating a unit test is easy. Creating a repeatably-passing unit test is not.

The problem is, just about all enterprise applications are dependent on an external database, and while a database itself isn't anathema to unit testing, the data inside it is. The reason is that, unavoidably, unit tests of an enterprise application must refer to specific data in order to test functionality, and this specific data is susceptible to change. What typically ends up happening is that earnest developers create unit tests that work at time t, and then at t+1 the underlying data has changed and subsequently a seemingly random assortment of unit tests fail - the ones that depended on the exact data from time t. Ouch. The inevitable fall-out is that developers must then either (a) investigate the failures and fix the unit tests, (b) delete the failing tests, or (c) live with something less than 100% passing unit tests. Not a good choice in the lot.

In my experiences and research, I've found about 7 different strategies for handling data in unit tests, and each one has different costs and constraints associated.

1) Mocks and Stubs

2) Development Database

3) Unit Test Database

4) Local Database

5) In-memory Database

6) Data-independent Tests

7) Non-durable Tests

And, yes, all but solution 1 would technically be considered integration tests, not unit tests. I will try to name them appropriately in this article, but if I slip up, you know what I mean.

Mock and Stubs

Most TDD purists would probably argue for the importance of completely isolating the *unit* to be tested (or "system under test"), and to achieve this, any class that the unit depends on must be mocked, or stubbed, or otherwise faked. For unit testing DAOs, which of course depend on the database, this means that the database itself must be mocked/stubbed. Doing this has its advantages, namely performance and isolation, as mentioned, but comes at a significant cost to complexity and maintainability - writing mock JDBC layers and fake data to be processed by DAOs is not a trivial task.

Even if you did go ahead and create this testing infrastructure, the real meat of the DAO (the SQL, HQL, or mapping) still wouldn't even be exercised by the test, since it's hitting the fake layer and not the real database. If a unit test of a DAO won't tell you that your SQL/HQL isn't valid, then, really, what good is it?

Essentially, mocks and stubs are a tried and true solution for unit testing in general, but with regards to a database dependence,they don't seem to be a workable alternative.

Development Database

This is the path of least resistence. Rather than spend hours mocking out database layers and creating fake data, why not just hit an actual database, and exercise the real queries, mapping files, etc? And further, since the development database (i.e. the central database the team uses for testing code in-development) already exists and has realistic data, why not just use that? Good plan, right? Well, for creating unit test that work *now*, yes, this is a great, low-cost solution. For creating repeatable unit tests, not-so-much.

The problem, of course, is that development databases are used by everyone, and so data is very volatile (proportional to the number of developers/users and rate of code change). You could attempt to control the volatility by using data population/clean-up scripts (e.g. DbUnit) that are run on the setUp() and tearDown() methods of your unit tests, but this solution too has cracks, as any client of the database manipulating data at the same time you run your test could easily muck things up. For instance, what if Joe in the next cube deletes the customer your unit test expects? Essentially, if a test fails, it could be because something is legitimately broken, or it could just mean that some user of the database unknowningly deleted the row your unit test was depending on. You just don't know.

Because of the lack of isolation in a development database, this is not a viable solution for creating repeatable, data-dependent unit tests.

Unit Test Database

A separate, central database created and managed specifically for the purpose of running unit tests would provide a degree of isolation more for running unit tests than a development database, and so therefore increases the chances that tests would run successfully at future points in time. Again, by using data population/clean-up scripts prior to and after running unit tests, the data conditions that the tests depend on could be assured. Further, by rolling back transactions at the completion of a test and thereby not modifying the data, you can feel confident that your unit tests are not stepping on the toes of other unit tests running at the same time.

There are problems with this solution, however. First, if unit tests have data that is specifically inserted and deleted for *each* test (i.e. in the setUp and tearDown methods of the test) rather than one central set of data for all tests, then multiple unit tests run at the same time could cause conflicts. For instance, if test1 tests that a "findBy" method returns 5 records, but test 2 inserts a new record in its setUp() that gets picked up by the "findBy", then test 1 would fail. The solution, of course, is to use one central data load script for all unit tests, which typically isn't too onerous.

The second problem is that in most enterprise environments, the database isn't owned by the application developers. Creating and maintaining a separate database just for unit testing means convincing (pleading with, cajoling, etc.) the DBAs...and in my experience, unless there's a very strong advocate of unit testing in the management ranks, it just ain't gonna happen.

The bottom line is that this is a good middle-of-the road solution - it has the advantage of being easy to manage (from the application developer's perspective), but still can suffer from data volatility problems which can reduce the repeatability of tests.

Local Database

Maintaining a separate database instance on each developer's local machine is the most optimal solution in terms of ensuring data durability, but the most costly in terms of investment in infrastructure/configuration and the most unrealistic in typical enterprise environments. On the up-side, with a local database, a developer can be extremely confident that the data that his unit test depends on will not change. Further, if one data-population script is checked in to source control and used by all developers, then developers can be sure that data on one developer's machine matches data on another - and one step further, a unit test that runs on one machine should run on another. Most excellent.

What's necessary from the application developers perspective are a few things. First, of course, each developer needs a instance of the database on their machine - which of course entails that each developer take some time to set up and adminster the database, but also could present some problems with licenses depending on your DBMS. Second, a DDL script that populates the structure of the database and DbUnit or SQL scripts that populate the base data. And third, these scripts need to be plugged in to some Ant targets that execute the creation, population, and removal of the database. These are all very achievable tasks.

Unfortunately, if it would be tough to convince a DBA of the "Unit Test Database" option, it'll be down-right impossible to convince him of generating and maintaining a DDL for creating the structure of your local database for the purpose of unit testing. Again, in my experience, DBAs are fairly protective of "their turf", and won't jump at the chance to change their processes and approaches to suit your "touchy-feely", agile practices.

Additionally, having each developer maintain their own instance of the database can provoke problems of data synchronicity and general maintenance chaos. For example, when your unit CustomerDAOTest runs but mine does not, I'm forced to wonder, "do you have different data than me?", "did I configure my database correctly?", "do I need to check out the latest DDL or DbUnit scripts and re-build my database"?

All things being equal, if the DBAs are receptive and developers are competent enough to handle the additional complexity, this is the most optimal approach, in my opinion.

In-Memory Database

If you have the fortune of working with an OR mapping framework, using an in-memory database is a very attractive option. Unfortunately, in many enterprise environments, SQL, stored procedures, triggers, and the like aren't going anywhere.

Data Independent Tests

If you find yourself in an environment where none of the approaches above work, but you still dream of a day with repeatable unit tests, then a very sub-optimal solution is to connect to the development database but merely lower the bar for your unit tests. For instance, instead of asserting that a "findBy" method returns exactly 5 records, just assert that the query does not bomb. Though this does very little to verify whether the actual functionality of the DAO or class still works, it at least informs that the mapping is correct - i.e. the database hasn't changed underneath your feet. In some environments, this alone provides enough value to write unit tests.

Again, this severely limits the coverage and power of the test, it still allows for the ability for unit tests to be assembled into suites, run in a nightly build, and pass with a 100% success rate independent of whether the data has changed. That's something, right?

Non-Durable Tests

In some camps, I imagine it'd be blasphemous to suggest writing unit tests that are non-durable (i.e. may break down-the-road if data changes), but it is an option. Unit tests serve many purposes, one of which is to give confidence that a change (refactoring or enhancement) made to the system has not broken old functionality. To realize this benefit, indeed, it's probably necessary to have an assemblage of unit tests that run with 100% success - run the tests, make the change, run the test, you're done.

There are, however, other, less-widely touted benefits of unit tests, and these benefits can be achieved even without a 100% success rate. Firstly, unit tests allow developers to test isolated pieces of a system without having to go through the interface. Without a unit test, a developer who wants to test a query in a DAO, literally must write the query, the DAO, and then every piece on top of it all the way up to the interface, compile and deploy the application, navigate to the part of the system that executes the query, and finally run the function. Whew. A unit test, checked into souce control, even if it doesn't pass, at least gives a maintenance developer a driver of that piece of code so he can execute it from his IDE. This alone is helpful.

Secondly, unit tests, regardless of whether they pass, can also serve as semi-decent documentation of code - describing what parameters to pass in, how to set up pre-conditions, etc.

This is an extremely unsatisfying solution, but it could be argued that there is some value in it.

Conclusion

From my experiences and research, these seem like the prevalent approaches for unit testing database dependent code. I'm quite sure I'm missing options, or missing specific costs, benefits, or nuances of the options I have described. Let me know what you think!

The Search for a Good UML Tool

Over the past couple weeks, I've dug into a few of the more popular UML tools out there, hoping to find out which to use at either end of the complexity spectrum, the small startup or the big corporation. What I found is that such a quest isn't so straight-forward. There are entirely too many UML tools to choose from, and it's amazing (at least to me) that a little marketplace natural selection hasn't yet weeded out the good from the bad from the ugly. But such is the state of the UML world: chaotic...and as I found out, a bit disappointing. In the end, however, there are some good alternatives, but not surprisingly, one size does not fit all.

My Approach

With so many tools on the market, it's just not possible to look at each one. [1] Instead, you've got to define your requirements up front, and then take a reasonable sample and see if you can find one that satisfices. This was my approach...

Breaking it down, developers essentially need a UML tool for three things: (1) to design something from scratch, (2) to understand some existing piece of code, and (3) to maintain documentation for an existing system or component.



For each of the these "use cases", different features are required from a UML tool. When designing from scratch (use case 1), I need the tool to help me easily create different perspectives of the system, share these diagrams with my colleagues, and perhaps forward engineer these diagrams into source code. When using a UML tool to understand some existing piece of code (use case 2), I need the tool to reverse engineer my code (without sucking the life from my computer), and then let me drill into the model to understand the relationships or structures that are germane to my task. And finally, when I'm maintaining documentation for an existing system or component (use case 3), I would like the UML tool to reflect any changes in the source code from the last time I've opened my model. For example, if I create and save a diagram at time T1, change the underlying source at T2, and then reopen my model at T3, I should see my changes from T2 in my diagram at T3.

By use case, here are the features I'm looking for:

1. design: intuitive interface, UML 2.0 support, export to image, forward engineering
2. understand: reverse engineer, not overly resource intensive, information hiding, dependency illumination
3. maintain: code-to-model synchronization, IDE integration


Most developers, in my experiences, only really need support for use cases 1 and 2 - they create diagrams to help them clarify or communicate design thoughts at the present time, and they capture these thoughts in some formal documentation (on a good day!). However, they typically aren't as concerned with maintaining their models. If something in the code has changed that affects the diagram, they'll just re-create (or re-reverse engineer) the diagram - they don't necessarily need the tool to keep in synch with the underlying code base. For my client, however, this wasn't going to work. They needed the code-to-model synchronization that comes with that 3rd use case. Updating documentation was a priority, and so the barriers needed to be as low as possible to do so.

So going off a few years of UML experience, a little internet research, and some conversations with friends, I narrowed my search to six tools: Poseidon, StarUML, Together for Eclipse, Omondo, Sun Java Studio, and MagicDraw. I put each of these tools through their paces, and here's what I found.

Poseidon

I fell in love with poseidon as soon as I opened it. First of all, there's a free version that is very capable, which is great. The interface seemed very usable, there were a bevy of nice features, and the GUI effects were very cool. But the price you pay, it seems, is performance. Even with a relatively small project (a few hundred classes), it was pretty memory intensive and slow. In the age of instant gratification, waiting a few seconds to drag-and-drop a class on a class diagram is too much. Yes, I'm impatient. Overall though, I got a good feel from poseidon. For a small college-type project, great. Not ready for prime time though, in my opinion.

StarUML

Another free UML tool, and this one was fast. Opening a project, dragging and dropping, rearranging - lightning quick. It even seemed to scale a little better to larger projects. The problem was, at least for me, that the interface was a little perplexing. I think this is because they are using Irrational's, errr....I mean Rational's terms and approach - which if you're not drinking their kool-aid is very counter-intuitive. For example, you can store your diagrams in one of five model types: the Use Case Model, Analysis Model, Design Model, yada-yada. This is just confusing. The graphic components are a bit cumbersome to use as well, and I found myself spending way too much time rearranging boxes and lines. All in all though, there are some nice things about it.

Together for Eclipse

I've used past versions of Together from Borland, and I have to admit, the tool is pretty bad-ass. With this version, they went the extra-mile and integrated with Eclipse, a very laudable effort. The problem is that they don't just give you a plug-in to hook in to your Eclipse, they give you their version of Eclipse instead. What the...? Well, I don't want to have to use two different Eclipses, and I don't want to be locked in to Together's Eclipse, so I guess I'm done here...

Omondo

There are two versions of Omondo available. The first is free, and pretty capable...until you realize that your model is stuck in your Eclipse. There's no image export, or even save available. Obviously this won't work, so I tried their Studio version. Bingo. This tool is very nice. First, it's plugged in to Eclipse, so round-trip engineering is all there (and so simple). The UI is intuitive, and I found some nice features for reverse-engineering (finding dependencies, associations, etc.). All that, and it's fast too. The only downside is that it adds annotations to your source - so for a legacy system where you don't want to be responsible for changing so much existing code, this might not work.

Sun Enterprise Java Studio

Admittedly, I did not dig quite as deep into Sun's product. I guess I'm settled on Eclipse (for good or bad), and I just couldn't see switching between two big-time IDEs. Overall though, and some friends confirmed this, it seems a bit buggy, slow, and confusing (especially the reverse engineering). There are some nice features...and it is free, but it wouldn't be my first pick.

MagicDraw

I found this to be a great all-around tool. It doesn't integrate into Eclipse and it didn't seem to solve the code-to-model synchronization problems from my 3rd use case, but all else was very solid. The UI features were quite helpful. For example, in a class diagram you can click on any class and automatically add to the diagram all related types. Awesome. It's also pretty quick even with a larger project, and not too expensive to boot. I found that MagicDraw recently won a reader's choice award from JDJ, and I can see why.

Summing Up


In the end, every tool that I looked at will handle use cases 1 and 2 - designing from scratch and understanding some existing code. If this is all you need, and your project small and budget tight, poseidon will do the trick. It's free, intuitive, usable, and has some "good-enough" features. If, however, you need that 3rd use case of maintaining your documentation (code-to-model synchronization), then the only two tools of the seven that'll do are Omondo and Together. Of these two, Omondo is superior if only because of the better integration with Eclipse. Finally, don't overlook MagicDraw if you need something more robust than poseidon, but less so than Together or Omondo. The price is reasonable, the tool is fast and very capable.

10 tools for Modern PHP Development

A simple list of tools for modern PHP development. There are alternatives to most of the tools, but I’ll list native PHP tools wherever possible.

1. PHPUnit

PHPUnit is a testing framework belonging to the xUnit family of testing frameworks. Use it to write and run automated tests.

2. Selenium RC

Selenium RC can be used in conjunction with PHPUnit to create and run automated tests within a web browser. It allows tests to be run on several modern browsers and is implemented in Java, making it available to different platforms.

3. PHP CodeSniffer

PHP CodeSniffer is a PHP code tokenizer, that will analyse your code and report errors and warnings based on a set of Coding Standards.

4. Phing

Phing is a project build tool and is a PHP port of the popular Java program ant. Phing can be used to automate builds, database migration, deployment and configuration of code.

5. Xdebug

Xdebug is a multi-purpose tool, providing remote debugging, stack traces, function traces, profiling and code coverage analysis. Debug clients are available in many PHP IDEs and even plugins so you can debug from everybody’s favourite editor vim.

6. PHPDocumentor

PHPDocumentor is an automated documentation tool, that allows you to write specifically formatted comments in your code, that can be brought together to created API documentation.

7. phpUnderControl

phpUnderControl is a patch for the popular Continuous Integration tool, CruiseControl. Together with the previous six tools, phpUnderControl gives you a great overview of the current state of your application/codebase.

8. Zend Framework

Frameworks facilitate the development of software, by allowing developers to focus on the business requirements of the software, rather than the repetitive and tedious elements of development, such as caching. There are plenty of frameworks to choose from, but I particularly like the Zend Framework.

9. Subversion

Subversion is a revision control system that has superceded CVS. If you’re writing software of any kind, you shoud be using version control software.

10. Jira

So I could have named one of many, but this is the one I’ve liked the most recently. Jira is a bug/issue tracking software package and can also help with project management in terms of goals and roadmaps. Most issue trackers link to version control repositories, such as Subversion. Only downside to Jira is that it costs for non open source projects.

I’m pleased to say that with a little bit of pushing and persuasion by myself, we are currently using all of these technologies with the exception of Jira, we have a bespoke issue tracker.

What do you think to the list? Anything I have missed? Any alternatives you prefer?

10 tips for working with PureMVC

1.Think in (Pure)MVC

How do I start using PureMVC? Short answer: Just think in (Pure)MVC! As its named says, PureMVC based on the classic Model-View-Controller design meta-pattern. Using the Facade-pattern you don’t instantiate the core actors directly, but every member of PureMVC has its own and clear defined role:
- Proxies = Model
- Mediator and its ViewComponents = View
- Commands = Controller

2.Create an API for View Components

A View Component might be a standard UI component (e.g. DataGrid) or a custom component (e.g. a world within a game) or whatever. Don’t use its public methods directly. In order to change its state or behavior create an API.

One of the advantage of PureMVC is to be neutral to the technologies being used. An example: I’ve built a “pure” Flash application based on PureMVC without using the Flex Framework. The same app will be ported to an AIR application for using AIR’s great File system API. The View Components have to be changed using the Flex Framework, but not the Mediators or any other actors of PureMVC.

3.Use one Mediator for multiple View Components

To coordinate more than one View Component closely, use one Mediator only. In other words: Not all Views need a Mediator. For example: Assume a ApplicationControlBar containing a TextInput , and a Button or something else. Then create just one Mediator for the ApplicationControlBar called ApplicationControlBarMediator and refer to the missing components casted as a second, third, etc. View Component.

4.Let’s Events bubble up

What happens if you don’t want to use multiple View Components within a Mediator? In order to handle user interactions with multiple View Components let’s bubble Events from the nested children of a View Component up.

For example: Clicking any Button within a View Component will fired up a custom Event which the Mediator is listen to. So the Mediator don’t have to know about the existing Button or about any other child of its View Component, just about the custom Event bubbled up.

5.Communicate using Notifications as often as possible

Notifications are the “Events” of PureMVC. For communicating between the three tiers Model, View and Controller use Notifications for the following scenarios as often as possible:
(communication from -> to)
- Mediator -> Proxy (via mapped Commands)
- Proxy -> Mediator
- Proxy -> Command
- Commands -> Mediator

Even if it’s possible to retrieve a Proxy from a Mediator, don’t change the Proxy from a Mediator directly rather than sending a Notification using a mapped Command. It’s a bad practice to change a Proxy (Model) from a Mediator (View) directly without using a Command (Controller).

6.Use Commands / MacroCommands as often as possible

Commands are doing the job at the Controller side: Retrieving and interacting Proxies, communicating with Mediators or executing other Commands. Even if a Command used only once or it has only two lines of code, use it as often as possible. To execute a Command once again anywhere or anytime within your application, you have to send just a Notification. In the future it’s easy to enlarge the Command with more complex actions. And - that’s very important - you always know, who the actor for changing the Proxy (Model) is.

Question: Have you had to execute more than one Command in a particular order? Use MacroCommands to execute multiple SubCommands (which means “simple” Commands) sequentially.

7.Use Remote Proxy to send and receive server-side data

To send and receive data between the application tier use Proxies called “Remote Proxies”. That’s not a special kind of a PureMVC Proxy, just a location based on a Proxy to organize the server calls such as HTTPServices, RemoteObjects or whatever.

For example: To call a server-side RemoteObject to login a user create Proxy called LoginProxy. The LoginProxy does all the job to communicate with the server-side, which means sending and receiving data. Whenever you’ll change the server-side implementation for the LoginProcess, you’ll have to change one location within your application only - the LoginProxy.

8.Remove unused Mediators

In some cases you don’t use a Mediator and its View Components anymore. Then remove the Mediator using facade.removeMediator(MyMediator.NAME); in conjunction with a self created destroy() method to remove the ViewComponent including all listeners, timer, references, etc. for a successful garbage collection.

9.The Power of VO’s (Value Objects)

The place to store data within the Model are the Proxies - that’s right. The View Components have no need to know the Facade and the rest of the PureMVC application - that’s right, too. This means that the View Component has no access to the Model data directly.

To avoid this issue store within the View Component a reference to the data using Value Objects (VO’s). The VO’s are not a core actor of PureMVC and in conjunction with the Data Binding feature of Flex are a powerful way to react changes in the Model data without breaking rules.

10.Courseware available

Cliff Hall has done an awesome job: You’ll find not only excellent documentations about the “Framework Overview“, “Best Practices” and a “Conceptual Diagram“, also a very, very, very helpful Courseware. Check it out!

“Top 19″ best practices for J2EE

The list of the best of the best Java EE practices can be found at IBM web site:

1. Always use MVC.
2. Don’t reinvent the wheel.
3. Apply automated unit tests and test harnesses at every layer.
4. Develop to the specifications, not the application server.
5. Plan for using Java EE security from Day One.
6. Build what you know.
7. Always use session facades whenever you use EJB components.
8. Use stateless session beans instead of stateful session beans.
9. Use container-managed transactions.
10. Prefer JSPs as your first choice of presentation technology.
11. When using HttpSessions, store only as much state as you need for the current business transaction and no more.
12. Take advantage of application server features that do not require your code to be modified.
13. Play nice within existing environments.
14. Embrace the qualities of service provided by the application server environment.
15. Embrace Java EE, don’t fake it.
16. Plan for version updates.
17. At all points of interest in your code, log your program state using a standard logging framework.
18. Always clean up after yourself.
19. Follow rigorous procedures for development and testing.

Study tips

In my opinion, there is no set timeframe like months or days to prepare for Java Certification. It depends entirely on how you want to approach the whole subject. If you are well versed with Java language it might take you little effort to prepare for the Java Certification or else if you are new to Java the efforts can double. The objective for passing the certification is totally different then objective for learning Java language. There are certain Java topics which are not covered in the certification objectives like Swing, EJB, Servlets, JDBC just to name few. When I started learning Java language I realized that it is kind of cumulative language, which means the new concepts are added to and build upon previous concepts. It is very important that the early material be mastered thoroughly. So.... do some initial homework, see where you stand in terms of your Java expertise and approach this issue accordingly.

Tips:
(1) Before you think of appearing for the certification, make sure that you are aware of Java language concepts, syntax and object oriented concepts. Lay special emphasis on the certification objectives. This will give you some directions as to what Sun(TM) is expecting from you for getting certified.

(2) Do some initial investment and buy a good Java book. I bought Ivar Hortan's Beginning Java 2.

Carefully read over the sections and look carefully at the sample problems. (One nice aspect of this book is that the author uses real life scenarios to explain Java concepts) .If you go to a school which teach Java or have joined a Java course, then decide if you benefit more by reading before or after the instructor covers the material. If you know which skill areas are the weakest, you can then work to improve yourself in those areas, and you'll have a far better chance to reach your full potential for higher scores.

(3) There is simply no excuse for this.. write lots of code. As you start developing code, you won't necessarily get it right the first time, but you can improve as you find more about the underlying details. You will realize the importance of this when you go in the examination hall and see the code intensive questions in the new SCJP format. Writing and executing code will fine tune your theoretical concepts and get rid of any ambiguities. Questions in the certification often test you on 'compile time error' and 'run time error' in the code and you are expected to know the difference between the two types of errors, which will not come to you unless and until you have made an conscious effort to write and compile the code.


(4)
Start making notes on piece of paper. Every time you find a concept which relates to the certification objective, jot it down. Put together all the notes pertaining to a topic in same folder in one place, so that you can refer to them at the appropriate time.


(5)
Identify your scoring topics. These are some of the topics where you stand a good chance of scoring 95% - 100%. Concentrate more on these.

(6) Once you are confident that your level of comfort with Java language is fairly good, start taking the mock exams. You may have to do the exams test for more than once. Try to get score over 90% in this mock exams. The questions that are in the real exam can be a lot trickier than those you solve in mock exams. One area which can be tricky is declarations and access control, Operators and assignments. In case of multiple choice questions, you can go thru the possible answers real quick and eliminate the wrong ones which seem obvious. This is the most difficult exercise, but once you crack it (by practice) you can get the answer fairly quickly.

It is very very important that you continually review and practice the java concepts you already know and the new concept you acquire in the process of learning. Best way to do so is visit a Java forums on the web. Try to answer the questions raised by the fellow programmers. I have listed some forums here on my website.

(7) Week before the exam collect all your notes which you have filed in Step (4) and start breaking them into one liners, just the gist. This way you have only the important points and concepts in hand. Use this material one final time one day before the exam and keep it in safe place.

(8) Take a good night sleep before the exam day and appear with fresh mind.

(9) When you approach a question try to understand why has the question come in the examination, what is that 'they' want to test by posing this question. In the real exam the questions are worded clearly and without any ambiguity (no tricky questions) , so spend some time reading them.

(10) Haste will only makes waste!!. Rushing thru the questions and trying to complete the test will not improve your test score.

(11) One very counter productive approach is to time your questions. You will end up spending more time looking at your watch and less time concentrating on the questions. You may want to get to the "easier" questions first and then revisit the remaining ones.

(12) Never get frustrated or discouraged by unfamiliar or "hard" questions which come can come in the beginning. Just keep concentrating and working on the remaining ones.

(13) Not failure but low aim is a crime....

My Web Application Development Process

The First Step - Analysis and Planning

The planning stage is where you meet with the client and get t know exactly what they need. If they have an existing system in place — either a paper-based system, existing web-based or desktop system, have then run through their typical daily tasks and show you exactly what they do, and why they do it. The point here is not to start making recommendations but to get really inside their current system and get a complete understanding of how the system helps them. Almost assume you’re being trained for their job and have to do each of the tasks that they’re doing and why they’re doing it so you can start thinking about the system from their perspective.
You might be thinking that a lot of clients don’t currently have anything in place, but I’ve had clients to wrote down all their service calls on paper and then wrote them on a big white board before I worked with them. That was their system, and that’s the first place we started. The goal of any web-based application is to improve employee work flow, and subsequently increase productivity. Otherwise, it’s hard to make a business case to the client to spend thousands of dollars on your custom software.

Once you have a clear understanding of their business and how their existing system works you can start planning and making recommendations for improvements to the system. Start brainstorming with the client and ask them what immediately comes to their mind in an effort to start improving their current work flow. Here is where the documentation starts as well. Start off with a functional specification of the system that clearly outlines, in a high-level description, what the proposed system will do and how it will improve efficiencies and productivity. This does a couple things: it helps define the exact scope of the project at the start to help reduce any scope creep and change requests throughout the project, and also helps you define the project to include in your contract or service agreement.
A Note on Documentation:You might be thinking to yourself, that it sounds like a lot of documentation, and a lot to do up front. However, I’ve found that it is quite rare for a client to truly understand themselves what they want in a system when it is being developed, and the more discussion, brainstorming, and documentation you put in place it helps develop further discussion on the system, and finalize on a complete and accurate system spec. The more details you include in your up front documentation, the less questions and changes you’ll have down the road. For large complex systems, a lack of documentation and planning can mean stalled projects, delays in delivery (and payment), and unhappy clients due to confusion about the project.

Interface Design

Yes, the interface is the second step. Part of the planning should include how the client wants the interface to work. This is arguably the most important aspect of the development project, since the interface will effectively determine whether the application is a success or not. Keeping the users of the system happy is the single most powerful tool in turning a web application client into a long-term business relationship. If the users are constantly complaining to their boss about how difficult it is to use, then you’re going to have more minor fixes, and headaches than you’ll want.

They won’t have a clue about the technical underpinnings of the system like how the database is setup or structured, or whether you’ve coded it well or not. Although database and coding is equally important to the interface on your end, the clients really could care less.

During the interface design, you need to design every single screen from the login, to the user’s dashboard, reports, and forms. Each and every module should be clearly defined including mock error messages and notices. The reason for doing this separately before the actual programming is that you won’t be in a programming state of mind while designing the system. If you do all your mock ups in Photoshop or Fireworks you’re not thinking about how you’ll code the HTML or structure the database - you’re solely thinking about how the system works. If you do leave these elements out, while you’re programming it, you won’t give them the required time and attention and the entire application will suffer.

This also gives your user a way of seeing what the application will look like and give you very important feedback. You don’t want to have to re-work the interface once you’ve already coded it. That can be a huge hassle, and changing it at this step is simple.

As I’m drawing up mockups, I like to label them with their proposed URL structure. Rather than trying to set this up in the development stage, start thinking about it here. Label each of your screens as domain.com/app/module/function ex: domain.com/app/calendar/view and domain.com/app/calendar/edit/434. It doesn’t mean you need to split these functions into different actual web pages - through the use of mod_rewrite you can create some great-looking URLs.

Database Design

Now we can begin the database structure. Look at the proposed screens for the application and start grouping fields, entities, and the data you’ll be storing and create some high-level Entity-Relationship Diagrams or ERDs. Then get more detailed and create a complete database structure including the relationships between each table. I like to reduce to Third Normal Form (3NF), but you can go deeper if you want. You’ll find that this step is quite easy now that you’ve already done the interface design, as well, from doing the interface design, you’ll also have the fields and other data clearly outlined so you won’t have as many surprise changes to the structure of the data. You probably don’t want to show this document to the client as they most likely won’t understand it.

Class and Application Structure

At this point I like to start outlining any classes and data objects I’ll need in the system. Object-oriented programming (OOP) is always the way to go, especially in large, complex web applications since you’ll be maintaining the system for some time as well. The goal is to have as much code reuse as possible, and to come up with a logical set of programming objects to reduce the complexity of programming the system as well as the maintenance.

This doesn’t mean just coming up with standard database connection objects, and other standards libraries, you want to look at objects specific to functions of the application. For example, if the system includes an inventory module, you want to create one or more inventory objects so if you need to use an edit form in multiple places within your application you don’t need to cut and paste code, its a simple function call.

Directory Structure

Now I start planning my directory structure. I like to group my directories in a similar manner as the applications function, and I keep my images, javascripts, css, etc grouped as well. Here’s a sample:
• .htaccess
• /images
• /javascript
• /css
• /conf
• /includes
• /class
• /modules
• /tmp
• /files
o /images
o /documents

I like to have a temp directory for file uploads contained within the web application rather than uploading files to a server’s general temp directory, and I also like to put all uploaded files within the files directory and organize them accordingly witihin. The conf directory holds any configuration files (which will include system options and database connection variables). The modules directory will include folders and the files for each module within the system. Finally, the .htaccess file includes any rewrite rules and server configurations.

Development

Now we can start the development of the site. This consists of converting my mockups to HTML/CSS and getting the templates uploaded, then building the database and finally connecting the HTML templates to the database with code. I always work off my local file server and then do periodic uploads of the system to a web server where the client can play around with it while I’m developing off my own internal server. This way they can look at the system and do some testing while I’m developing. It also keeps them in the loop during the entire development process to ensure that you don’t go off track on the system.

Also, ensure that you have some sort of backup in place for your system while it’s in development. This is critical for the obvious reason that you don’t want to lose it and have to start over, but you’ll often mess something up and want to start over from the beginning of the day or earlier. In fact, setting up some sort of version control system like CVS or Subversion is your best bet, I recommend Subersion.

Quality Assurance and Testing

You’ll be testing while you develop the site, but you want to put aside some time to try and break your system once you have a working BETA of the application. This means entering invalid data, trying to hack into login forms, etc. Have your clients try the same, as they’ll probably think of entirely different methods of using the system since they haven’t been so close to the development of the system like you have.
During the development phase you should also be putting together a test plan to help test the system. This is where you’ll refine it and then run through your test plan and track any bugs as they are found. I like to track bugs in a spreadsheet using Excel or iWork Numbers.

Launch

Finally, launch the application. You’ll want to give your client a notice that there may be some minor tweaks to work out in the first couple weeks or months of using the system. Just have them track any issues and report back to you for fixing. I typically give them a period of 1 or 2 months where I’ll fix any other bugs they find, but after that point any fixes are billable to the client.

Maintenance

Now that the project is initially complete, you’ll want to setup a maintenance agreement with the client to maintain the system. THis means ongoing support and bug-fixes, web hosting for the system, and regular backups.

Web applications can be a lucrative part of your web development business, they have been for me, and I really enjoy the challenge of planning, designing and implementing the systems. As well from a business point of view, they’re a great source of continual revenue, and also a great way to build stable, long-term clients, which are essential to the long-term plans for your business.