Register Now
Member Count: 240,743 - March 19, 2010  [Get Time]
Login
Dashboard > TopCoder Competitions > ... > How to Compete in Component Development Competitions > Component Development Tutorial
TopCoder Competitions View a printable version of the current page.  
Component Development Tutorial
Added by dzieba , last edited by volodymyrk on Jan 27, 2010  (view change)
Labels: 
(None)

I. Introduction

Developing at TopCoder

TopCoder develops components in several languages, including C#, Java, C++, Ruby, Flex, JavaScript etc. Though the languages may be substantially different, the process is rather similar. This tutorial will cover the development process, from start to finish. Where the process is substantially different, information will be given for each language.

Development Process

The development process, at a high level, is simple. You are tasked to convert a component design, prepared by the designer and reviewed by the Design Review Board, into a functional component. When you have completed your task, your submission will be reviewed by the Development Review Board. If you are the winning developer, you are then tasked to make changes required and recommended by the Review Board. Once complete, your component undergoes a Final Review, and you're done!
(Sometimes when the component is small and/or straightforward to develop, the design phase will be eliminated. In this case, a requirement document is given.)
TopCoder provides considerable documentation about its design and development processes; if you have not already done so, you should peruse the TopCoder Software development document archive (available here). The TopCoder Member Guide, Development Design and Review Scorecard documents should all be of interest to you. The documents will show you what is expected of your submissions.

Required Software

You may write your source code in any environment you wish. However, we rely on certain technologies to build and package our components. Also, we rely on reference libraries common to each language. Exact packages are listed below.
One tool common to all languages here at TopCoder is the TopCoder UML Tool

C#

Tool URL Description
Microsoft .NET Framework v3.5 MSDN SDKs If you're interested to develop in C#, you probably already have this installed. It is available through Windows Update, or through the link at left.
NUnit Homepage NUnit is a framework that will allow you to quickly and concisely test your code. Unit testing is covered in more detail in Section VI.
MSBuild Reference MSBuild is the build system for Microsoft and Visual Studio. You can obtain it for free as part of the .NET redistributable. For more information, use the reference link at left. Build scripts are covered in more detail in Section III.
TC Code Documenter Homepage The Code Documenter is a command-line utility that writes API documentation in a manner similar to JavaDoc for Java and nDoc for C#/.NET 1.0. The target language is C#.
NCover Homepage NCover is a code coverage tool.
     

Java

Tool URL Description
Sun JAVA SE 5.0+ SDK Download Page Java development is normally performed against the latest JDK. You should keep up to date with the latest edition from Sun.
Ant Homepage Ant is a utility that executes custom, extensible build scripts. You will need this tool to compile your project and submit your code to TopCoder. Build scripts are covered in more detail in Section III.
JUnit Homepage JUnit is a framework that will allow you to quickly and concisely test your code. Unit testing is covered in more detail in Section VI.
Sun JAVA EE SDK Download Page Only a few components will require this package. Check the Requirements specification for the project you are interested in before installing this software.
Checkstyle Homepage Checkstyle is a format checker. You should check your source code format with Checkstyle before submission, if possible.
Cobertura
Homepage Cobertura is a Java code coverage analysis tool. You can use it to determine what percentage of your source code is excercised by your unit tests.

Be sure to configure your system environment as required by MSBuild/Ant. Also, note the locations of your xUnit installation; the location may be required later to configure your build script.

Registration

To participate in any development contest, you must first register with TopCoder Software. Registration not only allows you to submit design and development solutions, but also allows you to compete in other TopCoder competitions, including algorithms, conceptualization, specification, architecture, application assembly and testing, and marathon. To register, follow this link.

II. Picking A Project

Picking a project is the first step to a winning development submission. You can quickly find open development contests at this page. From that page, you can see which projects are open, when registration ends and when submissions are due. These dates are very important. You must indicate your interest to develop a solution by the "Registration Ends" date. Your entire solution, complete with tests and documentation, is due by the "Submit by" date.
The payment for each project indicates the prize for first place winner. Second place winner is also awarded by half of the payment. "DR points" indicates the total Digital Run points allocated for this project. For more information about Digital Run, check out this page.

Project Details

Clicking on the name of any project will bring you to the details for that project. Here you will find detailed information about the project, links to documentation for the project, links to the forum of this project, payment information, and a more comprehensive timeline.

Deciding On A Project

After finding a project that interests you, familiarize yourself with the design documentation for the project. The most concise document is the requirements specification. This document will contain information about the various technologies involved in the project (e.g. SSL, LDAP, ODBC). If you are still interested, you can read the component specification, which will be a much more detailed guide to implementing the component. There are other documents available, but these are the most important to determine if a project is right for you.
Before choosing a project, it is very important to ensure you will have enough time to complete the project. Consider your other responsibilities and assignments for the scheduled development period. Also, keep in mind that the component may use some technology you are not familiar with. Do you know how to use database connections in C#? Do you know how java.lang.ref's classes are used? Do you know enough about a certain network protocol to implement a component which requires it? Be sure to review sections 1.2, 1.3 and 2 of the component specification to ensure you are familiar with the technologies employed.

