Topics Covered - 3.2 | Software Engineering - Advanced White-Box Testing Techniques | Software Engineering Micro Specialization
K12 Students

Academics

AI-Powered learning for Grades 8–12, aligned with major Indian and international curricula.

Academics
Professionals

Professional Courses

Industry-relevant training in Business, Technology, and Design to help professionals and graduates upskill for real-world careers.

Professional Courses
Games

Interactive Games

Fun, engaging games to boost memory, math fluency, typing speed, and English skillsβ€”perfect for learners of all ages.

games

3.2 - Topics Covered

Practice

Interactive Audio Lesson

Listen to a student-teacher conversation explaining the topic in a relatable way.

The Inadequacy of Simpler Coverage for Compound Conditions

Unlock Audio Lesson

Signup and Enroll to the course for listening the Audio Lesson

0:00
Teacher
Teacher

Good morning class! Today, we are diving into the world of Condition Testing. Let's start by discussing why simpler coverage metrics might not suffice when we deal with compound boolean expressions. Can anyone tell me how statement and branch coverage work?

Student 1
Student 1

Statement coverage ensures every line of code is executed, right?

Teacher
Teacher

Exactly! And what about branch coverage?

Student 2
Student 2

Branch coverage checks whether each 'true' and 'false' path of every condition has been executed.

Teacher
Teacher

Spot on! However, these approaches can miss certain critical bugs in complex conditions. For example, if we have a condition like 'if (A && B)', what might a single test case miss?

Student 3
Student 3

It might only test A true and B true at one point, but not when B is false.

Teacher
Teacher

Exactly! This is why we need deeper analysis, and this brings us to Condition Testing. Remember, we will use the acronym β€˜CARE’ which stands for Condition Analysis Requires Evaluation – emphasizing that each condition must be independently evaluated to see its influence. Let's move on.

Condition Testing: Drilling Down into Logical Expressions

Unlock Audio Lesson

Signup and Enroll to the course for listening the Audio Lesson

0:00
Teacher
Teacher

Now that we understand the problems with simpler coverage metrics, let's delve deeper into Condition Testing. Can anyone summarize what Condition Testing entails?

Student 4
Student 4

Condition Testing focuses on verifying logical conditions and ensuring each component is evaluated correctly?

Teacher
Teacher

Right, and what's the ultimate goal of Condition Testing?

Student 1
Student 1

To find errors in logical operators or conditions in complex expressions!

Teacher
Teacher

Exactly! It's about rigorously ensuring that logical conditions do not contain errors. This involves deriving effective test cases that will exercise each atomic condition to both true and false effectively. Remember to keep this approach systematic!

Types of Condition Coverage: Increasing Rigor

Unlock Audio Lesson

Signup and Enroll to the course for listening the Audio Lesson

0:00
Teacher
Teacher

Next, let's discuss the different types of condition coverage. Who can explain Basic Condition Coverage?

Student 2
Student 2

Basic Condition Coverage ensures every individual condition is tested for both true and false outcomes.

Teacher
Teacher

Great! What about its limitations?

Student 3
Student 3

It doesn't guarantee that the overall decision takes both paths.

Teacher
Teacher

Correct! That's where Branch/Condition Coverage comes into play. It combines both Basic Condition Coverage and Branch Coverage. What does it ensure?

Student 4
Student 4

It ensures each decision is taken and all conditions within those decisions are evaluated to both outcomes!

Teacher
Teacher

Perfect! Finally, Modified Condition/Decision Coverage or MC/DC adds rigor by requiring demonstration of independent influence. Remember the acronym 'I.V.E.' or Independent Validation of Each condition! Moving ahead now.

Practical Derivation of Test Cases for Condition Testing

Unlock Audio Lesson

Signup and Enroll to the course for listening the Audio Lesson

0:00
Teacher
Teacher

Let's shift gears and look at how to derive test cases for Condition Testing. What key elements are essential in this process?

Student 1
Student 1

We need to ensure that all simple conditions are tested for both true and false!

Teacher
Teacher

That's right. Can anyone think of a practical example?

Student 2
Student 2

What about testing a function that checks if a user is eligible to process an order based on login status and stock availability?

Teacher
Teacher

Good example! Therefore, we'd establish test cases that satisfy Basic Condition Coverage by ensuring each condition evaluates to true or false appropriately. Does anyone have questions about consolidating test cases?

