Live data from Hacker News

The Setup-Cleanup Problem

blog.gnoack.org

21–27 of 27 posts

Re: The Setup-Cleanup Problem

#21

It's weird to include a testing framework in it. That just speaks to usage of any orchestration class with overridable hooks, and has everything to do with events pertaining to domain (xunit's domain being "run a series of isolated tests") and not clarifying lower-level code organization. It's sort of like the author treated onFocus and onBlur in JS DOM events as startup/cleanup. It's just entry/exit orchestration. T…

Admittedly the part about xUnit was a slight derail, but I felt it made some sense to mention, as an example for "the framework" invoking cleanup handlers for the developer.

The remark about unnecessary tearDown() hooks is probably worth a separate article and not a very compelling argument in such a short form.

Re: The Setup-Cleanup Problem

#22
post #18

There's also Haskell's "bracket" ( https://wiki.haskell.org/Bracket_pattern ) which is similar to python's "with" statement but with plain functions instead of context managers.

Thanks for the pointer! I'm having trouble categorizing this one, tbh. (also its relationship to what dwohnitmok says on this HN discussion)

Superficially, the code on this Wikipedia page looks like the bracket pattern in similar to the `dynamic-unwind` low-level function and friends in Scheme and Lisp - but then again I realize the notion of cleanup probably only makes sense when mutable state exists :)

How does that look in practice? Is there a clever way to use the bracket operator together with Haskell's syntactic sugar for monads?

Re: The Setup-Cleanup Problem

#23

A comparison like this would be much more informative if it used more than one layer of setup/cleanup. When you get to four or five, it really highlights how well some of these scale up (or not). Also, neither nested functions nor mini state machines seem to get a mention, which is a shame. Nested functions are a good example of an approach that gets unwieldy fast as layers are added, and mini state machines scale as…

I'm not sure what you mean by "nested function" as a cleanup mechanism, and couldn't find a mention of state machines for cleanup purposes either (but maybe I'm searching for the wrong keywords). Is there existing open source code where these can be found, or do you have a link to an explanation for these?

Re: The Setup-Cleanup Problem

#24
post #6

When mentioning C# (not sure about any other language), I would have mentioned the using statement and IDesposable objects. This way each object's needed cleanup is encapsulated in each objects dispose method(s). Granted using compiles down to a try-catch-finally with the Dispose method called in the finally, but there is an elegance to it. https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...

Thanks for the pointer, adding it to the article (with credits)

Re: The Setup-Cleanup Problem

#25

The C# version is lacking the using pattern. https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...

Similar for Java's try-with-resources. Also, I use a style in Java with higher-order functions (aka Callables/Runnables) that's like the pattern ascribed to Ruby, for situations not covered by AutoCloseable.

Thanks for the pointers, adding them to the article (with credits)

Re: The Setup-Cleanup Problem

#26
post #22
post #18

There's also Haskell's "bracket" ( https://wiki.haskell.org/Bracket_pattern ) which is similar to python's "with" statement but with plain functions instead of context managers.

Thanks for the pointer! I'm having trouble categorizing this one, tbh. (also its relationship to what dwohnitmok says on this HN discussion) Superficially, the code on this Wikipedia page looks like the bracket pattern in similar to the `dynamic-unwind` low-level function and friends in Scheme and Lisp - but then again I realize the notion of cleanup probably only makes sense when mutable state exists :) How does tha…

An example use of bracket would be:

    do 
      filename  do
        contents 
this ensures that the file is closed even if readFile or writeFile throw exceptions.

Re: The Setup-Cleanup Problem

#27
post #21

It's weird to include a testing framework in it. That just speaks to usage of any orchestration class with overridable hooks, and has everything to do with events pertaining to domain (xunit's domain being "run a series of isolated tests") and not clarifying lower-level code organization. It's sort of like the author treated onFocus and onBlur in JS DOM events as startup/cleanup. It's just entry/exit orchestration. T…

Admittedly the part about xUnit was a slight derail, but I felt it made some sense to mention, as an example for "the framework" invoking cleanup handlers for the developer. The remark about unnecessary tearDown() hooks is probably worth a separate article and not a very compelling argument in such a short form.

I can see where it's an attractive example for cleanup behavior, for sure. But I do think the distinction between code-level cleanup and domain-level cleanup is important. You can see the fixture management as part of the test code and then they align much more closely. It's usually better to not couple that way, though, and to think of automation as something that fulfills a test instead of being the test.

I also know there's a lot of debate over xUnit patterns and, in particular, setup/teardown. My take is that the perceived value depends on a lot on background and how much experience one has actually maintaining automation strategies over time. One of the bigger dangers is losing track of what you're testing so thoroughly that any confidence you might have rests essentially in magical belief instead of periodic review. That especially hits unit tests since they're added from multiple sources, and makes things like standardized fixtures/setup/teardowns pretty useful for alignment.

I'll keep a look out for future blog posts. I'm interested in your take.

Post reply on HN