30

I'm going to start my first real project in Ruby on Rails, and I'm forcing myself to write TDD tests. I don't see real advantages in writing tests, but since it seems very important, I'll try.

Is it necessary to test every part of my application, including static pages?

Matteo Pagliazzi
  • 366
  • 1
  • 5
  • 15

11 Answers11

49

TDD isn't about testing, it's about design. Writing the tests forces you to think about how the class is supposed to work and what kind of interface you need. The tests are a happy side effect that makes it easier to refactor later.

So, with that in mind, what is the behavior of a static page and what is the interface?

My first response would be "none" and "none".

Jon Strayer
  • 666
  • 5
  • 7
34

It's always a cost-benefit analysis. What's the cost of the feature breaking to you? If the cost is high, then test well and thoroughly. If the cost is low, test lightly or not at all.

There's also the cost of time-to-market to consider. Maybe it's better for you to deliver a mostly working feature than to be late delivering a completely working feature.

It's almost impossible to answer these questions in the general IMO.

I think it's more important to preserve the ability to test in the case that some feature turns out to be more important than you originally realized.

Doug T.
  • 11,737
8

I would say "yes". If you have tests covering even the simplest features and code, then you can have confidence that adding new code doesn't cause in-place code to quit working. Similarly, putting in a test for every bug you encounter keeps regressions from creeping back in.

Bruce Ediger
  • 3,535
3

Yes, you should test everything...

You won't necessary be able to write automated tests for everything. For your static pages, look into using Selenium http://seleniumhq.org/ for making sure things are correct.

From my experience, some front end things are next to impossible to write test cases for but that is why you would actually want to test using the Mark 1 eyeball.

Schleis
  • 3,416
  • 1
  • 21
  • 21
2

Testing is as important as coding. You must heard the saying "If something can go wrong, it will". INMO, Out of the many techniques of software engineering that are employed to enhance quality, Testing is the most valuable one in helping you find problems early.

While testing everything is not possible (specially with small teams and large systems), it does not mean you skip testing altogether. Is testing worth it? See the section "Finding faults early" in See Wiki-SoftwareTesting.

NoChance
  • 12,532
2

As others have mentioned, in Ruby on Rails testing it is far more important than in (most) other languages. This is due to the lack of a compiler.

Languages such as Delphi, C++, VB.NET, etc... are compiled languages, and your compiler will pick up a lot of mistkes such as typos in calls to a method. In Ruby on Rails you will only know if there is a typo or a mistake in your code if that particular line of code is run or you are using an IDE that shows visual warnings.

As EVERY single line of code is important (otherwise it wouldn't be there) you should test every method you write. This is a lot simpler than it sounds if you follow some basic TBDD tools.

I found that Ryan Bates' Rails Cast on How I test was invaluable to me and really highlighted the simplicity of TBDD if done correctly.

jamesc
  • 121
  • 2
2

TDD Tests can also be living specifications if written that way. The names of the test methods should make sense to a business user.

1

If you're truly using the TDD methodology then you don't write code without first having a unit test you are trying to make pass.

wessiyad
  • 219
  • 1
  • 7
0

I would say to not start with TDD. Make an informed decision when you've spent more time learning architecture strategies in general. TDD won't let you skip that homework although you might start believing it does.

Here's my problem with it. When you say it seems like a lot of wasted time on stuff that will never break TDDers say you'll appreciate it when that one thing you didn't anticipate in a huge chain of dependencies gets busted. When you point out that it's impossible to predict such things before you write your app, which is uh... why we test, they tell you it's really more about design and not testing even though the testing comes in handy.

But aren't giant chains of unpredictable linked dependencies the product of crappy design?

So which is it?

Here's a thought. Let's not have huge complex chains of dependencies in the first place by considering the following two principles of object-oriented design from Design Patterns:

"Program to an interface, not an implementation"

That is to say, your objects should not care who is doing the calling or how they were made. Only that the proper args were fed in and that the methods they call from other objects they're directed to work as expected. Your chain of dependency in most cases should be at one linking point, the method call on the part of the caller and the spot where the args get dropped into your methods. That's where you log and validate and send useful messages for debug when things crap out.

And:

"Favor object composition over class inheritance"

Who's the dummy? The guy who did something to a class in a convoluted cascading inheritance scheme involving like 30 classes resulting in fringe case breakage, or the dev who came up with that architecture in the first place? TDD might help you get to the bottom of issues inside that leaning tower of class Pisa sooner than you could have without but does that make it any less painful to attempt to modify one of the endpoints of that code disaster the next time?

And that's where I get to the thing that bugs me. Does TDD really help design or does it enable bad architecture? It seems to me like it has potential to be a self-fulfilling strategy. The more your team doesn't have to own responsibility for poor architecture, the more helpful those granular testing components seem to become, but ultimately your app becomes an increasingly bigger PITA to work with (assuming they never gave much thought to architecture in the first place). And failure to acknowledge the consequences of that is hands down, always the most expensive mistake you can make when working on an application that's meant to be upgraded and modified over time.

Erik Reppen
  • 6,281
-1

To answer the question, think about "what could go wrong here". In particular, if you change the "code" (markup/whatever), how will you have confidence that you haven't broken the page. Well, for a static page:

  • it might not render
  • it might render incorrectly
  • the JS might not load
  • the paths for images might not work
  • the links might be broken

Personally, I would recommend:

  • write a selenium [1] test that checks for one string you expect on the page (near the bottom if possible). This validates that it renders.
  • check there are no JS errors (I think selenium allows this)
  • run the static pages through a html validator, and if possible, a link checker.
  • I haven't found a tool I like to validate JS, but you might find success with jslint or jshint.

The take away here is that you want something that is repeatable, easy to use, and will run automatically in your test runner.

Paul Biggar
  • 1,207
-1

Just to add to all the already excellent answers, here's my thinking on what to test, and what not to test:

Do test:

  • business logic
  • application logic
  • functionality
  • behaviour,
  • so, everything, really, except:

Do not test:

  • constants
  • presentation

So there's no point in having a test that says:

assert wibble = 3

and some code that says

wibble = 3

And there's also no point in testing presentational things, like whether the icon is in perywinkle blue, what font you've used for headings, and so on...

So, you ask, "should I test static pages", and the answer is: you test them insofar as they are part of your site's functionality, business logic, or behaviour.

So, in our app, we have a test that checks that the terms & conditions are available from every part of the site - for anonymous users, for logged-in users, from the dashboard, inside app screens etc. It just checks that there's a link called "terms and conditions" on each page, that the link works, and then the test says that when it arrives on the page, it "looks like" the Ts & Cs - just enough to reassure yourself it's the right page, without "testing a constant", or "testing presentation"... so you could check that the text is correct, for example, without checking the particular font size or text layout...

hwjp
  • 115