Mastering Test-Driven Development with React: Build Uncluttered and Robust React Applications Using Test-Driven Development Principles with Jest, React Testing Library, and Mocha (English Edition)
()
About this ebook
Related to Mastering Test-Driven Development with React
Related ebooks
Mastering Test-Driven Development with React: Build Uncluttered and Robust React Applications Using Test-Driven Development Principles with Jest, React Testing Library, and Mocha (English Edition) Rating: 0 out of 5 stars0 ratingsReact Anti-Patterns: Build efficient and maintainable React applications with test-driven development and refactoring Rating: 0 out of 5 stars0 ratingsMastering Test-Driven Development (TDD): Building Reliable and Maintainable Software Rating: 0 out of 5 stars0 ratingsMastering Efficient Software Design Practices Rating: 0 out of 5 stars0 ratingsReact and React Native: Build cross-platform JavaScript and TypeScript apps for the web, desktop, and mobile Rating: 0 out of 5 stars0 ratingsNode.js for Beginners: A comprehensive guide to building efficient, full-featured web applications with Node.js Rating: 0 out of 5 stars0 ratingsModern Full-Stack React Projects: Build, maintain, and deploy modern web apps using MongoDB, Express, React, and Node.js Rating: 0 out of 5 stars0 ratingsMastering Angular Test-Driven Development: Build high-quality Angular apps with step-by-step instructions and practical examples Rating: 0 out of 5 stars0 ratingsLearning Responsive Data Visualization: Create stunning data visualizations that look awesome on every device and screen resolutions Rating: 0 out of 5 stars0 ratingsUltimate Web API Development with Django REST Framework Rating: 0 out of 5 stars0 ratingsJavaScript Design Patterns: Deliver fast and efficient production-grade JavaScript applications at scale Rating: 0 out of 5 stars0 ratingsWeb App Testing Using Knockout.JS Rating: 0 out of 5 stars0 ratings
Programming For You
Excel : The Ultimate Comprehensive Step-By-Step Guide to the Basics of Excel Programming: 1 Rating: 5 out of 5 stars5/5Coding All-in-One For Dummies Rating: 4 out of 5 stars4/5SQL All-in-One For Dummies Rating: 3 out of 5 stars3/5Hacking Electronics: Learning Electronics with Arduino and Raspberry Pi, Second Edition Rating: 0 out of 5 stars0 ratingsSQL QuickStart Guide: The Simplified Beginner's Guide to Managing, Analyzing, and Manipulating Data With SQL Rating: 4 out of 5 stars4/5HTML in 30 Pages Rating: 5 out of 5 stars5/5Python Programming : How to Code Python Fast In Just 24 Hours With 7 Simple Steps Rating: 4 out of 5 stars4/5Python: Learn Python in 24 Hours Rating: 4 out of 5 stars4/5Excel 101: A Beginner's & Intermediate's Guide for Mastering the Quintessence of Microsoft Excel (2010-2019 & 365) in no time! Rating: 0 out of 5 stars0 ratingsLinux: Learn in 24 Hours Rating: 5 out of 5 stars5/5Automate the Boring Stuff with Python, 2nd Edition: Practical Programming for Total Beginners Rating: 4 out of 5 stars4/5Python: For Beginners A Crash Course Guide To Learn Python in 1 Week Rating: 4 out of 5 stars4/5A Slackers Guide to Coding with Python: Ultimate Beginners Guide to Learning Python Quick Rating: 0 out of 5 stars0 ratingsCoding All-in-One For Dummies Rating: 0 out of 5 stars0 ratingsBeginning Programming with C++ For Dummies Rating: 4 out of 5 stars4/5Learn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5Teach Yourself C++ Rating: 4 out of 5 stars4/5OneNote: The Ultimate Guide on How to Use Microsoft OneNote for Getting Things Done Rating: 1 out of 5 stars1/5Linux Command-Line Tips & Tricks Rating: 0 out of 5 stars0 ratings
Reviews for Mastering Test-Driven Development with React
0 ratings0 reviews
Book preview
Mastering Test-Driven Development with React - Ravi Kumar Gupta
CHAPTER 1
Getting Started with TDD
Introduction
As a software developer, a question must have crossed your mind many times: Did you write unit tests? Well, we all know the answer to that. In this chapter, you are going to embark on a journey into the world of Test-Driven Development (TDD), a game-changing approach to software development. TDD is not just another buzzword in the tech industry; it is a methodology that can transform the way you build applications, and it is especially relevant in the context of ReactJS. In the pages that follow, you will not only learn what TDD is but also why it is becoming a cornerstone of modern software development.
This book assumes that you have a basic understanding of React.js development. If you are already familiar with React.js, you will be able to follow the examples and concepts with ease. The libraries we are going to use for writing test cases are Jest, Mocha, and Chai. While prior knowledge of these is not required, the book will introduce and explain these testing frameworks as we progress.
By the end of this chapter, you will have a solid foundation to explore the practical aspects of TDD and how it can supercharge your React projects.
Structure
In this chapter, we will cover the following topics:
Overview of TDD
Cost of Fixing Defects
Development Life Cycle
Advantages of Test-Driven Environment
Myths Around TDD
TDD in Project Development
Observations on TDD
Success Stories of using TDD Over Normal Approach
Overview of TDD
Let us imagine you are participating in a project meeting (Figure 1.1). All of the development is completed; end-to-end testing is done. Your manager suddenly inquires whether we have performed unit testing or not. You, as a developer, start seeing flying birds around your head, and somehow you manage to convince them why it was not done.
Figure 1.1: Project meeting after development
(Source: https://www.commitstrip.com/en/2017/02/08/where-are-the-tests/)
Anyways, you fasten your belt for the next project that you are going to write unit test cases and going to show 100% test coverage. But, alas, same story again. Familiar enough?
What if you enforce your working style to be test-driven? Are you wondering what it is? In a normal scenario, you write your function, class, or a block of code to perform some task. You try executing it to see if it works. Finally, once it works, you decide to write unit tests.
Let us try the same development differently. You write an empty test first, which will call your function to test. Now you implement the function and run it to see if it works. It does not? Correct the function code and run the test again. Works now? Great.
Ultimately, you have your test cases and code that works well. This is a high-level view of how test-driven development works. It helps you to focus on what is required. As a developer, you code only the necessary part to make the test pass. While writing test cases, you can try to check on all types of input and output for the function code. Thus, if the test cases are written properly, there are very few chances of finding a defect later.
Cost of Fixing Defects
If a defect is found during development, the cost of fixing it is minimal, but if it is seen after the product is released, the cost is way higher. There are many studies performed to measure the cost of change when a bug is found.
In the paper, Integrating Software Assurance into the Software Development Life Cycle (SDLC), Jan 2010 (https://www.researchgate.net/publication/255965523_Integrating_Software_Assurance_into_the_Software_Development_Life_Cycle_SDLC), authors Maurice Dawson, Darrell Norman Burrell, Emad Rahim, and Stephen Brewster mention a study performed at IBM System Science Institute about the cost of fixing the defect at different phases of the project.
The following figure shows the cost of defect fixing at the design, development, testing, and maintenance phases:
Figure 1.2: Cost of fixing defects at each stage
As per the study, fixing defects already causes 15 times more resources as compared to the design phase. During the maintenance phase, the cost is 100 times more. With test-driven development, you catch defects during the design and development phases, thus saving a lot of time and money.
Development Lifecycle
When it comes to the Software Development Life Cycle (SDLC), there are many phases, namely, requirement gathering, design, development (coding), testing, deploying the code, and maintenance. To stay in context, we will only look at the development and testing phases. The following figure explains the development and testing lifecycle:
Figure 1.3: Development and testing lifecycle
After the design is approved, a developer starts writing code, for example, a function to implement a particular feature. Once the feature is coded, he/she tests it by executing it. In a sophisticated environment, developers will write unit tests and then test the function. Similarly, all or some of the features are developed and deployed to the QA instance so that a tester can test the given system (assuming an agile development here).
The key difference in the test-driven development lifecycle is that before writing the feature code, a test is written. Initially, the test would be empty and will fail because the feature function does not exist yet. Now write a simple feature function, and the test will pass. Update the test with more checks. The test might fail. Update the feature function again, and the test will pass. Keep doing this until all the test cases are covered. In the end, you will have a function that is well-unit-tested. Do this for all features, and you will have a nearly bug-free code. Nearly bug-free because there are many other factors responsible for zero-defect software.
The following figure shows a typical lifecycle in test-driven development:
Figure 1.4: Development Life Cycle in Test-Driven Development
The following list of tasks explains the different phases of a test-driven development lifecycle:
Pick a feature and write a test: Pick one out of all the features and start writing a test. Initially, the test would be to check if the function implementing the feature exists. Even though we know that the test would fail and functions are not implemented, we still write the test first. This is the key difference between other methodologies and TDD. It enforces writing a test first.
This way of development forces the developers to think about what is expected out of a feature, function, or simple logic. As a developer, you start thinking of what kind of various outputs (for example, different string values, different status codes, and so on) or the types of output (for example, integers, strings, Boolean, and so on) the function might emit. If you start writing tests for all possibilities, your actual code will never function unexpectedly.
Run the test: Once a simple test is written, we simply run it. We know it would fail since there is no logic or function coded yet. Still, we run the test to ensure that the test fails. You might wonder what the need is to run the test at this stage. Well, this is the first test case to find out if the feature exists or not.
Consider that the application is fully written and working fine. As a change request, you might need to alter the application code to add some features. Unintentionally, an old function you believed may not be utilized anywhere, gets deleted. With the first test case in place for checking if the function exists, you will know that something has been deleted.
Write feature code: After running the test and seeing it fail, we ensure that the function does not exist. Now, we write the feature code. Initially, it might simply be empty but should exist. The function might not implement all of the business logic yet. You might find yourself keen to write the actual logic, but TDD does not allow that. You should write the test cases first and then only the actual business logic.
Improve the test – Improve feature code: After writing the blank feature code, run the test again. The test will pass now. Now we add more checks in the test case to test the function logic and output. After adding the checks, we run the tests to witness it failing again. Now add the business logic to support the checks added in the test case. We keep repeating this process—improve test > run the test > improve the function code > run the test > improve the test, and so on. This function or feature code is sometimes referred to as production code.
These checks are assertions of any other way to test the validity of your code. We will cover the assertions later in the book.
Run all tests: Once you have written all of the tests and business logic, run it to ensure that everything works and you have greens against all of your tests. Developers gain good confidence seeing greens for all of the tests. This ensures that every new feature added or any old feature downgraded will not make the system unstable. Projects are often executed as teams, and you or any other team member can be responsible for the new code, which should be tested well to avoid any unexpected behavior.
Code clean up: Once all of the production code for a feature is written and tested well, it’s time to clean up the code and tests. Sometimes, we may write a lot of checks, and some of those might be redundant or unnecessary when the function is fully coded. These checks are to be cleaned up. With respect to the function code, all of the standards should be followed. Sometimes coding and testing standards are defined specifically by the team for a project. Variable names and function names should be proper, code comments should be added, duplicate code should be removed, and so on. This refactoring is much needed to prevent the code from becoming complex over time. After cleaning up, do not forget to run the test cases to make sure nothing is broken.
These preceding steps ensure that we have a working and zero-defect feature code at the end. Next, we choose another feature, follow the same steps, and repeat these for all the features of the application.
Advantages of Test-Driven Development
There are many advantages to working in an environment that follows the test-first approach. Some of the key advantages are listed as follows:
Productive development: The test-first approach enables developers to think and implement a feature in a precise and algorithmic manner. In addition to developing enough code to pass the tests, the developer becomes intensely focused on the feature. As a result, productivity rises significantly.
Maintainable code: The number of test cases developed for a larger function will be greater. This type of code is never scalable since it is hard to monitor the consequences of change in a large function code at the time of change. The code clean-up stage of the lifecycle allows developers to refactor the code to small functions. Thus, making the code maintainable.
Better code coverage: Most of the application code is written after the test cases are written, which ensures nearly 100% code coverage.
Fail-fast approach: Usually as a developer, we know the input and expected output of the function. Knowing this, writing test cases is easy since we already know the expected output. If the production code does not function the desired way, we get to know as early as possible.
Near zero-defect: Since the code coverage is great and all of the features are tested well at the developer’s end, it leaves fewer chances of a bug. If the code is maintainable, during any change request, developers tend to focus on purpose and leave little or no room for bugs.
Lower cost of change: By writing test cases before actual code, we get immediate feedback on the quality of the code, which helps detect issues early and allows developers to fix them on time. This saves the aftermath of testing and fixing bugs and leads to a reduced cost of development. The same thing applies when there is a change to be made in existing code. Due to maintainable code, the time required to add new features is much less compared to complex code. This saves time and money for development and testing. Overall, the cost of the project is significantly reduced.
Improved documentation: Test cases also serve as documentation. A test case can be seen as an example of how the function behaves. It can tell us that for a given input, what would be the expected output? If a new team member joins or even you as a developer, these test cases act as a great reference. If test cases are grouped into test suites, that’s the cherry on top.
Myths
It is common to develop misconceptions about any technology or methodology over time. Let us discuss some of the common myths about TDD:
Waste of time: It is common to think that writing unit test cases is a time-consuming process, and if we are writing unit tests, and writing them first is going to consume more time than usual development. TDD saves time by finding bugs earlier and reduces the frequent troubleshooting needs. Also, in the long run, TDD speeds up development by avoiding frequent debugging and rework.
No testing needed: One can say that if we are going to write a test for every single function, we do not need a QA. In reality, this is not true. Testing is more than just writing unit test cases. System integration testing and testing of the complete business logic still need manual testing. Although the chances of finding bugs are significantly