Student 3
Student 3

Does multiple tests count towards coverage, or do we need uniquely different ones?

Teacher
Teacher

The goal is to cover all conditions while minimizing the number of tests through shared cases when possible. A solid understanding of how these test cases relate is crucial.

Advantages and Limitations of Condition Testing

Unlock Audio Lesson

Signup and Enroll to the course for listening the Audio Lesson

0:00
Teacher
Teacher

To conclude our discussion, let’s evaluate the advantages and limitations of Condition Testing. What are some advantages you can think of?

Student 4
Student 4

Improved defect detection by uncovering errors in logical expressions.

Teacher
Teacher

Exactly, and does anyone want to highlight another advantage?

Student 1
Student 1

It also forces a deeper understanding of the code logic and structure!

Teacher
Teacher

Correct! However, what about the limitations?

Student 2
Student 2

Generating tests for complex conditions can lead to a combinatorial explosion!

Teacher
Teacher

Right! And it won't catch conditions that are missing outright. Summarizing, while Condition Testing greatly enhances logical coverage, it also presents challenges that we need to manage carefully. Great job, everyone!

Introduction & Overview

Read a summary of the section's main ideas. Choose from Basic, Medium, or Detailed.

Quick Overview

This section discusses advanced white-box testing techniques, particularly focusing on Condition Testing and its various coverage types.

Standard

In this section, the reader will explore Condition Testing, its limitations in simpler coverage criteria, and its importance in high-quality software development. It covers the significance of Condition Coverage types including Basic Condition Coverage, Branch/Condition Coverage, and Modified Condition/Decision Coverage (MC/DC), while also providing methods to derive practical test cases for ensuring robust logical testing.

Detailed

Detailed Overview of Advanced White-Box Testing Techniques

This section extensively covers advanced white-box testing techniques, particularly emphasizing Condition Testing. White-box testing involves evaluating the internal structures or workings of an application, as opposed to its functionality. The goal is to ensure that the logic flows correctly across various paths.

Key Areas Covered:

  • The Inadequacy of Simpler Coverage for Compound Conditions:
    Simpler coverage metrics like statement or branch coverage fail to assess complex boolean conditions effectively. A compound boolean expression combines multiple atomic conditions with logical operators, leading to potential bugs that simpler tests might miss.
  • Condition Testing: This method focuses on evaluating individual conditions in depth within a compound boolean expression to ensure each part works as intended. The primary aim is to find logical errors or typos within an expression that could cause incorrect results.
  • Types of Condition Coverage:
  • Basic Condition Coverage (BCC): Ensures each atomic condition within an expression is tested for both true and false conditions, although it may not guarantee overall decision outcomes.
  • Branch/Condition Coverage: A more comprehensive criterion than BCC that combines both branch coverage and condition coverage, aiming to ensure the correctness of both overall decision outcomes and individual conditions.
  • Modified Condition/Decision Coverage (MC/DC): This highest standard of condition testing focuses on demonstrating that each condition independently influences the decision outcome, making it crucial for high-integrity systems.
  • Practical Derivation of Test Cases: Emphasizes how to create test cases that effectively achieve specified levels of condition coverage. This segment illustrates the application of theoretical concepts through practical examples.
  • Advantages and Limitations of Condition Testing: Describes the benefits, such as improved defect detection, and the challenges, such as the combinatorial explosion of test cases and the inability to detect missing conditions in logical expressions.

By mastering these advanced techniques, software engineers can enhance unit and component testing, particularly within high-integrity software, leading to greater reliability and defect detection.

Audio Book

Dive deep into the subject with an immersive audiobook experience.

Inadequacy of Simpler Coverage for Compound Conditions

Unlock Audio Book

Signup and Enroll to the course for listening the Audio Book

1. The Inadequacy of Simpler Coverage for Compound Conditions:

The Problem: While statement coverage ensures every line executes and branch coverage ensures every decision (e.g., if-else) takes both its true and false paths, these criteria often fall short when dealing with compound boolean expressions. A compound boolean expression combines multiple individual (atomic) conditions using logical operators like AND (&&), OR (||), and NOT (!).

Example Scenario: Consider a decision if (A && B) { ... }.

