The effectiveness of test-driven development and refactoring techniques in computational science and engineering software development