On Wed, Feb 14, 2018 at 10:30 AM, Axel Wagner <axel.wagner...@googlemail.com
> wrote:

>
> On Wed, Feb 14, 2018 at 10:01 AM mrx <patrik....@gmail.com> wrote:
>
>>
>> On Tue, Feb 13, 2018 at 5:26 PM, Axel Wagner <
>> axel.wagner...@googlemail.com> wrote:
>>
>>> Not very, but it does depend on the details. For example, you might
>>> provide your own http.Transport for the client to use, or even your own
>>> net.Conn.
>>>
>>
>> Using ioutils.ReadAll() on a HTTP request means to me to read out the
>> response's body. I cannot see how http.Transport and net.Conn would have
>> anything to do with this.
>>
>
> Presumably, to read out a response body means, that you made a request. By
> passing in a custom http.Transport, you can have that transport return a
> non-EOF error at will in tests.
>
> It would be far more helpful, if there would be actual code here.
>

Sure thing, taken from the http docs:

resp, err := http.Get("http://example.com/";)
if err != nil {
        // handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)


That err returned from ReadAll. I cannot see how that can possibly fail.


> You might have the server stop sending any data, so eventually the
>>> connection will timeout.
>>>
>>
>> So what you're saying is that unless the response contain chunked data,
>> ioutil.ReadAll() will never fail?
>>
>
> I say that ioutil.ReadAll will fail if and only if the io.Reader it's
> called with returns a non-EOF, non-nil error on some read. That, at least,
> seems the most obvious semantics of that function to me and it's how I read
> its documentation:
>
> > ReadAll reads from r until an error or EOF and returns the data it
> read. A successful call returns err == nil, not err == EOF.
>

Sure, that make sense. When testing for err i try to imagine what could go
wrong, to get the error handling correct. But in this case (code from http
docs above) i cannot see it...


>
> The question is, though, why would you want that?
>>>
>>
>> As ioutil.ReadAll does return an error in its signature, i think it's
>> good form to test it. Don't you?
>>
>
> No, I don't think I do, actually :) Like, what failure modes is this
> testing, how often will they occur, how likely is it, that a future change
> would break the behavior? I'm just having trouble coming up with a bug that
> might be introduced in the future, that could be caught by testing this.
>
> Checking every branch seems to be an incarnation of the "we need 100% line
> coverage" testing philosophy, but honestly, I don't believe that's
> particularly helpful, because a) path coverage is much more important than
> line coverage
>

I'm not after a 100% line coverage. =)

Is there a way to get branch/path coverage in Go? I cannot find anything
like that in the help from go test.


> and b) 100% is unattainable in practice. Adhering to some kind of
> mechanical rule about what code must have test coverage will just lead to
> wasted time - if there are zero future bugs with or without that test, it
> definitionally was useless. And I'd say that the likelihood that this is
> going to catch a future bug is very low. So if, with very high probability,
> writing that test is a waste of time then that seems a good enough reason
> not to write it.
>

I agree, i'm just trying to get the error handling correct. That's really
difficult if i cannot even imagine what could go wrong.


>
> (unless, of course, you are trying to write tests *for ReadAll itself*,
> in which case checking the whole API contract makes of course sense. But I
> assume you're not :) )
>

You're correct, i'm not writing tests for ioutil.ReadAll()


>
> Is that actually a path that is worth testing? Personally, I kind of doubt
>>> it.
>>>
>>
>> That's kind of it really, i am having a hard time making up my mind here.
>> That's why i come for the golang nuts wisdom.
>>
>>
>>> You'll probably get more bang for your buck, if you instead send back
>>> broken/incomplete data from the server and see if the client handles that
>>> correctly.
>>>
>>
>> I already test for this kind of problems in my unittests. It's more a
>> matter of what to do with the error return value from ioutil.ReadAll() when
>> i cannot see how i could ever get anything but err == nil. It might just be
>> me, that doesn't know enough about the ioutil.ReadAll() internals.
>>
>
> After digging some into the code, it does inform a sensible additional
> test you might be doing, as it also returns an error if the reader returns 
> *too
> much* data - so it would make sense to check what happens if the server
> would send back, say, an infinite bytestream. But that still isn't really a
> test for the ReadAll error return, as a check for "does this function
> behave well if fed unreasonable data".
>
> And to answer the question of what to do about err != nil: You should
> handle it :) It means the data the server sent was broken in some way, you
> should handle that in some way that is appropriate for the application you
> are writing - which might include logging it, ignoring it, aborting,
> retrying or anything else, really :) Presumably, you are also handling
> invalid data somehow - this shouldn't be any different.
>

Handling those errors still mean that i need to have at least an idea or
two on what could happen, no?

// Patrik

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to