HN user

mattvanhorn

666 karma
Posts3
Comments73
View on HN

Tell them to subpoena you - then the choice to testify is not yours any more. You'll have to. But you can tell future employers that you were forced, if you'd like to.

I'm terribly saddened by this. It's a great genre bookstore, and although I have a kindle, I still love having dead tree books, especially ones I read for pleasure.

I worked at a place where the VPE would talk about technical debt as a mortgage. Yet they had a culture that abhorred paying down the debt through refactoring, and so it was more like one of those interest-only payment mortgages. They paid higher interest in the form of reduced productivity and speed, and ended up with the same amount of debt as when they started.

I suppose that if you do keep things that small, it could work well to trash and rewrite. Plus it has the benefit of making you consider explicitly what is going/staying.

Personally, I like my tests to be pretty clearly about the behavior of the contract, and not the implementation, which is hard when you require every method have a test.

I'd also be concerned that other team members are reluctant to delete tests - as this is a dysfunction I see often, and try to counteract with varying degrees of success.

I agree with the general approach suggested in the article (in tests, write/assume the code you wish you had).

But one detail ran counter to my personal practice.

I don't believe that "symmetrical" unit tests are a worthy goal. I believe in testing units of behavior, whether or not they correspond to a method/class. Symmetry leads to brittleness. I refactor as much as possible into private methods, but I leave my tests (mostly) alone. I generally try to have a decent set of acceptance tests, too.

Ideally, you specify a lot of behavior about your public API, but the details are handled in small private methods that are free to change without affecting your tests.

I think that Red-Green-Refactor is as much about learning to habitually look for and recognize the refactoring opportunities as it is about being meticulous in reacting to those opportunities.

It's true that nothing forces your to refactor - but I think wanting that is a symptom of treating TDD as a kind of recipe-based prescriptive approach. It is not a reflection of the nature of TDD as a practice or habit.

It's a subtle difference, but important:

A recipe says "do step 3 or your end result will be bad"

A practice says "do step 3 so you get better at doing step 3"

If "the design in your head" involves classes or functions, or any programming language dependent ideas, then it you are not doing TDD. I call this style test-first, or pseudo TDD.

But if the design in your head is an algorithm that can be expressed in natural language, then TDD will let you take that and make a loosely coupled, maintainable program out of it.

Good post on the difference here: http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-me...

I think far too many people fail to make the distinction between designing an algorithm and designing a program (which implements it).

This is why I have to watch co-workers create dozens of useless error classes and utility functions, and totally ignore YAGNI, before actually taking a single step towards a working program.

If you don't know the algorithm, and haven't figured out the abstractions, then just slinging some implementation code is the easiest (and laziest) thing you can do. It's basically a way of avoiding having the necessary conversations. In this case, the question that needed answering before beginning TDD was: "How does one efficiently solve a sudoku puzzle (as opposed to just manipulating one)"

I still do a lot of decent work on a non-unibody MBP from 2008, so I think a 2009 model would still have some utility, but I would consider the price carefully - it might be more worth it to buy a newer MB air or something, knowing you'll get a few more years out of it.

I don't find implementing the tests very difficult at all - but I am comfortable with regular expressions, and ruby.

It's no more burden to write step definitions than it is to write RSpec directly. I use SOLID OOP to write my tests, most of the logic lives in regular old methods, and my steps look like:

  Then 'the current subscription payment date should be tomorrow' do
    verify_next_payment_date(Date.today + 1)
  end
Since I start with the Gherkin file, I type less than 10 keystrokes to make the step.

I was listening to Robson Moura (BJJ black belt) talk about why he loves the art so much. He said something like: when you walk out of a karate class, after a lot of sparring, you feel like a tough-guy who's ready to kick some ass, but when you walk out of a BJJ class, where people smaller than you have just repeatedly demonstrated that they could kill you with their bare hands, you feel very humbled.

