exercism / go-test-runner

GNU Affero General Public License v3.0
15 stars 17 forks source link

Output in case of a test fail #44

Closed kwiat1990 closed 3 years ago

kwiat1990 commented 3 years ago

Hi, I've recently pick up Go on Exercism and one by one I try to go through all exercises. The web editor is great for this purpose but what's bother me, and I think also slows down quite a bit, are tests which failed. I feel like the messages are not clear enough and in some tests one doesn't even know what exactly failed.

An example of such test would be following output - in this case the "failure" description is completely missing and by single test case it would be helpful if there is also got key or something like this, which would hold returned value:

func TestSetItem(t *testing.T) {
    type args struct {
        slice   []int
        index   int
        value   int
    }
    tests := []struct {
        name    string
        args    args
        want    []int
    }{
        {
            name:   "Overwrite an existing item",
            args: args{
                slice:  []int{5, 2, 10, 6, 8, 7, 0, 9},
                index:  4,
                value:  1,
            },
            want:   []int{5, 2, 10, 6, 1, 7, 0, 9},
        },
        {
            name:   "Overwrite first item",
            args: args{
                slice:  []int{5, 2, 10, 6, 8, 7, 0, 9},
                index:  0,
                value:  8,
            },
            want:   []int{8, 2, 10, 6, 8, 7, 0, 9},
        },
        {
            name:   "Overwrite last item",
            args: args{
                slice:  []int{5, 2, 10, 6, 8, 7, 0, 9},
                index:  7,
                value:  8,
            },
            want:   []int{5, 2, 10, 6, 8, 7, 0, 8},
        },
        {
            name:   "Index out of bounds",
            args: args{
                slice:  []int{5, 2, 10, 6, 8, 7, 0, 9},
                index:  8,
                value:  8,
            },
            want:   []int{5, 2, 10, 6, 8, 7, 0, 9, 8},
        },
        {
            name:   "Negative index",
            args: args{
                slice:  []int{5, 2, 10, 6, 8, 7, 0, 9},
                index:  -1,
                value:  8,
            },
            want:   []int{5, 2, 10, 6, 8, 7, 0, 9, 8},
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := SetItem(tt.args.slice, tt.args.index, tt.args.value); !slicesEqual(got, tt.want) {
                t.Errorf("SetItem(slice:%v, index:%v, value:%v) = %v, want %v",
                    tt.args.slice, tt.args.index, tt.args.value, got, tt.want)
            }
        })
    }
}

=======

=== RUN   TestSetItem

--- FAIL: TestSetItem (0.00s)

If I'm missing something or read provided output wrong please let me know.

SaschaMann commented 3 years ago

I've had a similar experience when working through the exercises.


The Card Tricks exercise stands out because it also seems to jump between tests for GetItem and SetItem.

This (wrong) solution results in the next error being about TestSetItem:

// GetItem retrieves an item from a slice at given position. The second return value indicates whether
// a the given index existed in the slice or not.
func GetItem(slice []int, index int) (int, bool) {
    if len(slice) > index - 1 {
        return 0, false
    } else {
        return slice[index], true
    }
}

// SetItem writes an item to a slice at given position overwriting an existing value.
// If the index is out of range it is be appended.
func SetItem(slice []int, index, value int) []int {
    panic("")
}

However, when I change SetItem, the next error displayed is about GetItem again:

// GetItem retrieves an item from a slice at given position. The second return value indicates whether
// a the given index existed in the slice or not.
func GetItem(slice []int, index int) (int, bool) {
    if len(slice) > index - 1 {
        return 0, false
    } else {
        return slice[index], true
    }
}

// SetItem writes an item to a slice at given position overwriting an existing value.
// If the index is out of range it is be appended.
func SetItem(slice []int, index, value int) []int {
    if len(slice) > index - 1 {
        slice = append(slice, value)
    } else {
        slice[index] = value
    }
    return slice
}

I know these are wrong but I'm confused by the order and interaction of tests.


In addition to what you describe, I was also confused by the number of tests passing/failing changing.

For example, in the Card Tricks exercise, the following function results in 3 tests passed, 2 failed:

func GetItem(slice []int, index int) (int, bool) {
    return slice[index], true
}

Changing the function to the following, the numbers change to 2 tests passed, 6 failed:

func GetItem(slice []int, index int) (int, bool) {
    if len(slice) > index - 1 {
        return 0, false
    } else {
        return slice[index], true
    }
}

In the Annalyn exercise, something similar happens. With only the first function implemented, it shows "3 tests passed, 2 tests failed". After implementing the second function, it switches to "10 tests passed, 2 tests failed". Where do these tests suddenly come from? This makes it hard to keep track of which tests are actually passing and which aren't.


(Perhaps this should be split into an issue about that exercise in particular, but I think it works as an example for this issue too.)

angelikatyborska commented 3 years ago

I am interpreting this issue as a general confusion about failure messages, as @kwiat1990 reported. However @SaschaMann reported two related, but more specific issue, that I myself also experienced, and I opened separate issues for them.

Perhaps this should be split into an issue about that exercise in particular

I experienced very similar issues for a different exercise - Cars Assemble

The Card Tricks exercise stands out because it also seems to jump between tests for GetItem and SetItem.

I created a separate issue for the random order: https://github.com/exercism/go-test-runner/issues/46

With only the first function implemented, it shows "3 tests passed, 2 tests failed". After implementing the second function, it switches to "10 tests passed, 2 tests failed".

I created a separate issue for this: https://github.com/exercism/go-test-runner/issues/47

junedev commented 3 years ago

I am closing this issue because everything mentioned in here is covered in other issues. The original issue is covered in #8.