Project Registration

Now that you've found a project you're comfortable with, and you have the time to complete it, you're ready to register! Click on the Register link on the project details page to register for the project.

III. Getting Started - Environment

After registration, you'll have access to the project submission application, as well as a forum for your component.

Project Submit and Review

Project Submit and Review is the central hub for all development and design contests you participate in. You will upload your submission via this application, and you receive your review scores here as well. To begin, go here, and log in. Once logged in, you will see a list of all your open projects, as well as your status.
Click on the name of the project to view the timeline for the project, or to see other more detailed information. At the bottom of this screen, you will have buttons appropriate to the current phase of development. Additionally, there is a button marked "Contact Product Manager". You can use this button at any time to send questions, comments, complaints, or any other information to the Product Manager.

Developer Forum

A link to the development forum for your project is also available from the project detail page. Most communication regarding your project will take place on the forums. Your TopCoder username and password should allow you to view the Developer Forum for your component. If it does not, contact your Product Manager immediately.

Development Distribution

On the development forum, there are four main sections: Design Phase Documents, Design Phase Questions, Development Phase Documents, and Development Phase Questions. You will find the Development Distribution for your component under Development Phase Documents. The Development Distribution should contain all the files and documents necessary to start development on your component.
Java distributions are commonly in jar format, and .NET distributions are commonly in zip format. Both can be extracted with an unzip utility.

Contents

/conf - This directory, if present, will contain configuration files for your component. Sometimes this will include configuration for components your submission will rely on, or sample configuration files written by the designer. If no such files were created during design phase, you may not have this directory in your distribution.
/docs - This directory contains all current documentation for your component. This includes a .tcuml UML design specification, as well as the requirements and component specification. The design documents are covered in more detail in Section IV.
/src - This directory will contain all your source, when you complete your project. In the distribution, normally only a directory skeleton will be created here. Developers are responsible for source file generation, covered in more detail in Section IV.
/test_files - This directory contains all files used by your component during testing. This can include special or extreme configuration files, input and output samples, database schema, and anything else non-compilable your testing needs. The distribution will often contain some sample testing data that the designer has created.

Java

/META-INF - This directory is created by the jar packager, and can be ignored.
/build.xml - This is a default, possibly unconfigured build script. Build scripts are covered in more detail in Section III.
/build-dependencies.xml - This is a build script fragment which contains dependencies definition for this component. This is also covered in more detail in Section III.
/build.version - This is a configuration file containing meta information for this project, including name, version, source directory and package definitions.

C#

/<project name>.sln - This is the Visual Studio solution file contains two projects listed below.
/Component Sources.csproj - This project file defines project containing the main source codes (in the main directory).
/Component Tests.csproj - This project file defines project containing the test source codes (in the tests directory).
/Build.dependencies - This is the dependencies definition project. This will be covered in Section III.
/Build.version - This is a configuration file containing meta information for this project, including name, version, source directory and package definitions.
/README.txt - This fine explains how to setup and build the component.

Setting Up Your Environment

First off, you'll need to decide on a working directory. Appropriate examples include C:\working\, C:\proj\, ~/projects/ , or wherever you are comfortable putting your code. It is recommended to establish a new directory for TopCoder projects, to minimize confusion and reduce the chance of submitting the wrong files when you're ready to submit. For this tutorial, we'll assume your working directory is /proj/tc/.
Once you've found a place to store your project, unzip the distribution. This directory (/proj/tc/project-name) will be referred to as your project directory. For this tutorial, we'll assume your project name is tutorial_gen.
The next step is to configure your build script. Keep in mind that TCS will not be using your build script: don't devote TOO much time here. Make the tweaks below to fix paths and library references. If you're having significant problems, check in with your project manager.

Java Build Script - build.xml

You will need to set up the cobertura directory in this build script.

<property name="cobertura.dir" value="${ext_libdir}/cobertura/1.8"/>

In many cases, this will be all the configuration you will need to do.

Java Build Script - build-dependencies.xml

If you cannot add the JUnit jar to your classpath, you will need to include it in the build dependencies. Change

<property name="junit.jar" value="${ext_libdir}/junit/4.6/junit.jar"/>

to the correct path.
If your project requires additional libraries, you will need to configure your build dependencies to account for these during build and run time. Here is an example of a TopCoder library.

<property name="spell_check.version" value="1.0"/>
<property name="spell_check.jar.name" value="spell_check.jar"/>
<property name="spell_check.path" value="spell_check/${spell_check.version}"/>
<property name="spell_check.jar" value="${tcs_libdir}/${spell_check.path}/${spell_check.jar.name}"/>