To achieve 100% branch coverage, you only need two test cases: one where A && B is true (e.g., A=true, B=true) and one where A && B is false (e.g., A=false, B=true).
Notice that in the second case (A=false, B=true), the condition B was never evaluated to false. If there's a bug that only manifests when B is false (e.g., if (A && B) should have been if (A && !B)), branch coverage alone would miss it. The problem is that the individual conditions within the compound expression (A and B) were not thoroughly tested in isolation.

The Need for Deeper Analysis: This highlights a critical gap. For high-quality software, especially in scenarios where complex logic dictates critical outcomes (e.g., access control, financial calculations, safety systems), simply covering branches isn't enough. We need techniques that ensure every component of a compound decision is thoroughly exercised.

Detailed Explanation

This chunk explains how simpler coverage techniques, like statement and branch coverage, are insufficient when it comes to testing complex boolean expressions. In programming, conditions often combine multiple logical statements. For instance, if we have a condition like 'if (A && B)', achieving branch coverage only requires that both outcomes (true and false) of the entire condition are tested. However, this does not guarantee that each individual condition (A and B) within the expression has been adequately tested. Consequently, if there is a subtle bug that only occurs when B is false, this defect could go unnoticed. This underlines the necessity for more thorough testing methods that evaluate each condition independently to ensure the integrity of complex logical decisions in software development.

Examples & Analogies

Think of this like a safety checklist before flying an airplane. If the checklist only confirms that the cockpit light is either green (all systems go) or red (issues present), it may overlook the individual checks for fuel level, engine status, or passenger safety. If one of those individual components fails but is not tested separately, it could lead to serious issues in flight. Similarly, testing individual conditions in a boolean expression ensures that no critical aspects are overlooked.

Condition Testing: Drilling Down into Logical Expressions

Unlock Audio Book

Signup and Enroll to the course for listening the Audio Book

2. Condition Testing: Drilling Down into Logical Expressions:

Definition: Condition Testing is a white-box test case design technique specifically aimed at thoroughly verifying the behavior of logical conditions (boolean expressions) within a program's source code. It goes beyond merely exercising the true/false outcomes of an entire decision and instead focuses on ensuring that each individual, atomic component of a compound condition is evaluated to both true and false, and that these individual evaluations contribute meaningfully to the overall decision.

Primary Goal: The paramount goal of Condition Testing is to detect errors related to the incorrect formulation or evaluation of boolean expressions. This includes:

  • Errors in logical operators (e.g., using && instead of ||).
  • Typographical errors in conditions (e.g., x > 5 instead of x >= 5).
  • Incorrect variable usage within conditions.
  • Missing or superfluous conditions.

Underlying Principle: It operates on the principle that to thoroughly test a compound condition, each atomic condition (also called a 'simple condition' or 'predicate') that makes up the compound expression must independently be made to evaluate to both true and false during testing.

Detailed Explanation

This chunk introduces Condition Testing, a technique in software testing that specifically targets the evaluation of logical expressions. Unlike simpler testing methods, Condition Testing ensures that each atomic condition (the individual components of a compound logical condition) is tested separately to verify its influence on the overall decision. The main goal here is to catch errors related to how logical conditions are structured or evaluated. It seeks to identify mistakes like incorrect logical operators or issues where a variable isn’t used as intended. For effective Condition Testing, it is crucial that every atomic condition is tested in both true and false scenarios, confirming their correctness before incorporating them into complex logical expressions.

Examples & Analogies

Imagine you're a teacher trying to grade a test based on multiple criteria. If your grading only checks whether the student passed (true) or failed (false) the entire test, you might overlook specific errors in the individual answers that contribute to the final grade. For example, a student could score poorly on critical questions due to misunderstandings of key concepts but still pass overall with low effort. Condition Testing in software works similarly by ensuring every portion of a logical condition is correct before moving on to make final decisions.

Types of Condition Coverage: Increasing Rigor

Unlock Audio Book

Signup and Enroll to the course for listening the Audio Book

3. Types of Condition Coverage: Increasing Rigor:

