Live data from Hacker News

Write tests. Not too many. Mostly integration

blog.kentcdodds.com

311–320 of 338 posts

Re: Write tests. Not too many. Mostly integration

#311
post #133

Earlier quoted context omitted.

This is a matter of taste not fact. In functional languages the style is compositional with static functions everywhere. It works well. The keeping data and methods together thing is one approach. Sometimes it's great. Sometimes unnecessary. For example would you argue against string formatting helpers? Or would they need to be written to an interface and added to myriad DI bucket lists?

It's not that simple and it's not a fact. I'm an advanced user of functional languages as well and have written an entire scheme implementation before. I only semi-agree. That's slightly disingenuous representation of functional languages which have more than a few pitfalls. They certainly aren't the silver bullet and they really do not scale to the same height and complexity of the problem domain as the OO languages…

To be clear I'm not saying functional is always better. I'm saying there are other possibilities and dogma is bad.

The Haskell community has its dogmas too. And it's fair share of "let's do this simpler" blog posts.

As an aside Haskell has many equivalents of dependency injection and sugars to help and you can "inject all the things" there too.

My point is to think of the problem you are trying to solve, rather than ticking off the SOLID / Martin Fowler etc. tick boxes.

Understanding OO patterns, SOLID etc is a good thing but being prepared to "break the rules" is good IMO too.

Re: Write tests. Not too many. Mostly integration

#312

Earlier quoted context omitted.

> Now your testing will dirty whatever database you're using, as well as run 10x slower It sounds like a problem is a few layers higher. Why is there a live database in your unit testing environment? Why are working credentials configured? If they're unit test, not integration tests, all db operations should be DId / mocked / whatever. Any call that isn't should fail, not take longer time. Db interaction is for the i…

That's exactly my point, mock your external dependencies. Static calls don't allow you to do that.

In your language of choice:

    static_function(db, other, arguments) { ... }
    test { static_function(fake_db, 1, 2) }
You can even omit the db in the standard case if your language allows default keyword arguments. In almost every language, a method is just a fancy static call that takes extra arguments implicitly. (Closures are poor man's objects, objects are poor man's closures...)

Re: Write tests. Not too many. Mostly integration

#313

Earlier quoted context omitted.

That has nothing to do with docker, really. I run postgres standalone on my laptop and it starts in < 1 second.

I guess they meant so your tests can start with a blank or reproducible state. But you can of course achieve the same by running a script before your tests start. There are also some frameworks for doing this sort of thing too, such as Fixie for .NET

I do this with rsync to restore a snapshot of the database data folder.

Re: Write tests. Not too many. Mostly integration

#314
post #85

I think the testing pyramid reflects a false correlation — it seems to assert that higher up the pyramid tests are more expensive to write/maintain and longer to run. In reality the execution time of a test says nothing about how hard the test is to write. Sometimes a very fast to execute unit test can be much harder to write/maintain than a longer running test that avoids mocking an api and perhaps utilizes abstract…

> to get the most value, test suites should accelerate the time to useful feedback Well, they should also optimise the usefulness of the feedback they provide. Typically, tests higher up the pyramid are also more brittle (e.g. end-to-end tests might fire up an entire browser and Selenium), and thus are more likely to fail when in actuality, nothing is wrong. That's an additional reason for limiting the number of thos…

Brittle tests seem not useful in general though aren't they?

I'm not sure its necessarily true that brittleness must correlate with height in pyramid or execution time -- in my experience brittleness correlates with selenium more than it does pyramid height (that's a statement about selenium more than it is a statement about any particular category of testing pyramid).

Its possible to write very useful non-brittle tests using something like headless chrome ...

Re: Write tests. Not too many. Mostly integration

#315

Earlier quoted context omitted.

>I find when you're writing tests first, you're being forced to write code without understanding the problem space yet and you don't have enough code yet to see the better abstractions. That's why it's better to start with the highest level tests first and then move down an abstraction level once you have a clearer understanding of what abstractions you will need.