This allows for easy configuration of different versions of the library with minimal build editing. You may have noted the reference to:

${tcs_libdir}

This should already be defined at the top of your build script as follows:

<property name="tcs_libdir" value="lib/tcs" />

This configuration would look for the spell check library jar at /proj/tc/tutorial_gen/lib/tcs/spell_check/1.0/spell_check.jar. You can alter your build script as appropriate, by changing the path or file name property above.
You must include any library your component requires to build or run. While it can be useful to rely on your classpath, it is good practice to include all the necessary libraries here.
The TopCoder catalog dependencies can be found here.

Java - topcoder_global.properties

As you may (or may not) have noticed, the build.xml that came with your distribution contains a reference to a file named "../../topcoder_global.properties". Using this file, you can set properties that won't change between projects, such as the path to your 1.3 JRE.
The format is simple (and common to all Java properties files).
propertyname=value
First, create topcoder_global.properties in the directory below your project (if your current project is/proj/tc/tutorial-gen, your properties file will reside in /proj/tc). Now, you can set properties for all your build scripts. For the JRE, you would add:

java_1_3_bootclasspath=C:\Program Files\JavaSoft\JRE\1.3.1_10\lib\rt.jar

You can add comments to the file, as well.

# I need a comment to remember what this means.
java_1_3_bootclasspath=C:\Program Files\JavaSoft\JRE\1.3.1_10\lib\rt.jar

You can also use property expansion.

java_home=C:\Program Files\JavaSoft\JRE\1.3.1_10
java_1_3_bootclasspath=${java_home}\lib\rt.jar

Keep in mind that your topcoder_global.properties reference is at the beginning of your build.xml. This means that properties from the build.xml won't expand in your properties file (they aren't yet defined). Also note that properties set in the topcoder_global.properties will always override properties set in the build.xml. For more information, see the Ant documentation.

C# Build Script

There are some general build targets referred in the two projects (Component Sources and Component Tests). But they are not in the development distribution. You can download it here. After this, extract them out and put the targets files to the parent directory of your project. For example, if your current project is/proj/tc/tutorial-gen, your targets file will reside in /proj/tc.
MSBuild scripts are easy to configure because the project files can be opened by MS Visual Studio directly. Simply open the solution file, and the two projects Add the dependencies to the projects as project reference. And you're all set.
The dependencies can all be added by manually editing the Build.dependencies file.
Find the corresponding section for Sources or Tests project, in the ItemGroup section which contains the dependencies, add those required in your project. For example:
For TCS components,

<Reference Include="LendingTree.EPC.Data, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>lib\LendingTree.EPC.Data.dll</HintPath>
    </Reference>

For third party libraries,

<Reference Include="log4net, Version=1.2.9.0, Culture=neutral, PublicKeyToken=b32731d11ce58905">
      <SpecificVersion>False</SpecificVersion>
      <HintPath>lib\log4net.dll</HintPath>
</Reference>

For .NET system libraries:

<Reference Include="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>

There may be other design files provided by the designer or Project Manager, such as sample configuration file or database definition.

Development Process

As explained in Section I, your part in the development process is to implement the a design which has already been created and reviewed. To this end, you should consider the public API in the design document as canon. You are not allowed to deviate from the public API without approval from the Product Manager and/or the designer. This includes: adding or removing public classes, methods, and interfaces.This is not to say that every design is flawless; quite the opposite. There is almost always room to improve any design. However, disagreements with design decisions are fixed by design revision, not by development. The implementation phase of the development process is not the appropriate time to remedy design issues, unless they are fatal to the project. TopCoder employs a fully reviewed process for all design changes.
If you have any improvements or insights for the next revision of the design, please post them on the forum. If you do happen to run into any problem during development, bring them up, immediately, on the development forum. The earlier any conflicts or issues with the design are noted, the sooner they can be fixed. If appropriate, read up on the design forum posts. It is possible that issues have already been identified and addressed there. Again, if you see anything that hasn't been addressed, please bring it up in the development forum... it can't hurt!
All this being said, you are encouraged to make any possible improvements on the underlying implementation. If you can refactor the behavior of the public classes into a private helper class: go for it! If you can come up with a more efficient data gathering or manipulation algorithm than the one specified by the designer: wonderful! The only part of the design set in stone is the public API and the general behavior of the component from the user's perspective. Basically, you can't change the "what" of your project, but you do have some freedom to improve the "how."

Development Innovation