3.1. Basic Condition Coverage (BCC): Exercising Each Atomic Condition:

  • Concept: This criterion requires that for every simple condition (each individual boolean operand) within a compound decision, both its true and false outcomes must be exercised at least once. It does not necessarily consider the overall decision outcome.
  • How it Works: For a condition like (A || B) && C:
  • A must be true and A must be false.
  • B must be true and B must be false.
  • C must be true and C must be false.
  • Example: if (X > 10 && Y < 5) To satisfy Basic Condition Coverage, we need test cases such that:
  • X > 10 is true (e.g., X=12) AND X > 10 is false (e.g., X=8)
  • Y < 5 is true (e.g., Y=3) AND Y < 5 is false (e.g., Y=7)
  • Sample test cases for BCC:
  • TC1: X=12, Y=3 (true && true) -> X>10 true, Y<5 true
  • TC2: X=8, Y=7 (false && false) -> X>10 false, Y<5 false
    (This set would achieve BCC for this simple case).
  • Limitation: While it ensures individual conditions are exercised, it doesn't guarantee that the overall decision (the if statement's outcome) will take both its true and false paths in response to independent changes in single conditions.

Detailed Explanation

This chunk discusses Basic Condition Coverage (BCC), which is a foundational level of testing that focuses on ensuring that each individual atomic condition within a compound decision is tested at least once in both true and false scenarios. For example, if a conditional expression includes multiple conditions combined with logical operators, BCC requires that each condition yields its true and false values during testing. However, while BCC ensures that all parts of the condition are evaluated, it does not guarantee that the highest-level expression as a whole will yield both true and false outcomes based on those evaluations. This is a critical limitation when assessing complex boolean expressions since it may allow certain programming errors to remain undetected.

Examples & Analogies

Consider a restaurant inspection checklist where each item (like food storage, cleanliness, staff hygiene) must be checked but only individually. An inspector might confirm that each item is satisfactory without ensuring they all add up to a safe dining environment together. A simple checkmark on each item doesn’t confirm that, for example, the fridge temperature is not just fine independently, but also sufficient collectively with food spoilage risk when combined. Similarly, BCC needs to ensure each condition is checked but does not confirm the overall logic of the decision structure at a higher level.

Branch/Condition Coverage: A Stronger Combination

Unlock Audio Book

Signup and Enroll to the course for listening the Audio Book

3.2. Branch/Condition Coverage (BCC + Decision Coverage): A Stronger Combination:

  • Concept: This criterion combines the requirements of both Branch Coverage (also known as Decision Coverage) and Basic Condition Coverage. It mandates that:
  • Every branch of every decision (true/false paths of if, while, etc.) must be executed.
  • Every simple condition within a decision must take on all possible outcomes (true/false).
  • How it Works: For each decision statement, you need to ensure that the compound boolean expression evaluates to both true and false. Additionally, for each atomic condition within that expression, you must ensure it individually evaluates to true and false across the test suite.
  • Advantages: This is a more comprehensive criterion than either Branch Coverage or Basic Condition Coverage alone. It helps to find bugs related to both the overall decision structure and the internal logic of the component conditions.
  • Limitation: It still doesn't guarantee that each simple condition independently influences the outcome of the decision. This means some subtle bugs related to the interaction of conditions could still be missed. This is where MC/DC comes in.

Detailed Explanation

In this chunk, Branch/Condition Coverage (BCC) is defined as a more rigorous testing criterion that combines the strengths of both Branch Coverage and Basic Condition Coverage. This means not only do all branches of a conditional statement need to be executed, but every atomic condition within those branches must also be evaluated for both outcomes. By applying BCC to software tests, testers ensure they are covering both the decision-making structure and the logical underpinnings of any conditional statements used. While this improves testing comprehensiveness and can reveal more bugs than simpler coverage methods, it still lacks the ability to assure that conditions do not mask each other or fail to reflect cause-and-effect in decision-making, hence the development and implementation of Modified Condition/Decision Coverage (MC/DC).

Examples & Analogies

Imagine a car safety test which checks both the independent mechanisms for the brakes and the entire braking system as a whole. While testing individual components like the left and right brakes is essential, it's also crucial to test the entire system to confirm that they work together effectively and reliably. BCC focuses on both components (individual conditions) and the overall system (branch logic) to ensure comprehensive safety.

Modified Condition/Decision Coverage (MC/DC)

Unlock Audio Book

Signup and Enroll to the course for listening the Audio Book

3.3. Modified Condition/Decision Coverage (MC/DC): The Gold Standard:

  • Concept: While we will dedicate the next two lectures to MC/DC, it's important to introduce it here as the pinnacle of condition testing. MC/DC goes beyond Branch/Condition Coverage by requiring that for each simple condition within a decision, you must demonstrate that changing only that condition's value, while holding all other conditions fixed, causes the overall decision's outcome to change.
  • Goal: This highly rigorous criterion ensures that every condition genuinely contributes to the decision, and that no single condition is superfluous or incorrectly implemented. It's often mandated for safety-critical software.

