CUP™ - Overview

CUP is a disciplined and radical approach to software development. CUP emphasizes teamwork. Managers, customers, and developers are all part of a team dedicated to delivering quality software. CUP implements a simple, yet effective way to enable distributed cooperative development. CUP emphasizes iterative development. Iterative development adds agility to the development process.

The process is described in detail below. The reader should use the above diagram as a visual aid while reviewing the detailed process.

Release Planning

A Market Requirements document identifies the overall product positioning and high-level roadmap of the product over several releases. The first step in the process is to come up with a release plan based on the feature set that needs to be rolled out. It is important for technical people to make the technical decisions and business people to make the business decisions.

A release-planning process is used to create a release plan, which lays out the overall project. The release plan is then used to create iteration plans for each individual CUP cycle.

The essence of the release-planning process is for the team to estimate each high level requirement in terms of ideal programming weeks. An ideal week is how long you imagine it would take to implement that requirement if you had absolutely nothing else to do: no dependencies and no additional work. Note, however, that testing time must be included in the projection of ideal weeks. The customer then decides which requirements are the most important or have the highest priority.

CUP Cycle Planning

A planning meeting is called at the beginning of each CUP cycle to produce that cycle’s plan of programming tasks. Each cycle is 1 to 4 weeks long. It is important for the developer who accepts a task to also estimate how long it will take to finish. Each CUP cycle should result in measurable progress. Where practical, higher priority tasks and features are implemented first, thus driving the goals established for each cycle. Features should never be partially implemented in a CUP cycle. It is critical that at the end of each CUP cycle, you are left with a unit of code that can be tested, and that builds on all of the previous cycles.

An individual CUP cycle consists of the following phases: Scope & Plan, Design, Develop and Test.

1. Scope & Plan
Before beginning development, the project manager will develop a cycle plan. The number and length of each CUP cycle will depend on the complexity of development occurring during that cycle. On simpler projects, a series of rapid one or two week CUP cycles throughout the entire project may be feasible. For complex projects, the initial cycles may require additional time to provide enough meaningful, measurable functionality.

At the start of each CUP cycle, the cycle’s goals are carefully reviewed. The level of effort to complete the specific collection of features, bug fixes, and other tasks that the team will take up during the cycle are estimated, and all team members must confirm that the tasks can be completed in the allotted time with the allocated resources. Any unfinished tasks from the previous cycle are rolled over into the new cycle. The high level tasks are decomposed and resource assignments are made. Any resource shortfalls are flagged and reviewed with the team and management, and the conflicts are resolved before the cycle begins.

Each task should be estimated as 1, 2, or 3 ideal programming days in duration. Ideal programming days are how long it would take you to complete the task if there were no distractions. Tasks that are shorter than 4 hours can be grouped together and completed in a day. Tasks that are longer than 3 days should be broken down farther. The estimated time should not be less than 1 hour.

2. Design
Simplicity – A simple design always takes less time to finish than a complex one. Keep things as simple as possible as long as possible. The temptation of many engineers is to over-design, building richer functionality into the product earlier than it needs to be implemented.

Object Design - Allow people to break away from the procedural mode of thought and more fully embrace object technology. Object design results in more independence among modules, which allows more individuals to contribute to the design without stepping on each other’s work. The more people who can contribute to the system, the greater the number of good ideas that can be incorporated.

Refactoring - Refactor mercilessly as you go to keep the design simple and to avoid needless clutter and complexity. Keep your code clean and concise so it is easier to understand, modify, and extend. Make sure everything is expressed once and only once. Refactoring throughout the entire project life cycle saves time and increases quality.

3. Coding
Quality - Code must be written according to the agreed standard.

Code the unit test case first - Creating a unit test helps a developer to really consider what needs to be done. Requirements are nailed down firmly by tests.

Integrate often - Code is integrated on a daily basis to ensure compatibility of checked-in code from concurrent development versions. Developers should be integrating and releasing code into the code repository every few hours, whenever possible. Never hold onto changes for more than a day. Continuous integration avoids diverging or fragmented development efforts, where developers are not communicating with each other about what can be re-used, or what could be shared. Everyone needs to work with the latest version. Changes should not be made to obsolete code causing integration headaches. Continuous integration avoids or detects compatibility problems early.

4. Testing
CUP emphasizes testing, but more importantly, effective testing. All code must have unit tests, the importance of which cannot be underestimated. The standard practice is for developers to construct a set of automated unit tests utilizing tools such as JUnit and NUnit. These are developed in support of the identified test cases. In some complex cases, Cactus, HTTPUnit or other tools may be necessary to develop automated unit tests, or in rare cases, manual unit testing may even be necessary.

Use automated functional test software to develop a suite of automated tests that can be used for regression testing for each release. Develop load test scripts and performance test scripts wherever necessary.

Acceptance tests should be automated so they can be run often.

Create tests whenever a bug is found to guard against it coming back.

In larger projects a separate set of staging clusters is set up that closely matches the production configuration. Upon deployment on the staging environment, a set of automated scripts is typically run for regression testing and assurance that the release will not have any unforeseen problems in the target environment.

In addition, an extended set of load and stress tests may be conducted on the staging environment to anticipate the effect of the software under various conditions. As a result, adjustments may be made to the hardware or software configuration.