Different designs allow for different degrees of development-phase innovation. This is partly a matter of the complexity of the design itself, and partly a matter of the designer's approach. It is possible for a design to describe the component so completely that component coding is reduced to a translation of pseudo code from the Component Specification into the appropriate language for the component. It is also possible for the design to be restricted to definition of the public API, leaving the developer to provide all other implementation details. Most designs, however, fall somewhere in the middle.
Implementation of method bodies is always an area in which developers have an opportunity to put their own twist on the development. With some designs it may also be reasonable or even necessary to add private or package-private methods, constructors, or even whole classes that are not specified explicitly in the design documents. If and when you make such additions you should take care to ensure that they are both necessary and appropriate because these parts of the submission are likely to attract extra scrutiny from the Development Review Board. Developer additions (like any other element of the component), should generally have the narrowest possible scope and the most restrictive access that are consistent with their intended usage. Be sure everywhere to use the most appropriate types of objects and primitives for the tasks at hand.

Generating Stubs

The first step in concrete development will be stub generation. Stubs are compilable code skeletons. Where you would normally find a function body, however, there is simply a "stub." The stubs feature the full API of the final component, but none of the logic. The TopCoder UML Tool can generate stubs for you.Keep in mind that the stub code you receive will likely not be compilable. You'll need to ensure that approximations and external references are resolved. For instance, in a .NET component, the designer may have had to create stand in objects for system types. You'll need to delete these.
Another common problem with generated stubs is the association section. Many relationships (such as aggregation and composition) in the UML document will be inappropriately translated to code. You are responsible for ensuring the proper translation of the API documentation (the UML document and the Component Specification) to compilable code.

Project Structure

The source for your project will reside under /src in your project directory. At this point, your project should be arranged similarly to the following (under the /proj/tc/tutorial_gen/ directory in the example case):

Path Description
conf/ Any configuration files necessary to your component.
docs/ All the documentation for your project.
lib/ All your local libraries.
src/ All your source code will be placed here (including test code).
test_files/ All non-compiled files used in testing will be placed here.

Java

The code for your component will be stored in the /src/java/main/ directory. From there, you need to arrange your source according to the package for your project. For instance, if your component was com.topcoder.util.tutorial, your full path to source would be /src/java/main/com/topcoder/util/tutorial/. Below are Java specific paths.

Path Description
lib/tcs/spell_check/1.0/spell_check.jar In this example, a component that the Tutorial Generator relies on. Your component may not depend on any components, or it may depend on many.
src/java/main/ Your component code will reside in this directory.
src/java/main/com/topcoder/util/tutorial/ In this example, this is the appropriate place for stubs. In your project, the path will be different.

C#

The code for your component will be stored in the /src/csharp/main/ directory. From there, you need to arrange your source according to the package for your project. For instance, if your component was TopCoder.Util.Tutorial.dll, your full path to source would be /src/csharp/main/TopCoder/Util/Tutorial/. Below are C# specific paths. Although C# namespaces do not require directory arrangement conformity as Java packages do, it is TopCoder practice to arrange the source files according to namespace.

Path Description
lib/TopCoder.Util.SpellCheck.dll In this example, a component that the Tutorial Generator relies on. Your component may not depend on any components, or it may depend on many.
src/csharp/main/ Your component code will reside in this directory.
src/csharp/main/TopCoder/Util/Tutorial/ In this example, this is the appropriate place for stubs. In your project, the path will be different.

Building Your Project

Once you have generated and cleaned your stubs, you should be able to build your component with the build script. To do so, you simply execute your build tool from the command line, with a target.
Here are the build targets for Ant:

Target Name Description
compile This target will compile your project into a fully functional binary unit (assuming that your code is correct).
compile_tests This target will compile your tests. It depends on a successful compile.
test This target will execute your tests. It depends on a successful compile_tests. After test execution, the results can be found in the /log directory.
coveragereport
This target will execute your tests and generate the coverage report. You can find the results in the log/coverage directory.
clean This target will clean the /build directory, removing all compiled code and intermediate files from the project.
dev_submission This target will create a packaged submission for you to upload via Project Submit and Review, when your project is complete.


Here are the build targets for MSBuild:

Target Name Description
Build This target will compile .cs sources into the /build directory
Test This target (run from Component Tests project) will run test cases and output the nunit results into /log.
NCoverReport This target(run from Component Tests project) will generate test coverage reports for the component's test into /log.
FxCop This target(run from Component Tests project) will generate reports information about the assemblies, such as possible design, localization, performance, and security improvements.
Doc
This target(run from Component Tests project) will generate API documents for the component in a javadoc manner.
Dist This target will generate a binary distribution for deployment, depends on 'Build'.
CleanSolution This target will delete all compiled code in /build and the content of /log directories.

To execute a build target, you simply move into the directory where your build script is (it should be the project root directory), and execute ant <target> or MSBuild <project> <target>. Make sure that you've properly configured Ant/MSBuild to allow execution at the command line, or this step simply won't work!
Example NAnt Build
Example Ant Build
Your component should almost always build cleanly against the stubs. If they do not compile, you probably have an API problem, or a library configuration issue. It is far easier to fix these issues now, before you have written any tests or code, and you should do so if possible.

And You're Off!

