At this point you've finished the behavior design, and written its C++ header file. (The C++ header file for our sample behavior is here.) Now you're ready to write your code and test it.
I like to write my automated test code first, before I write my behavior code. Of course, you could write it afterwards too, just as long as you write it. (Yes, you have to. Why? Because long after you've finished your behavior, I still have to test it whenever new changes come into the model. I will not test your behavior by hand. Therefore, I do not accept new behaviors into the code repository if they don't also have an automated test class.)
The automated testing environment for the C++ code is based on CppUnit. You can download the code in the downloads area. There are installation instructions here.
Here's how to create your automated test code:
1. Organize the test data you created in Part 1 into test runs. Your behavior may be the only behavior in the run. Your test runs should test all of your behavior's functionality. Usually, I can get to all parts of my behavior by putting in parameter files and examining the results of a timestep's run. This is best testing method, because it tests the behavior just like it will be used during actual simulations. If it is absolutely necessary, add your test class as a friend class of your behavior class so you can examine private behavior data directly to make sure the behavior is working.
For our sample behavior, we could use two runs for our test data.
At this point we write parameter files that will set up each run.
2. Write your automated test code. It is helpful to group your tests into a single master test function. Your code creates test runs by the following basic steps:
Your test code verifies results by using the macro CPPUNIT_ASSERT(test_condition_evaluating_to_true_or_false). When you do this, if the condition fails, a message will be passed to you at runtime.
Now you write the ".cpp" file to go with your C++ header file. At this point, it should be simple. You've already written out what all your functions do, so now you just fill in the code.
Some tips:
clTreePopulation::Find()
method. With this method you tell the tree population what kind of trees you need, and those are the trees you get. Our biomass calculation example behavior would ask the tree population for all adult trees. Remember that your behavior should only act on the trees to which it is applied. You can find out to which trees your behavior is applied by examining the mp_whatSpeciesTypeCombos
attribute of your behavior (defined in the clBehaviorBase
class).clSimManager::GetGridObject()
method. If it returns NULL, then you know the user didn't enter any grid objects and you can create the grid from scratch.m_iNumBehaviorSpecies
is defined in clBehaviorBase
and automatically given a value. You can use it to manage array size. Also, be sure your code will not throw errors if parameters are absent for species to which the behavior is not applied.Run your automated tests until it passes. There will be bugs in both your automated test code and your behavior code, but it is highly unlikely that you will duplicate the exact same bug in both places.