Iteration 1 was an interesting challenge because it was one of our first tries at test driven development and regular expressions. This was one of the largest C++ projects either of us has had a chance to work on. The purpose was to write a Scanner class that would scan a char buffer for certain tokens. The primary method of the Scanner was the scan method, which returns a list of tokens. The types of tokens the scan method looked for depending on the types of tokens defined by the types of constructs in the pfp language.
Early in the project, we worked together to create a loose plan and start writing tests. We decided on using emulated pure blocks for our code layout and dividing up different parts of the code to each other. Then we worked individually, meeting up occasionally to talk about the next steps. During our independent work times, we managed to write most of the tests and most of the component functions of scan. Then towards the end of the iteration, we met up again to finish the scan method and make sure all of the tests passed.
The amount of work for this iteration is about right for two people. Although the scan method and its component functions was short enough for one person to write, the testing and debugging really required two people to finish in the time allowed.
Luckily, my partner and I live close to each other, so it was easy to meet up to work on the project or talk about the project. The two of us have different levels of understanding of C++. I was able to teach him the relevant constructs of C++ and he was able to absorb it quickly without causing too many errors or spending too much time. It helped that our team dynamic was very good; little time was wasted when we worked together in person.
What Went Well:
Overall, the scanner came out quite nicely and many things went well for us. We chose to use emulated pure blocks for our layout style and it accurately represented the structure of our code. The comments were well formatted and appropriately used and they were useful when looking back at the code. The comments also helped us organized our test cases by having beginning and ending comments to section off related tests, such as the regular expressions tests.
I have previous experience with C++, which helped us with this the scanner because it helped us avoid errors caused by a lack of C++ experience. The most important part of the process was the testing. We were able to write a lot of tests that fully tested all of the features we implemented. The tests ensured that the component functions and features were working before moving on to the scan method. The tests helped us test the large amount of regular expressions we made, which is one of the most important parts about the scanner. Also, the tests helped us debug by helping us narrow down the root of the problem.
What Didn't Go Well:
Although we were able to pass all of our tests before the deadline, not everything went perfectly. Our planning and organization was not very good. We both worked on different parts of the code concurrently, which hampered us because we have different levels of understanding of C++ and regular expressions. We should have both worked on the same part of the code until that part was completely finished. Also, we should have looked at each other's code very closely. The error that caused us the most trouble was with the backslash regular expression. We assigned it to the wrong location and it caused segmentation faults in multiple tests and parts of the code. Closer cooperation and communication would have avoided this error.
Another main problem with our process was bad planning. We ended up doing a large portion of work towards the end of the iteration. Due to bad planning, much of the work we did individually was wasted. I became slightly frustrated when I realized how much there was left to do, and how little time we had left.
For Next Time:
There are some things that will need to change for the next iteration. We need to make a solid plan and stick to it. We need to plan what parts of the code need to be tested and completed and by when. That way we can make better markers for how much progress we have made. If one of us writes tests for a certain component, then that person needs to be the one to write those components. By writing tests, one is designing what the component should do and how it will relate to other parts of the code. The person who writes the tests has essentially written the function, that person just needs to actually do it.
Often different parts of the code depend on each other, so if we are writing different parts of the code in parallel, one of us could be road blocked by the other not finishing a function. That is the disadvantage of working on different parts of the code concurrently. For the next iteration, we have to ensure that we both finish a certain part of the code, before moving on to the next part of the code.
When working independently, we updated each other using a text document. We usually listed what we did and when on a high level. In the next iteration we will have to record precisely what we did and what we changed. We proposed listing each change and what it does. This should greatly improve communication when we are not working together.
Test driven development offered us a lot of tools for helping us design, test, and debug our project, specifically using white box and black box testing. Our white box tests allowed us to target certain parts of functions and target specific bugs. Our black box tests allowed us to confirm that an entire function was working correctly. We will continue to use this in the next iteration. Emulated pure blocks is a great way to consistently structure code, and we continue to do that as well. Our team dynamic is very good, and we should keep working together in person as often as possible.