At this point in the tutorial, you should be ready to develop your project. Any more specific information on development technique or strategy is beyond the scope of this document. However, for the next few sections, we'll walk you through documentation, unit testing, and common problems during development, common to all projects.

V. Working Towards Your Submission - Documentation

Documentation is critical to a useful, maintainable component. If you document your code as you write it, you probably won't even notice the burden of writing a project's worth of documentation. Your submission will be assessed on the quality of documentation. Furthermore, the better your documentation is, the easier it will be for the Review Board to understand and evaluate your code, and the better your overall score will be.

API Documentation

Auto-generated API documentation from the UML document is intended for your consumption, not for the final product. In Java, the API is documented through javadoc comments, and in C# via XML comments. All classes, interfaces, methods, and variables must be documented. Below are examples of each type:

Java

Many Java IDEs (such as Eclipse or IDEA) will automatically generate API documentation as you type.

/**
* Saves the file to permanent storage, on the path specified by configuration. The path
* must not begin with a backslash, and must not contain any special characters (see component
* specification). If the filename cannot be used, an exception will be thrown.
*
* @param filename The filename to save to. May not be null or empty.
* @throws IllegalArgumentException If filename is null.
* @throws IllegalArgumentException If filename is not valid (zero length, invalid characters, etc).
* @throws IOException If an error is encountered while saving the file.
*/
public void SaveAs(string filename)

For more information on javadoc commenting, please see here.

C#

Visual Studio.NET will create much of your XML documentation for you, as you write your code. Simply type /// before a declaration.

/// <summary>
/// Saves the file to permanent storage, on the path specified by configuration. The path
/// must not begin with a backslash, and must not contain any special characters (see component
/// specification). If the filename cannot be used, an exception will be thrown.
/// </summary>
/// <param name="filename">The filename to save to. May not be null or empty.</param>
/// <exception cref= "ArgumentNullException">If filename is null.</exception>
/// <exception cref="ArgumentException">If filename is not valid
/// (zero length, invalid characters, etc).</exception>
/// <exception cref="IOException">If an error is encountered while saving the file.</exception>
public override void SaveAs(string filename)

Though C# does not have checked throws, it is good practice to note expected exceptions that the function can generate in your API documentation. For more information about XML documentation, see here.

Documentation Content

Explain how the component will behave, invalid input, failure behavior. If the object mutates based on certain operations, make sure this is clear (though List.add(object) is obviously a mutator, List.screenedAccept(object, bool) may not be so obvious [even if it is obvious to you!]). Make sure to document the return value, all thrown exceptions, and all parameters. Additionally, every class and interface in your project should have summary documentation, explaining its general function and place in your component. They (not including exceptions and enumerations) should also have thread safety information.
It's also a good practice to add sample configuration and usage of the components to main classes.
You should not include any personally identifiable information in your submission. Anywhere you would use your TCS handle (for instance, in an @author tag), put TCSDEVELOPER. This helps keep review as impartial and objective as possible. After you win, you'll change your code to include your handle (during Final Fixes).

Documentation Audience

The audience for your API documentation will be the consumers of the component; TopCoder Software's customers. Always keep a professional tone in your API documentation. Write in an active voice. Be as descriptive as possible, and consider that the consumer of the component may not be as familiar with the language, or the component, as you are.
As mentioned above, documentation from the UML source will not be appropriate to the final product. For instance, you might have received the following documentation for the SaveAs function above: Pull the path info from the config file, then append the filename passed in. Attemptsto save the file to that location, throws exception otherwise.
Invalid Input: null, blank, funny characters, non-fs safeValid Input: everything else
Throws: IOException on failure, InvalidArgumentException if it is.
This documentation is certainly descriptive of what the SaveAs function does, but it is more a guideline for you, the developer, than descriptive documentation for the user. You'll want to remove the implementation details, and explain, clearly and concisely, how the function behaves. Also, "funny characters" may be appropriate documentation for internal development, but is not appropriate to go to a customer. You should rewrite the API documentation as you complete each function, with these guidelines in mind.

Inline Documentation

Inline documentations are simple comments which explain code function within code blocks. Documentation here is intended both for possible component consumers, as well as internal TopCoder improvement. As with any programming, the more documentation you add, the easier the code is to maintain. x+; is obviously incrementing x. No documentation necessary. Or is there? loopIndex+ might be more appropriate, or recordCount++, and so on. If the intention of your code is not plainly obvious, perhaps you need some commenting!

Required Documentation

There is no hard and fast rule for correct API or inline documentation, and review here will be highly subjective.
However, there are some basic requirements.

  • Every file must contain a TopCoder copyright notice.
  • All public API elements MUST be commented fully (parameters, return types, exceptions). NOTE: This includes Unit Tests.
  • Any overly complex or large block of code should contain some inline commenting to explain purpose and function.
  • Documentation must be professional in tone and quality.

Keep in mind the guidelines in this section, and you should score well on your documentation!

VI. Working Towards Your Submission - Unit Tests

