We have a legacy system, which is a web service, receives HTTP POST from clients, parses the data, then stores them in a file.
The function of the system is simple, and people already done functional and performance test, it’s stable. As time drifted away, the system was copy and paste to some projects by only changing the data parsing logic.
I had a similar requirement recently, then I delved into the legacy code to check if it works in order to not reinventing the wheel.
At first, I noticed below code in a HttpServlet class, it allocates more than 1M memory for each HTTP POST request.
XCTest is used as the unit test framework, and Xcode 6 is needed.
Add a test for a user case or a user story
Run all tests and see if the new one fails
Write some code that causes the test to pass
Run tests, change production code until all test cases pass
Refactor the production code
Refactor the test code
Return to 1, and repeat
The 5 and 6 are optional, do them only if needed, but be sure that DO NOT do them at the same time. That is, when you refactor production code, you can’t change the test code, until all the test cases are passed, then you are confident that your production code refactoring is perfect, then, you can refactor the test code, and this time, you can’t change the production code.
A Simple Example
We are about to implement a super simple bank account management tool.
Create a Project
Use Xcode to create a project BankAccount (iOS Single View Application)
Add a Test Case
Create a Swift file named SavingAccountTest, and choose BankAccountTests as target.
“People can deposit money to a saving account”, it’s our first user story.
Don’t forget to run all the tests, make sure it is succeeded.
Why no setup and tearDown
People coming from objc may doubt that why the account instance is not put into setUp method, the way we use might cause different test cases sharing one instance variable, as we know, test cases should be independent with each other.
Yes, I had this doubt, too. So I did a test, by adding a “account balance should be 0” check before each test cases.
The result shows that the XCTest framework avoids instance variable sharing between test cases by instantiating a brand new XCTestCase object for each test case. That is, it instantiated two SavingAccountTest objects as our tests run.
To TDD Haters
If you hate TDD, and may think this blog post is garbage.
Sorry for that, you can remove your browser history of this address, if it makes you feel better.