Discover millions of audiobooks, ebooks, and so much more with a free trial

From $11.99/month after trial. Cancel anytime.

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)
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)
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)
Ebook465 pages3 hours

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 stars

()

Read preview

About this ebook

React and TDD: Craft Reliable, High-Quality Apps from Scratch!Key Features● Master Test-Driven Development to build reliable, bug-free React apps.● Write comprehensive tests to ensure maintainable, scalable React code.● Leverage Jest and React Testing Library for efficient automated testing.● Build real-world React applications by applying TDD prin
LanguageEnglish
Release dateDec 10, 2024
ISBN9788196862077
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)

Related to Mastering Test-Driven Development with React

Related ebooks

Programming For You

View More

Reviews for Mastering Test-Driven Development with React

Rating: 0 out of 5 stars
0 ratings

0 ratings0 reviews

What did you think?

Tap to rate

Review must be at least 10 words

    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

    Enjoying the preview?
    Page 1 of 1