Every component, big or small, requires a set of tests. These tests are meant to probe the component for correct behavior when given proper input, as well as correct failure when given improper input. Our style of unit testing originates from Extreme Programming. You don't necessarily need to program in this style, but for more information on the thought and methodology of unit testing, see here or here.
In Extreme Programming, you write tests before you write code. Again, this is not required, but it can be very useful. Your API is largely immutable, so you should be able to write tests against the API, regardless of their success. Use this fact to your advantage, and test often. As you fill in the stubs, more tests will pass.

What Are Unit Tests?

Unit tests are programmatic tests for the correct functionality of a piece of software, at the finest granularity possible (i.e. tests for each unit of functionality.) This normally means tests of each individual non-private method and constructor of each class. Tests should verify correct operation across the spectrum of legal state and inputs, including extreme values, and also should verify correct failure behavior for every testable failure scenario.

Test Scope

Unit tests can be as extensive as you like. In some cases, your tests may include more code than the unit you are testing!
For every public function in your component, you must have a corresponding test. You should test accuracy and failure (valid and invalid input). The wider range of input and output you test, the more likely you are to expose bugs. It is very difficult to test the full range of input (sometimes impossible in large input spaces). However, the closer you can approximate the full range of input, the more robust your code will be.
In addition to these small, atomic tests, you should always create tests that probe the expected function of your component, from start to finish.

Creating Your Tests

The first thing you'll need to do is create a directory for your tests. It'll be under your src/ tree. Each language is a bit different for testing purposes.

Unit Testing Tips

It can be very tempting to simply aggregate all of your unit tests into one function. However, this greatly reduces the utility of your tests. In our example above, we could easily combine all three test functions into a single function, testSaveAs(). Instead of having three tests, we now only have one. If any of the three behaviors are broken, all tests will fail. In larger scale testing, this composite testing methodology can lead to very confusing failure conditions, and it can become difficult to debug your testing code. The smaller and more atomic your tests become, the more obvious the failure point and probable cause generally are.

  • ALWAYS implement a tested version of the demonstration from the component specification.
  • ALWAYS provide a meaningful message in assert and fail calls.
  • ALWAYS document your test code as well as you document your component code.
  • Break up your tests into discrete TestCase classes. If one TestCase becomes unmanageable, don't hesitate to break it into two or more classes.
  • Break up your tests within those classes into the smallest functions possible; this way, it is clear which areas of the component are failing. You can then use the number of tests passing and failing as a completion metric, as well.
  • Reduce code duplication and increase robustness with setUp() and tearDown().
  • Test every public function for as much valid and invalid input as time allows.
  • Test expected component processes: loading, processing data, and saving data, for instance.
  • Don't forget to clean up your environment! Unit tests should leave the system in the same state they found it in; there should be no persistent changes. This is checked during development review.
  • Test classes are normal classes in every respect, except that they have special significance to the testing framework. These classes can inherit from a class intermediate between themselves and the final test. They may contain methods other than test methods. They may have state.
  • Because they are in the same package or namespace as the component classes they test, the unit tests can access package-private and protected classes and their members.
  • Interfaces cannot be tested directly, but methods that accept interface arguments can be presented with alternative implementations. This technique has great potential for verifying that the component does the expected things with and to its interface-typed fields and method arguments, and that it reacts correctly to exceptions thrown by methods invoked on such arguments.
  • All the configuration files and other resources used should be put into the test_files directory.
  • In some cases, the dependencies are not available yet while the project is being developed. You need to write mock classes. Also, you're allowed to use open source mock utilities like JMock or EasyMock. But please make sure with the Project Manager before using it.
  • Never hardcode the database connection information in the source code. Please make sure the database connections are configured in a single file. This will make the testing and building processes easier and more flexible. And this applies to other kinds of configurations (like network configurations) too.

VII. Working Towards Your Submission - Problems

During the course of development, you may run into any number of problems. You may need a component from the catalog. There may be some flaw in the design that blocks development. You may have questions about the designer's intent, or some technology employed by your component. Have no fear, you're not alone!
If you find any confusion or ambiguity in the design, bring it up on the forums for your component (available from Project Submit & Review). It's possible that you've found some case or situation that the designer may not have thought of. It may be that you're misreading the component, or overlooking something. In any case, problems specific to the component itself should be addressed on the component forum.
On the other hand, if you have problems writing your code, or if you don't understand a required technology, or bugs in that regard, you should probably go to TopCoder's Round Tables, and not the development forums. The TopCoder Round Tables are available at here. The General, or Component Competition Forums are appropriate places to start looking for help. The Round Tables are frequented by many of the highly experienced TopCoder members, as well as TopCoder Software staff, who will always try to help as best they can.
If you ever have a problem that blocks you from working on your project, email the Project Manager immediately. This includes things such as missing or corrupt files, access or application problems, and major design issues. You can email your Project Manager from the Project Submit & Review Details page for your component. If you can't access Project Submit & Review, email service@topcoder.com" rel="nofollow"linktype="raw" linktext="service@topcoder.com|mailto:service@topcoder.com">service@topcoder.com">service@topcoder.com, and indicate which project you're registered to, and the nature of your problem.
The proper method of communication is NOT a readme file. If you need to make any significant deviation from the design, you need to get in touch with the designer and PM.