Detailed Explanation

This chunk introduces Modified Condition/Decision Coverage (MC/DC), which represents the highest level of testing rigor when it comes to evaluating logical conditions in software. MC/DC ensures that each individual condition within a decision not only gets tested but that it can also independently demonstrate an effect on the outcome. This means that if a single condition's status is altered while keeping other conditions constant, the overall result of the decision must also change. Achieving MC/DC typically involves careful test case design to accurately reflect this requirement and is crucial, especially in safety-critical systems where software failures must be avoided at all costs.

Examples & Analogies

Consider a team that is testing a new alarm system for a hospital. Each alarm must be checked not just for functioning (like whether it rings at set intervals) but also for specific triggers (like door openings or smoke detection). Testing should confirm that if one trigger is activated while others are not, the alarm behaves correctly. This multifaceted testing appears simple but is critical for ensuring that every scenario is covered, demonstrating a clear connection between conditions and outcomesβ€”essentially what MC/DC aims to achieve in software tests.

Practical Derivation of Test Cases for Condition Testing

Unlock Audio Book

Signup and Enroll to the course for listening the Audio Book

4. Practical Derivation of Test Cases for Condition Testing (BCC Example):

Let's take a function canProcessOrder(isCustomerLoggedIn, hasEnoughStock, isValidPayment) which returns true if all conditions are met: (isCustomerLoggedIn && hasEnoughStock && isValidPayment).

  • Conditions: A = isCustomerLoggedIn, B = hasEnoughStock, C = isValidPayment.
  • Target: Basic Condition Coverage (each A, B, C must be true and false).
  • Truth Table (partial, focusing on BCC fulfillment):
  • Explanation: TC1 makes A, B, C true, covering the true side of each condition and the true outcome of the decision. TC2 makes A, B, C false, covering the false side of each condition and the false outcome of the decision.
  • Result: With just two test cases, we achieve 100% Basic Condition Coverage and 100% Decision Coverage. However, this is for a very simple AND condition. More complex conditions (with ORs, NOTs) would require more test cases to ensure all simple conditions are exercised true/false.

Detailed Explanation

In this chunk, we explore the practical application of Basic Condition Coverage through a functional example. The function 'canProcessOrder' operates based on three conditions associated with user status, stock levels, and payment validity. To effectively achieve BCC, test cases must be generated where all conditions are evaluated as both true and false. For instance, one test case could evaluate to true for all three inputs while another sets all to falseβ€”thus satisfying the basic criteria for effective coverage. The effectiveness is illustrated: although this simple example achieves comprehensive coverage, more intricate logical combinations in advanced coding would necessitate additional, more elaborate test case design processes.

Examples & Analogies

Imagine a coffee shop where different conditions must be met before a customer can make an order, like being a member, having enough products in stock, and paying correctly. If the manager only asks whether the customer meets all conditions without checking each one, they risk turning away a paying customer. Testing each condition allows the staff to ensure they are meeting all necessary criteria for each transaction.

Advantages and Limitations of Condition Testing

Unlock Audio Book

Signup and Enroll to the course for listening the Audio Book

5. Advantages and Limitations of Condition Testing:

5.1. Advantages:

  • Improved Defect Detection for Logical Errors: Highly effective at uncovering errors in boolean logic, such as incorrect operators (&& vs. ||), swapped conditions, or missing negations (! operator).
  • More Rigorous than Branch Coverage: Goes deeper than just overall decision outcomes, ensuring that the components that build those decisions are properly exercised.
  • Enhanced Code Understanding: Forces developers and testers to meticulously analyze compound conditions, leading to a clearer understanding of the expected logical flow.
  • Systematic Approach: Provides a structured method for deriving test cases, ensuring that critical logical paths are not overlooked.

5.2. Limitations:

  • Doesn't Guarantee Independent Influence: The primary limitation is that even achieving 100% Branch/Condition Coverage does not guarantee that each individual condition independently affects the decision's outcome. This specific guarantee is provided by MC/DC, which requires more sophisticated test case design.
  • Combinatorial Explosion for Complex Conditions: For compound conditions with a large number of simple conditions, generating test cases for all possible combinations can become prohibitively expensive, leading to a 'combinatorial explosion' problem. This is where MC/DC aims to achieve high confidence with a minimum number of tests.
  • Doesn't Address Missing Conditions: Condition testing verifies the conditions that are present in the code. It cannot detect if a crucial condition is entirely missing from the boolean expression, as that would be a requirements defect, not a coding error in the existing logic.

