Agile is arguably the most rapidly growing trend in software engineering over the past decade. Besides its undoubted benefits in real-word cases, still, it has not been fully adopted as part of the daily work. The main reason is that when something becomes trendy and creates hype around it, everyone wants a piece of it and it ends up being misunderstood. This is exactly the case with agile. The true meaning of agility has survived in what we call software craftsmanship, which practically implies to implement or modify key features in short time intervals with confidence and professionalism while preserving software quality and continuous integration. But to be there it needs a well-understood mode of operation and development life cycle that the whole team (not only software engineers) follow with discipline.
Test Driven Development (TDD) constitutes an important aspect of Agile, although yet not drawn the attention it deserves. To align with strict deadlines, very often we find that the written tests are adapted to the code and not the other way around, thereby introducing a validation bias while software engineers still have the wrong impression that guarantees high-quality standards. Even worse, these tests are not even written since the code seems to work as expected and hence it is a waste of time to write them. However, the tough reality (especially in projects with large codebase) is that the investment made timely on tests will be largely refunded in the future when adding new features or code refactoring.
Recognizing that this gap is primarily a matter of “software development culture” and not due to a technological lack,the main objective of this training course is to address common misconceptions concerning the test driven development process as part of the agile methodology, and to emphasize on all the advantages that it brings to the daily work. Fundamentally, TDD is a software engineering practice that requires unit tests to be written before the code they are supposed to validate. This paradigm shift allows obtaining an easy to modify clean code that satisfies the business logic that will be delivered. To achieve this, TDD process is divided into three phases:
- Red: First write a unit test that intends to validate a new functionality. Initially, this test will fail
- Green: write the minimum software solution that is required and make the unit test to pass.
- Refactor: This phase is often neglected but is essential as it eliminates possible code duplications. During this phase, the dirty solution that we already have is refactored to match perfectly as part of the overall software architecture. The refactoring is an internal process that must not modify the external behavior of the program, which is materialized by a green test execution status.
The above cyclic processconstitutes the precondition that if followed with discipline can help to attain clean testing documentation that follows the following rules:
- Fast: A test must be fast that eases frequent execution
- Independent: tests must not depend on each other
- Repeatable: a test must be reproducible in any environment
- Self-validating: a test must have a binary result (success or failure)
- Timely: a test must be written at the appropriate time, i.e. just before the production code it will validate, as the TDD approach suggests.
Bringing TDD in the big picture, some major benefits cannot be ignored:
- You are enforced to write down clear acceptance criteria: This is a necessary step that will make clear what exactly is going to be tested.
- Clearer focus: By starting to code after describing the corresponding unit test that must be passed, will inevitably enforce you to narrow the focus to the necessary changes that need to be done, rather than thinking the application as a whole (this can be done in refactoring phase, if necessary)
- Clearly defined interfaces: Because you’re writing a test for a single piece of functionality, writing a test first means you have to think about the public interface that other code in your application needs to integrate with.
- Safer refactoring: Once you have the minimum and dirty solution that makes the test to pass, then you can safely start with clean-up and refactoring with the confidence that the functionality will not break. In any case, you have a test case that can be executed at your own pace during the refactoring phase.
- Documentation: Tests can serve as documentation to a developer that needs to understand how the code works and which are the expected results after triggering a specific flow.
In this course, we will explore some best practices that will ensure that the above objectives will be met and in a way that will allow the participants to make them an integral part of their everyday work. We will focus on producing executable documentation (unit tests) and specifically, in small batches, along with production code (TDD). We will explore refactoring and make it an unnoticeable habit or our workflow. We will understand that the ultimate goal of these disciplines is to empower us to create well-designed, high-quality, crafted software and we will learn to apply the same disciplines in our day to day work.
Spring Framework, and especially Spring Boot, has been selected as the base framework for all hands-on practice throughout the course. Spring has long been around as the de facto standard framework for developing Java applicationsand addresses almost all modern business needs via its portfolio projects. Spring Boot, in particular, offers a new paradigm for developing Spring applications with minimal effort, with more agility, and with minimal (or possibly no) configuration effort. These facts pushed us to demonstrate TDD hands-on examples on Spring Boot, as a means to make the course even more realistic.
- This specific Code.Learn program lasts 2 weeks (2 Thursdays & 2 Saturdays) and consists of 24 hours of lectures and hands-on exercise on real case studies and projects.
Key Objectives – Curriculum (High Level)
The core perspectives of this program will be to present, explore and adequately cover with extended real-life business case studies & industry scenarios the following aspects:
- Craftsmanship, agility, and professionalism
- Spring boot basics
- Unit testing
- Classicist TDD: Feedback loop, TDD cycle, Incremental progress, Classicist TDD as a design tool
- MOB/Pair program a problem with classicist TDD
- Outside-In TDD: Outside-In TDD cycle, Outside-In TDD as a design tool, London vs Chicago
- Patterns for Test Driven Development
- TDD with Spring boot
- Develop a web service from scratch using Outside-In TDD
- Best practices – takeaways
By completing the above training flow, the participant is expected to deal with the following indicative cases:
- How can we fearlessly deploy to production multiple times per day?
- How can we constantly refactor the code to better accommodate our needs?
- How can we implement applications that scale and are easy to maintain?
The roots of the answers to these questions reside deep inside our code. To address them we need to constantly think about code design and architecture while writing code. We need to learn to identify trade-offs and make informed, responsible decisions and we need to do it in a structured way. TDD is a great tool for these problems and putting it in practice in a real-world context is an essential step towards becoming a software craftsman and mastering code design and architecture. This is exactly the main principle and culture that this training program aims to promote.
Computer scientists, software engineers, and developers are welcome to participate in this code.learn program and unlock the full potentiality of the topics taught by upskilling their future careers.
Participants are expected to have working experience as software engineers and basic knowledge regarding unit testing. It is recommended that the participant has a basic spring boot experience (although not mandatory).