VIII. Submission!

The hard work is over, and you've got 150 successful unit tests. You're ready to submit your solution!
First, you should review your code. Make sure that your submission meets the review guidelines (Section IX) as fully as possible. Finding small issues now will save you points later in the review process. Make sure that your directory structure is appropriate as above.
Secondly, make sure your code compiles.
Finally, run the dev_submission build target. This will build a compressed archive of your files. Make sure to verify that all the files you've written are in the archive, and add any missing files as needed. Your submission should include a successful log from your unit tests, all the files in the conf/ tree, and all the files and directories you need in test_files/. If you have time, you can extract your dev submission to another directory and ensure that it builds cleanly.
Once you're satisfied with your submission archive, you can upload it through Project Submit & Review!

Making your Submission Shine

In order to win development competitions it is necessary to make your submission outshine your competition.This can be quite a trick for very simple, highly specified components, and should be of considerable concern even for more complex or more loosely specified components. There are many ways to put that shine on your submission, but here are some suggestions:

  • Write clean, clear, efficient code. Even though there is no review line item specifically for this, reviewers are nevertheless likely to react better to code that is easy for them to read and understand. With efficient code you get a potential performance advantage in stress and benchmark testing, as well as likely kudos (and a few extra points) from the reviewers.
  • Write a comprehensive unit testing suite. Inadequate tests can cost you dearly because there are several review line items pertaining to the unit test suite. Tests should cover all non-private methods thoroughly, and they should be well documented. Doing a good job on the tests can be a big win because the unit test suite is one of the areas that are more frequently neglected.
  • Provide excellent documentation. The class and method documentation is the developer's responsibility, and few developers seem to give it the attention it deserves. Good documentation will be clear and comprehensive. Read and become familiar with Javadoc's docs. Note, for instance, that more or less arbitrary HTML can be inserted into documentation comments; appropriate use of that feature can be very effective. Try to put yourself in another developer's position and ask yourself what you might possibly want to know about the component - then put it in. Read and follow Sun or Microsoft's guide on writing comments for the respective language, and also their related documentation on how to write API specifications.
  • Fully satisfy all requirements and provide all required functionality. Perhaps this should go without saying, but it will hurt your chances if anything is left out. Watch out for special cases and unusual inputs.
  • Pay attention to any issues that the designer may have disregarded or overlooked - thread safety, for instance, or portability (even Java and .NET software can have portability issues). Where you have discretion within the design, give your submission desirable properties such as these.

IX. Review

The submission is out of your hands, and the Review Board will judge it on the following criteria. Before the review, there is a screening phase for the submissions, you can find a sample screening scorecard here. You can find a very detailed summary of the scorecard here and a sample review scorecard here.

Functionality

The most important is the functionality. The Review Board will check whether all the requirements are implemented and all functionalities in the design documents are provided. The proper technology should be used to achieve them (for example, do you connect to the database properly? Do you use proper XML configuration? ). And if there are complicated algorithms in the component, they are likely specified by the design. You're encouraged to imporve it. But if you are not sure whether your algorithm is correct, please ask in the forum.

Definition

Another important aspect is whether your submission conforms to the defined interfaces(visibility, types, modifiers, names, exception list). Removing, adding, or altering non-Private API is unacceptable without prior approval from the designer or PM. Helper classes/methods are allowed but you need to narrow them to the minimum scope.

Code

  • Reviewers will look into the code in details to see whether the object types are used as the best choice. For example, you may decide to use a TreeMap to store some value mappings. Unless you need to preserve key ordering, you should probably use a HashMap instead. The "best" choice here is generally related to efficiency. And there shouldn't be useless and sloppy codes. Your code should be elegant enough to minimize the code redundancy while keep it clean and clear.
  • This is somewhat subjective, but there are objective references. You probably shouldn't go more than one level with the ternary if operator (e.g. good ? "great!" : ok ? "I suppose" : bad ? or_is_it ? "darn" : "phew" : "who knows?"). This is not clear. Similarly, large blocks of code... if you're getting more than 50 lines in a single function, you can probably break it up into multiple functions. For example, if you're drawing a graph, you can have a drawAxes() function, a drawData() function, and a drawLegend() fuction, rather than a very large block of code. As for efficiency, small things can make a big difference. Break out of a search when you've arrived at the desired value. Set intelligent sentinel conditions, use short circuit evaluation. Don't overcomplicate your code, and try to simplify whereever possible.
  • All code, including test cases, follows the TopCoder coding conventions. Our coding conventions are the published standards for Java and C#. You can view them at the following links:
    Java Coding Conventions
    .NET Coding Conventions