Detailed Explanation

This chunk outlines the strengths and drawbacks of applying Condition Testing in software development. On the advantages side, Condition Testing significantly enhances the detection of logical flaws within code, enabling clearer defect resolution. It encourages a more profound understanding of how individual logical expressions relate to larger constructs, improving overall code quality. However, there are noted limitations that mainly revolve around the inability to always guarantee individually verifiable test results or the potentially overwhelming number of test cases needed when conditions are complex. Additionally, while this method verifies current logical expressions, it cannot identify entirely missing conditions or scenarios, marking a need for complementary testing strategies, such as MC/DC, which addresses these gaps more comprehensively.

Examples & Analogies

Consider a team of chefs developing a new recipe. They might test the recipe for specific ingredients to ensure the dish is delicious (advantage). However, if they don't ensure that all ingredients are present in their tests, they may miss out on a crucial herb, leaving the dish bland despite testing everything else rigorously (limitation). Just like chefs need to evaluate every single aspect, Condition Testing ensures all logical components interact as expected, but lacks the power to address what isn’t considered at all.

Definitions & Key Concepts

Learn essential terms and foundational ideas that form the basis of the topic.

Key Concepts

  • Condition Testing: A focused approach to testing logical conditions ensuring comprehensive coverage.

  • Basic Condition Coverage (BCC): Evaluates all atomic conditions of an expression for true and false outcomes.

  • Branch/Condition Coverage: Ensures every decision and each condition within is tested.

  • Modified Condition/Decision Coverage (MC/DC): Provides the most rigorous checking ensuring independent influence of conditions.

Examples & Real-Life Applications

See how the concepts apply in real-world scenarios to understand their practical implications.

Examples

  • A function checking user eligibility using conditions like login status and stock availability derived from the examples discussed.

Memory Aids

Use mnemonics, acronyms, or visual cues to help remember key information more easily.

🎡 Rhymes Time

  • Conditions that we test, logical errors we quest, coverage ensures we're at our best!

πŸ“– Fascinating Stories

  • Imagine a detective analyzing decision-making paths like a maze, ensuring he leaves no hidden corner unchecked.

🧠 Other Memory Gems

  • Remember the acronym 'CARE' to encapsulate the importance of Condition Analysis Requires Evaluation.

🎯 Super Acronyms

BCC - Basic Condition Coverage

  • Each condition checked for true/false to ensure thorough testing.

Flash Cards

Review key concepts with flashcards.

Glossary of Terms

Review the Definitions for terms.

  • Term: Condition Testing

    Definition:

    A technique used in software testing that focuses on verifying the behavior of logical conditions in a program's code.

  • Term: Compound Boolean Expression

    Definition:

    An expression that combines multiple conditions using logical operators such as AND, OR, and NOT.

  • Term: Basic Condition Coverage (BCC)

    Definition:

    A coverage metric ensuring each atomic condition within a compound decision is evaluated to both true and false at least once.

  • Term: Branch/Condition Coverage (BCC)

    Definition:

    A criterion combining essentials of both branch coverage and basic condition coverage, ensuring a thorough evaluation of decisions.

  • Term: Modified Condition/Decision Coverage (MC/DC)

    Definition:

    A stringent coverage criterion ensuring that each condition in a decision independently influences the outcome.

The Problem While statement coverage ensures every line executes and branch coverage ensures every decision (e.g., if-else) takes both its true and false paths, these criteria often fall short when dealing with compound boolean expressions. A compound boolean expression combines multiple individual (atomic) conditions using logical operators like AND (&&), OR (||), and NOT (!).

Example Scenario: Consider a decision if (A && B) { ... }.

To achieve 100% branch coverage, you only need two test cases: one where A && B is true (e.g., A=true, B=true) and one where A && B is false (e.g., A=false, B=true).
Notice that in the second case (A=false, B=true), the condition B was never evaluated to false. If there's a bug that only manifests when B is false (e.g., if (A && B) should have been if (A && !B)), branch coverage alone would miss it. The problem is that the individual conditions within the compound expression (A and B) were not thoroughly tested in isolation.