Skip to main content

Branch testing with Chat GPT

You can use any other Chat Bot. If you do so, change the page title.

Task 1 (student 1) 

Using a Chat Bot identify branches for the insertSort function. Assign a tag to for each identified branch.  Present the list of statements with tags. Write the prompt and the chatbot answer. Discuss the result - compare it with the previous page of the book.

Prompt

Branch testing.
Identify branches for the insertSort function.
Assign a tag for each identified branch.
Present the list of statements with tags.

void insertSort(int a[], int length)
{
    int i, j, value;
    for (i = 1; i < length; ++i)s
    {
        value = a[i];
        for (j = i - 1; j >= 0 && a[j] > value; --j)
        {
            a[j + 1] = a[j];
        }
        a[j + 1] = value;
    }
}

Response

Here’s the insertSort function with explanations and branch tags added:

void insertSort(int a[], int length)
{
    int i, j, value;
    for (i = 1; i < length; ++i)               // [B1]
    {
        value = a[i];
        for (j = i - 1; j >= 0 && a[j] > value; --j)  // [B2a], [B2b]
        {
            a[j + 1] = a[j];
        }
        a[j + 1] = value;
    }
}
Identified Branches and Tags
Tag Branch Condition Description
B1 i < length Outer for loop condition
B2a j >= 0 First part of the inner for loop condition
B2b a[j] > value Second part of the inner for loop condition

 Task 2 (student 2) 

Using a Chat Bot generate the Control Flow Graph in the DOT language for the insertSort function. Label the edges of the CFG. Discuss the result - compare the CFG with the graph created by a human. 

 Task 3. (student 3) 

Convince a Chat Bot to write a branch test for the function insertSort in the C language. Write the prompt and the chatbot answer. Discuss the result, compare it with the code written by a human in the previous section of the book.

 

Prompt

generate branch test for the function insertSort in the C language

#include <stdio.h>

#include <assert.h>

// Funkcja, którą mamy testować

void insertSort(int a[], int length)

{

int i, j, value;

for (i = 1; i < length; ++i)

{

value = a[i];

for (j = i - 1; j >= 0 && a[j] > value; --j)

{

a[j + 1] = a[j];

}

a[j + 1] = value;

}

}

// Funkcja pomocnicza do sprawdzania, czy tablica jest posortowana

int isSorted(int a[], int length) {

int sorted, unsorted;

for (int i = 1; i < length; ++i) {

if (a[i - 1] > a[i]) {

unsorted++;

return 0; // Tablica nie jest posortowana

}

}

sorted++;

return 1; // Tablica jest posortowana

}

// Testy

void testInsertSort() {

// Test 1: Tablica pusta

int a1[] = {};

insertSort(a1, 0);

assert(isSorted(a1, 0) == 1); // Tablica pusta, powinna być "posortowana"

// Test 2: Tablica z jednym elementem

int a2[] = {5};

insertSort(a2, 1);

assert(isSorted(a2, 1) == 1); // Tablica z jednym elementem, jest już posortowana

// Test 3: Tablica już posortowana

int a3[] = {1, 2, 3, 4, 5};

insertSort(a3, 5);

assert(isSorted(a3, 5) == 1); // Tablica już posortowana

// Test 4: Tablica w odwrotnej kolejności

int a4[] = {5, 4, 3, 2, 1};

insertSort(a4, 5);

assert(isSorted(a4, 5) == 1); // Tablica w odwrotnej kolejności, po posortowaniu powinna być rosnąca

// Test 5: Tablica z powtarzającymi się elementami

int a5[] = {3, 1, 2, 3, 1};

insertSort(a5, 5);

assert(isSorted(a5, 5) == 1); // Tablica z powtarzającymi się elementami

printf("Wszystkie testy zakończone sukcesem!\n");

}

int main() {

testInsertSort();

return 0;

Response

To generate branch tests for the function insertSort, we want to ensure that all logical branches in the function are exercised. This involves:

  1. Covering both true and false evaluations of all conditions.

  2. Ensuring every line of code that could be executed under some condition actually gets executed.

🔍 Branches in insertSort

In your implementation:

for (i = 1; i < length; ++i)
{
    value = a[i];
    for (j = i - 1; j >= 0 && a[j] > value; --j)
    {
        a[j + 1] = a[j];
    }
    a[j + 1] = value;
}

We focus on two conditions:

  • Outer loop: i < length

  • Inner loop: j >= 0 && a[j] > value (compound condition: both j >= 0 and a[j] > value)


✅ Existing Test Case Coverage (from your testInsertSort)

Test CaseCovers i < lengthCovers j >= 0 && a[j] > value trueCovers j >= 0 && a[j] > value false
Empty array ({})❌ (loop not entered)
Single element ({5})✅ (i=1 not < length) → skips loop
Sorted ({1,2,3,4,5})❌ (no shifting)
Reversed ({5,4,3,2,1})✅ (shifting happens)
Duplicates ({3,1,2,3,1})

So, your current tests already provide excellent branch coverage. But for clarity and academic rigor, here's a rewritten annotated version of the tests explicitly aimed at covering all branches.


✅ Revised Branch Coverage Tests for insertSort

void testInsertSort_BranchCoverage() {
    // Branch 1: length == 0 → outer loop not entered
    int empty[] = {};
    insertSort(empty, 0);
    assert(isSorted(empty, 0) == 1);

    // Branch 2: length == 1 → outer loop condition false immediately
    int one[] = {42};
    insertSort(one, 1);
    assert(isSorted(one, 1) == 1);

    // Branch 3: no inner loop shifting needed (j >= 0 is true, but a[j] > value is false)
    int sorted[] = {1, 2, 3, 4};
    insertSort(sorted, 4);
    assert(isSorted(sorted, 4) == 1);

    // Branch 4: inner loop shifting occurs (j >= 0 && a[j] > value is true multiple times)
    int reversed[] = {4, 3, 2, 1};
    insertSort(reversed, 4);
    assert(isSorted(reversed, 4) == 1);

    // Branch 5: mix of conditions (some shifting, some not)
    int mixed[] = {3, 1, 2, 3, 1};
    insertSort(mixed, 5);
    assert(isSorted(mixed, 5) == 1);

    printf("All branch coverage tests passed successfully!\n");
}

📌 Additional Notes

  • You should initialize variables in isSorted() to avoid undefined behavior:

    int sorted = 0, unsorted = 0;
    

    Although these variables are unused, if you're tracking counts later, it's essential.

  • Consider using a unit testing framework like CUnit or Unity for larger projects.

Would you like a version that logs exactly which branches are executed during tests?