Documentation

The implementation code contains detailed documentation for classes, methods, and variables, written in Javadoc / XML style as required by the Java / C# coding standards. And the documentation must be syntactically correct: no documentation for elements that no longer exist, no inappropriately anchored or malformed documentation elements.

Unit Testing

  • Unit Test Cases thoroughly and correctly test all methods and constructors. Unit Test cases contain an implementation or a demonstration of how the component will be used. The demonstration should be done in the required environment. For example, for a web component, the demonstration should be provided as a web application.
  • The environment should be configured as flexible as possible. There shouldn't be any files/connections opened after testing. Always cleaning up the environment in tear-down method is a good practice.
  • Your unit test code must be documented exactly as your component code. Additionally, each of the three development reviewers will write unit tests that will probe your component for accuracy, proper failure, and performance under stress. Your component will be awarded a score based on each of the above points, and those tests.

X. Appeals

After review is complete, you will have a few days to view and appeal the score your component was given. You'll see the comments from the Board on each point above, and you can dispute any score. Please keep in mind that you must have a very good reason to appeal, or it will be denied. If the reviewer makes a statement that is in conflict with the design, or if the review has made an oversight, feel free to appeal. On the other hand, matters of opinion may not be appealed. If you are the winning developer, you will have the opportunity to discuss reviewers' judgments in Final Fixes...

XI. Final Fixes

Congratulations! You're the winning developer!
However, there is probably still work to be done. Your review scorecard will be available via Project Submit & Review, and there you will find any and all problems the Review Board found with your submission. It will contain required and recommended fixes to the submission as received.

  • Every single required fix must be addressed. Your component WILL NOT be completed until they are.
  • Every recommended fix should be attempted. Obviously, they follow the required fixes in priority, but if there is time, they should be completed.
  • And don't forget to change TCSDEVELOPER to your real handle!

    Communication

More than any stage of the component, communication during final fixes is key.If, for any reason, you have a question or comment on the review, post it as soon as possible. If there is any blocking issue, email the PM immediately, and post to the forum. The PM will look into the issue, and ensure that the primary reviewer is on top of things. If, for whatever reason, you feel a required fix is impossible, you need to address it on the forums. Do NOT just resubmit without the fix done, or a comment in a readme. This is never acceptable. Communicate with the reviewers to avoid these conflicts! The more detail you can give, and the sooner you give it, the more smoothly this stage will go. The Review Board is always open to communication from the developer; they may have overlooked something in the design or in your submission. Don't be afraid to question the Review Board. Questions and comments show that you're paying attention and actively involved; without communication, the Review Board doesn't know that you're working on the fixes, and can't clarify their requirements.

XII. Final Submission and Review

This is just another dev_submission build. Follow the same guidelines above for ensuring all your files are uploaded properly. Try to be as complete as possible before resubmitting. This saves everyone time, including you.
If you've met all the requirements, and all the review tests still pass, the component is complete, and goes into preparation to be added to the catalog. Your work is complete!
If anything is not done, you've earned a return trip to Final Fixes.

XIII. Prizes

Now congratulations! You are ready to receive the winning prize, but there could be more!

Reliability Bonus

Your profile has a reliability factor for the last 15 component design and 15 development competitions. The reliability factor is calculated as the percent of the last 15 projects that a member registers for in which that same member presents a timely submission that scores at least a 75 in review. For a high enough reliability, a bonus will be given for every winning afterwards. For example, with 100% reliability, you will get 20% more for every winning.
In order to keep a high reliability, you need to be careful when registering for a project. Before registration, make sure that you have enough time to complete it, and are familiar with the technologies used. It's always a good idea to download the Requirements Specification on the project detail page and Component Specification on the project forum to see more details before making decisions.
If you don't feel confident that you can complete it in time, before registration ends, you can always unregister. This can be done through the Online Review page for the development - there is an "Unregister" link. You can unregister only before the registration closed. Then non-submitting won't affect your reliability.
For more information about reliability, please see this page.

Digital Run Bonus

Digital Run gives you more prize if you compete consistently. For every project you submit, there is a Digital Run point associated. Placement Points will be awarded based on the number of submissions that pass review.
Digital Run bonus is meant to award those who consistently compete. So the basic and best idea is to compete as many as possible and try to get the highest place. Projects with high DR points are often more difficult and thus fewer people will submit, so it will be a good chance to win more points .
For more information about Digital Run, please see this page.

XIV. Conclusion

That concludes this development tutorial. You've registered, developed, tested, submitted, been reviewed, appealed, won, fixed, and finally submitted once again. You've earned your payment, and will receive royalties from your work going forward. Again, congratulations. What better way to celebrate than finding another project to register for and doing it all over again?