Live data from Hacker News

Multiple assertions are fine in a unit test

stackoverflow.blog

231–240 of 348 posts

Re: Multiple assertions are fine in a unit test

#231

Earlier quoted context omitted.

Is there something like this available for javascript?

Not really, no. I like to use Jest’s toMatchObject to combine multiple assertions in a single assertion. If the assertion fails, the full object on both sides is shown in logs. You can easily debug tests that way. The only way to make it even possible is to do some eval magic or to use a pre-processor like babel or a typescript compiler plugin. But if you find something, Lemme know.

Well, Function.toString() should print the code of a lambda in JavaScript. So I think you could do it without a pre-processor: use Babel as a library to parse the body of the function; run each sub-expression separately and display the results.

Re: Multiple assertions are fine in a unit test

#232

Earlier quoted context omitted.

> Testing lots of things at the same time means strictly speaking you're writing an integration test rather than a unit test There's nothing wrong with integration tests, but they're not unit tests. It's fine to have both, but the requirements for a good unit test and those for a good integration test diverge. The title of this post, at least, was specific to unit tests.

A unit tests tests one unit. And integration tests covers more than one unit. I think everyone agrees with that, but nobody has defined unit. The longer I program the more I am convinced that the larger your unit the better. The unit tests is a statement that you will never refactor across this line, and that eliminates a lot of flexibility that I want. It turns out that debugging failed integration tests is easy,the…

Michael Pollan was right: Write tests, not too many, mostly integration.

Re: Multiple assertions are fine in a unit test

#233
post #70

Earlier quoted context omitted.

To answer your question: We zealots test for the fact that something changes to some degree. E.g with rubys rspec library: expect { foo.call() }.to change { bar.value }.by(2) That is, regardless of the absolute value of bar.value, I expect foo.call() to increment it by 2. The point of the 1 assertion per test guideline is to end up with tests that are more focused. Giving that you did not seem to think of the above t…

You tested a postcondition. What about preconditions and invariants, do you have separate tests for those assertions too, or just not bother?

Please correct me if I'm wrong, but would a precondtion not just be the postcondition of the setup?

Invariants would either have to be publically available and thus easily testable with similar methods, or, one would have to use assertions in the implemention.

I try to avoid the latter, as it mixes implemations and 'test/invariants'. Granted, there are situations (usually in code that implements something very 'algorithm'-ish) where inline assertions are so useful that it would be silly to avoid them. (But implementing algos from scratch is rare in commercial code)

Re: Multiple assertions are fine in a unit test

#234

Earlier quoted context omitted.

It’s debt. When you can’t add new features quickly because you have nightmarish tests to fix and you spend more time on the tests than the product, I’d say it’s debt. Especially with the insane mocking setups.