The effects on ego tend to weed out a lot of assholes, and between this and the mental challenges of the sport, it is one of the reasons I've come to love it. (Ryron & Rener also do a pretty good job of distinguishing between self-defense and sport jiu jitsu, at least in the videos I've seen from them.)

full disclosure: (I work for New Relic now)

I've also used New Relic developer mode to identify requests that have too many queries, and optimize them. At my last job I cut the queries on the homepage by 75% this way. I also used it to look at GC, tuned that, and cut the total response time by about 80%

Personally, I'd like to see some of the smart folks in the community assist the police in identifying the source of the threats and helping to ensure that those miscreants get jail time.

The Start-Up Trap 13 years ago

Here's my work flow:

I write a specification (using RSpec) of some behavior. It fails.

Then I write code to make that specification pass.

Now the code is working correctly, as I have defined it.

Then I refactor, using my specs (tests) as a safety net to ensure that everything after the refactor still works as intended.

This is a _VERY_ different approach than coming up with some solution in my head, implementing it (most likely with bugs), and then using tests to find and eliminate as many bugs as possible (but usually not all of them).

Any errors that make it through to a commit, when I am doing TDD, are errors in how I have specified (or failed to specify) the behavior. Any errors in the design or implementation of the solution are caught by building to a spec in very small steps.

That's the key difference between properly done BDD/TDD and other testing. Writing the tests prevents bugs instead of catching them, and it ensures that behavior does not change after refactoring.

It may be a subtle distinction, but in practice it makes a huge impact.

The Start-Up Trap 13 years ago

I won't write tests for getters and setters, but then again, I try not to write getters and setters very much in the first place.

The Start-Up Trap 13 years ago

Actually, that is a great metaphor. But you should know, TDD is the way I repeatedly sample and appraise my work as I go. Multiple times per hour, in fact.

Red -> Green is the sampling and Green -> Refactor is the appraising.

The Start-Up Trap 13 years ago

It's Test Driven Development - not Proof Of Correctness. The worst thing about TDD having 'test' in the name is that people think it is about preventing bugs, or catching them.

It is not.

It is about enabling easy refactoring. The other stuff - preventing regressions, catching bugs, etc. is gravy.

The Start-Up Trap 13 years ago

I can only speak from my experience (20 years) of developing web apps, but I've never seen a cohesive, loosely coupled web app, that was both over 2 years old AND not using some form of TDD.

The Start-Up Trap 13 years ago

I have 20 years of experience developing web apps, most of which was at startups. Some succeeded despite not doing TDD, others failed despite doing it.

I don't think doing TDD alone will make or break a startup.

But I will say this - when your startup requires 40 developers to maintain the "festering pile of code" instead of the 4-6 that should be required, you are wasting investor dollars.

When prospective candidates for employment see your code and run away from the interview, you are wasting time & money.

When your developers get burnt out dealing with that pile of crap, and your annual turnover exceeds 100% you are wasting time, money and experience.

All of these things I have seen happen, personally, at companies I worked for.

And skipping TDD doesn't help you go faster. The only timescale I've seen where it seems that TDD slows me down, is on the order of minutes. Even after working a couple of hours, I'm ahead of the game because my code works - I don't spend time with a debugger, and I won't have to do a week of refactoring next month just to add a new feature.

The Start-Up Trap 13 years ago

Actually, TDD is the way you figure out what you are building. People who start with a solution in mind may write tests first, doing a kind of pseudo-tdd, but they are not reaping the benefits of letting the requirements drive the design.

This is NOT TDD:

1 - Think of a solution

2 - Imagine a bunch of classes and functions that you just know you’ll need to implement (1)

3 - Write some tests that assert the existence of (2)

4 - Run all tests and fail

5 - Implement a bunch of stuff

6 - Run all tests and fail

7 - Debug

8 - Run the tests and succeed

9 - Write a TODO saying to go back and refactor some stuff later.

see: http://cumulative-hypotheses.org/2011/08/30/tdd-as-if-you-me...