Coming back to my project with a failing test worked great. I was able to immediately run my tests, see which one was failing and then figure out where to go from there. So I figured out my date issues and now have that logic working as I want. Next up is to test out the functionality in the app.
Running through the app I found some more issues here and there. Another good reminder that while Unit Tests will help prevent bugs and regressions, there is still a need for manual testing as well. If it makes sense to add more Unit Tests as you find issues from your manual tests, then add those in as well.
I was able to fix up the issues I found from manual testing and moved on to getting the app on my actual phone. This ended up being pretty easy and straight forward. I needed to get a certificate from Apple to sign my app, but Xcode took care of most of that and I was able to publish the app to my phone pretty easy.
I have my own little ToDo list that I have been working through and adding to as I come up with new features that I want in the app or find issues that are broken. One of the main benefits to TDD is that you should be able to create a test for the smallest step that will move you forward towards the end goal. Practicing TDD for a while now has really helped me see how useful breaking up tasks into small chunks can be. and having a super simple ToDo list has allowed me to break up tasks I want to do outside of code, or at least outside of tests, into small easy to complete pieces. With this little tasks in front of me, it is not very scary to move forward, or start back up after a break, because I can just pick the first thing in the list and get to work. Because that first item is likely to be small and easy I don't have to think too hard at how to approach the problem, I can jump right in and start completing the task.
I now have a fully working app. One of the big pieces of TDD, the one that seems hardest for me, is to refactor after you have your tests working. Given that my app is pretty simple and small, now would be a good time to go over the existing logic and see if there aren't areas that could be refactored. As an indication to the user for how they are doing in relation to their goal, I had added some logic to change the color of today's total so that as they got closer to their goal they would easily see how they were doing. As it turns out, I had not put any tests around this logic, and this logic was duplicated in a couple places.
Since the main purpose of refactoring is to remove duplication, and I have a very obvious example of duplication in front of me, it is time to refactor this code. Given that I don't have any tests in place for this logic, I will need to build tests around this logic as part of my larger refactoring. I see this as doing a little TDD cycle inside of my refactor cycle. I start by creating the class I want to hold my tests, and write my first test, by calling a class that doesn't exist, this class will be where I want my logic to end up. Then I move through the mantra: Red, Green, Refactor, until I have the new class and its logic working as desired. Then I replace the places where the original code was with my new code. I have greater confidence now in the logic behind these tests, I have reduced the complexity of my app by consolidating duplicate code, and I have set myself up for easier modification in the future.
So I have gone through my little app and refactored a bit, added some tests, and have some insights into plugin/addons/enhancements to Xcode that would be nice for testing purposes. First and most obviously is that I have been running Xcode in full screen mode. Its great for focusing on the code and what is in front of me. However, when I run my tests, it launches the simulator and with launching the simulator it takes me to another window that is not Xcode, I see the simulator boot up and then I get a notification of wether or not my tests were successful. This is definitely not the ideal way this should be handled. Unless you are running UI tests, which Xcode ought to be smart enough to know, I don't think you would ever want to launch the simulator. At the very least it could launch the simulator behind the scenes and keep Xcode in the forefront, perhaps this isn't a problem if you aren't doing Full-Screen.
Another tool I miss very much is NCrunch. NCrunch is great for so many reasons. My personal favorites, and the ones I most wish were available for iOS development:
Running through the app I found some more issues here and there. Another good reminder that while Unit Tests will help prevent bugs and regressions, there is still a need for manual testing as well. If it makes sense to add more Unit Tests as you find issues from your manual tests, then add those in as well.
I was able to fix up the issues I found from manual testing and moved on to getting the app on my actual phone. This ended up being pretty easy and straight forward. I needed to get a certificate from Apple to sign my app, but Xcode took care of most of that and I was able to publish the app to my phone pretty easy.
I have my own little ToDo list that I have been working through and adding to as I come up with new features that I want in the app or find issues that are broken. One of the main benefits to TDD is that you should be able to create a test for the smallest step that will move you forward towards the end goal. Practicing TDD for a while now has really helped me see how useful breaking up tasks into small chunks can be. and having a super simple ToDo list has allowed me to break up tasks I want to do outside of code, or at least outside of tests, into small easy to complete pieces. With this little tasks in front of me, it is not very scary to move forward, or start back up after a break, because I can just pick the first thing in the list and get to work. Because that first item is likely to be small and easy I don't have to think too hard at how to approach the problem, I can jump right in and start completing the task.
I now have a fully working app. One of the big pieces of TDD, the one that seems hardest for me, is to refactor after you have your tests working. Given that my app is pretty simple and small, now would be a good time to go over the existing logic and see if there aren't areas that could be refactored. As an indication to the user for how they are doing in relation to their goal, I had added some logic to change the color of today's total so that as they got closer to their goal they would easily see how they were doing. As it turns out, I had not put any tests around this logic, and this logic was duplicated in a couple places.
Since the main purpose of refactoring is to remove duplication, and I have a very obvious example of duplication in front of me, it is time to refactor this code. Given that I don't have any tests in place for this logic, I will need to build tests around this logic as part of my larger refactoring. I see this as doing a little TDD cycle inside of my refactor cycle. I start by creating the class I want to hold my tests, and write my first test, by calling a class that doesn't exist, this class will be where I want my logic to end up. Then I move through the mantra: Red, Green, Refactor, until I have the new class and its logic working as desired. Then I replace the places where the original code was with my new code. I have greater confidence now in the logic behind these tests, I have reduced the complexity of my app by consolidating duplicate code, and I have set myself up for easier modification in the future.
So I have gone through my little app and refactored a bit, added some tests, and have some insights into plugin/addons/enhancements to Xcode that would be nice for testing purposes. First and most obviously is that I have been running Xcode in full screen mode. Its great for focusing on the code and what is in front of me. However, when I run my tests, it launches the simulator and with launching the simulator it takes me to another window that is not Xcode, I see the simulator boot up and then I get a notification of wether or not my tests were successful. This is definitely not the ideal way this should be handled. Unless you are running UI tests, which Xcode ought to be smart enough to know, I don't think you would ever want to launch the simulator. At the very least it could launch the simulator behind the scenes and keep Xcode in the forefront, perhaps this isn't a problem if you aren't doing Full-Screen.
Another tool I miss very much is NCrunch. NCrunch is great for so many reasons. My personal favorites, and the ones I most wish were available for iOS development:
- Continuous Tests - having this functionality would alleviate my issue with the simulator because I wouldn't need to launch anything as the building and testing would always be happening behind the scenes.
- Real-Time Code Coverage - showing on the side of your editor which lines of code have tests covering them and which ones are failing and which ones aren't being tested at all is fantastic. Xcode does not have an easy way to see your Code Coverage, so having something that could do this would be wonderful.
- Inline Debugging - You can also launch your tests from the Code Coverage side-bar. I can see from the red X which line of the code is causing my test to fail and I can tell NCrunch to debug all the tests that cover that line, from the Code file not the Test file. I can set a breakpoint and immediately begin figuring out what is going wrong.
For the most part, my experience with Xcode and iOS development have been exciting and positive. I have learned a bunch and have seen how the things I know from .NET can be applied to Objective-C. I still have lots of features I would like to add to my app and I expect I will continue to learn as I implement them.
Comments
Post a Comment