Achieving a Sustainable Code Base: Moving Beyond Test-First Approach

Test-First Approach

As iOS software developers and tech firms, it's crucial to understand the significance of building a sustainable code base. While the test-first approach has its merits, it may not be sufficient on its own. In this article, we'll explore why relying solely on test-first development might lead to gaps in code coverage and how we can enhance our practices to create a more robust and maintainable architecture.

The Limitations of Test-First Approach

The test-first approach has proven effective in ensuring code correctness. However, during my experience, I noticed a few drawbacks. Firstly, some of my infrastructure tests had an excessive number of tested paths, lacking a clear point of satisfaction. This approach made me feel insecure about the implementation, potentially leading to missed edge cases. Moreover, the tests themselves became long, unreadable, and failed to provide a clear understanding of their purpose.

Reviewing Architecture and Dependency Diagrams

To address these challenges, I decided to review my architecture using Dependency Diagrams. This analysis revealed a vulnerability: there was no protective layer between the infrastructure component and the rest of the system in the face of breaking changes. Recognizing this, I developed the infrastructure component with a variety of scenarios in mind.

Embracing Command and Query Separation Principle

To better align with business needs, I employed the Command and Query Separation principle. This allowed me to identify the goals of the component and its dependency's protocol. Adopting a test-driven development (TDD) approach, I iteratively built the component while maintaining a clear understanding of its responsibilities and dependencies.

Utilizing the Inbox Checklist Technique

To comprehensively cover all scenarios for each method or command, I utilized an implementation Inbox checklist. This checklist provided a list of potential inputs, outputs, and potential errors for each command. I followed a rule of thumb: test whether the command results in no changes, specific changes, or throws an error. Similarly, I assessed queries by evaluating whether they returned zero, one, a few, many, or threw an error.

Remarkable Results

Incorporating these techniques yielded impressive outcomes:

  • Reduced the infrastructure test file from 416 lines of code (LOCs) to 187 LOCs.

  • Decreased the average number of LOCs per test from 27 to 8.

  • Trimmed the production code of the infrastructure component from 100 LOCs to 86 LOCs.

  • Significantly improved testing time from 30 seconds to 0.03 seconds.

  • Achieved increased overall code coverage from 90.2% to 92.5%.

Screenshot of the testing times.

Screenshot of the latest tests.

Conclusion

These results were achieved by adopting a holistic approach encompassing various techniques such as TDD, Inbox checklist, Command and Query Separation, Dependency diagrams, Modular design, BDD, and DTOs. Discipline played a vital role throughout the process.

By moving beyond a test-first mindset and embracing these additional techniques, iOS software developers and tech firms can build a sustainable code base that is more resilient, maintainable, and aligned with business needs. Let's strive for excellence in our development practices and continuously refine our approaches to ensure the long-term success of our projects.


Follow the code along here: repo here


I also would like to give credit to the iOS Essentials Program that helped a lot to achieve the knowledge and techniques applied here.

If you also would like to learn more visit: www.essentialdeveloper.com

Previous
Previous

Investing in High-Quality iOS Software Services: The Value of Principles and Performance

Next
Next

Practical guide to manage developer certificates in your iOS team