Tests can carry tech debit, just like any code. They certainly are not identified by it. Tests are one of the ways you have to ensure your code is correct. Consequently, they are business-oriented code that exist to support your program usage, and subject to its requirements. How much assurance you need is completely defined by those requirements. (But how you achieve that assurance isn't, and tests are only one of t…

They are still debt since they don't directly contribute to product value: you can delete all your tests and your software will keep functioning.

It doesn't mean it's a debt worth taking, though IME most companies are either taking way too much or way to little. Not treating tests as debt typically leads to over-testing, and it is way worse than under-testing.

Also, what you're talking about (business-oriented requirements) is more akin to higher level tests (integration/e2e), not unit tests.

Re: Multiple assertions are fine in a unit test

#235

Earlier quoted context omitted.

Test2 is a Perl distribution that replaces a bunch of older test stuff. See https://metacpan.org/pod/Test2 But unlike TAP, it's fairly Perl-specific as opposed to just being an output format. I imagine you could adapt the ideas in it to Node but it'd be more complex than simply implement TAP in JS. And yes, I think the idea of having different output formats makes sense. With Test2, the test _harness_ produces TAP fr…

What is this madness? Nothing should have to be parsed. Write test results to sqlite, done. You can generate reports directly off those test databases using anything of your choice. your-program test-re.sqlite output.html

Yeah, but sqlite doesn't scale, and SQL isn't a functional language:

https://web.archive.org/web/20110114031716/https://browserto...

Re: Multiple assertions are fine in a unit test

#236
post #194

Earlier quoted context omitted.

They are the same. I don't care, as I'll fix them one at a time, and if the fix happens to fix more than one great.

Fixing one at a time like that is a good way to get into an endless cycle. Zoom out a bit and make a plan before you start coding.

That should be understood wothout saying. Even with a plan I'm going to fix one at a time.

Re: Multiple assertions are fine in a unit test

#237
post #99

> The excellent book xUnit Test Patterns describes a test smell named Assertion Roulette. It describes situations where it may be difficult to determine exactly which assertion caused a test failure. How is that even possible in the first place? The entire job of an assertion is to wave a flag saying "here! condition failed!". In programming languages and test frameworks I worked with, this typically includes providi…

I've noticed the opposite in a Java codebase I work in. Tests where the test is assertEquals(toJson(someObject), giantJsonBlobFromADifferentFile). Of course the test runner has no idea about formatting strings that happen to be json, so I end up having to copy these out into an editor, formatting them and eyeballing the difference, or for even larger ones having to save them out to files and diff them. And of course…

As an aside, FWIW there are libraries to do JSON and XML comparisons in assertions. Output is good and you can control whether ordering is important.

Re: Multiple assertions are fine in a unit test

#238

Earlier quoted context omitted.

To answer your question: We zealots test for the fact that something changes to some degree. E.g with rubys rspec library: expect { foo.call() }.to change { bar.value }.by(2) That is, regardless of the absolute value of bar.value, I expect foo.call() to increment it by 2. The point of the 1 assertion per test guideline is to end up with tests that are more focused. Giving that you did not seem to think of the above t…

I think you forgot at least one valid assertion and implied another one: foo.call() might have a return value. Also, the whole story invocation shouldn't throw an exception, if your language has them. This assertion is often implied (and that's fine), but it's still there. Finally the test case is a little bit stupid, because very seldom code doesn't have any input that changes the behavior/result. So your assertion…

When you say I 'forgot' an assertion, are you implying that test should include all possible assertions on the code? That would perhaps cover more surface, but my goal (read zealot ideology) here is to have the tests help document the code:

test "pressing d key makes mario move 2 pixels right" {

expect { keyboard.d() }.to change { mario.x }.by(2)

}

I could test the value of the d() function, but I dont because I don't care what it returns.

Didnt understand the "whole story invocation" and exception part, am I missing some context?

Sure property-based testing can be invaluable in many situations. Only downside is if the tests become so complex to reason about that bugs become more likely in the tests than the implemenation.

I've sometimes made tests with a manual list of inputs and a list of expected outputs for each. I'd still call that 1 assertion tests (just run multiple times), so my definition of 1 assertion might too broad..

Re: Multiple assertions are fine in a unit test

#239
I have a bad habit of writing a mondo-super-all-encompassing test, and I have to break it up when I realize it’s a house of cards.

I think the better rule is “just test one thing, don’t use a lot of overlapping assertions between tests”.

Number of assertions, as noted by this post and this comment section, is not a smell at all.

Re: Multiple assertions are fine in a unit test

#240

Earlier quoted context omitted.

> Is it weird that not only have I never heard of the "rule" this post argues against This "rule" is known mostly because it is featured in the "Clean Code" book by Robert C. Martin (Uncle Bob). You should have heard of it ;)

Heard of it, but never read it. Looking at the Amazon listing and a third-party summary[0] it seems to be the sort of wool-brained code astrology that was popular twenty years ago when people were trying to push "extreme programming" and TDD. [0] https://gist.github.com/wojteklu/73c6914cc446146b8b533c0988c...

Wait what's wrong with XP and TDD? Where I'm from those are absolutely considered best practice for most situations
Post reply on HN