Can you do that with TDD though? Why not just sketch the code out first before you start writing tests? I find TDD proponents don't take into account that writing tests can actually be really time consuming and challenging, and when you've got a lot of code that is tests, refactoring your tests becomes very tedious.

You can do that with TDD (it's called outside-in), although I agree that it is time consuming and challenging, especially without the right tools.

Re: Write tests. Not too many. Mostly integration

#316

Earlier quoted context omitted.

Extension methods are useful for only one reason: they trigger code completion for browsing what this object can do. Static methods suffer from FP code completion problems (you can’t complete easily in the first arg of a function/procedure).

I think I am not mistaken in saying extension methods, like lambda functions, were invented primarily for the use case of Linq. Even if they weren't, that's how Linq is implemented, so extension methods serve more than that "one purpose" if you don't insist on writing C# in the style of C# 2.0.

They came out at the same time, I’m sure there was some influence between them (Mads Tergesen would know better). However, all the functionality added in could have been done with static methods, just with more verbose syntax. LINQ query syntax could have been special cases. Anyways, I like what they came up with, it’s very versatile.

Re: Write tests. Not too many. Mostly integration

#317
post #65
post #6

I'd take a slightly different take: - Structure your code so it is mostly leaves. - Unit test the leaves. - Integration test the rest if needed. I like this approach in part because making lots of leaves also adds to the "literate"-ness of the code. With lots of opportunities to name your primitives, the code is much closer to being self documenting. Depending on the project and its requirements, I also think "lazy"…

- Structure your code so it is mostly leaves. - Unit test the leaves. - Integration test the rest if needed. Exactly. You expressed my thoughts very succinctly. Though I feel the post tries to say the same just in a lot more words.

I didn't get that from the post at all, I thought the post advocates mostly for integration tests and I didn't see anything about refactoring code to make unit testing easier.

Re: Write tests. Not too many. Mostly integration

#318

Earlier quoted context omitted.

the point is that blind 100% coverage cargo-cultism is not a working strategy.

Does anyone even believe in 100% coverage?

I never said anything about it, personally.

It's nice to shoot for if you're greenfield. Line coverage != path coverage and blind adherence to line coverage metrics isn't going to guarantee anything.

Re: Write tests. Not too many. Mostly integration

#319
post #13

Why does everyone rethink a working strategy. Write lots of unit tests that are fast. Write a good amount of integration tests that are relatively fast. Write fewer system integration tests that are slower. The testing pyramid works. He even talks about it in this post, and then ignores the point of it. You write lots of unit tests because you can run them inline pre-commit or in a component build. If you integration…

Because for certain kind of project the strategy stops working. I work as QE on a fairly large, ~7 years old project. Micorservice architecture has been attempted. We always merge to master, which means that everything more-or-less is a feature-branch merge. We have too many repositories to count. And what we learned is, that most of the components we have are just too thin to allow for useful unit-test coverage. Alm…

The units tell you tons. They just don't tell you the whole story. Trust me, try complex distributed systems testing in an environment the underlying services themselves are bug-prone and issuing stack traces all over because of poor fencing/bounds checking/et al.

You may think that way now regarding mocking the database, but where you will find yourself down the line is trying to devise a functional system integration test case for a slightly esoteric condition (deadlocks, timeouts). It's nice to have the scaffolding of a unit testing framework with robust mocks for those situations.

Edit: also, you should consider a gitflow workflow (dev -> integration -> master/stable) and make feature branch off of dev to insulate your master.

Re: Write tests. Not too many. Mostly integration

#320
post #77

Earlier quoted context omitted.

>Why does everyone rethink a working strategy. Write lots of unit tests that are fast. * Because I want to avoid writing more code than necessary. * Because I want to avoid writing tightly coupled code. * Because I'd rather have a test that takes 2x longer and catches 5% more bugs. Premature optimization and all that.

Lots of unit testing can cause tightly coupled code, if the units are too small and/or against internal APIs: The tests are tightly coupled to a piece of code which should have been able to change freely.

I don't know what to say... you have to write good code and good unit tests. I think talking how to do that is a bit outside of the scope here, but mocks for external apis & sensible function complexity metrics are good things.
Post reply on HN