Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having never written any automated tests, how should I start behaviour-driven development? [closed]

I've been programming for years in plenty of languages and like to think I'm generally pretty good at it. However, I haven't ever written any automated testing: no unit tests, no TDD, no BDD, nothing.

I've tried to start writing proper test suites for my projects. I can see the theoretical value of being able to test all the code in a project automatically after making any changes. I can see how test frameworks like RSpec and Mocha should make setting up and running said tests reasonably easy, and I like the DSLs they provide for writing tests.

But I have never managed to write an actual unit test for any part of my code. Stuff I write never seems to be very testable in a way that's actually useful.

  • Functions don't seem to be very callable outside the context in which they're used. Many functions I write make HTTP-request calls, or database queries, or some other non-easily-testable call.
  • Some functions return strings of HTML. I can compare the HTML string against a hardcoded version of the same string, but that only seems to limit my ability to change that part of the code. Plus having loads of HTML in my test code is a mess.
  • I can pass mock/spy objects into a method, and make sure they get certain method calls, but as far as I can tell that's only testing implementation details of the method I'm "testing".

How would I go about getting started with proper BDD testing? (I'd preferably like to do this using Mocha and Node.js, but general advice on BDD is fine too.)

like image 666
00dani Avatar asked Feb 14 '13 09:02

00dani


1 Answers

It looks like the main question you're asking is, "how do I write testable code"?

Being a fan of object oriented programming I know I'm biased, but in my experience it's far easier to test code that is written in an OO style. The reason for this is that unit tests are meant to test small, isolated components of a system, and well designed object oriented code (mostly) provides this.

I agree that functions are often linked to the context that they're in, making them difficult to test. I don't have a lot of experience with functional programming, but I know that context is often passed around in some sort of variable, making it difficult to separate concerns of functions.

With OO programming, I have successfully tested objects that wrap around HTTP requests, database queries, etc, by mocking the object that does the actual network request to return a known set of data. You then test that your wrapper object handles that data in the right way. You can also test for failures and unexpected data. Another way of doing this is by setting up a local server that you use instead of the normal endpoint, but this gives your test suite an external dependency, which should be avoided when possible.

When testing HTML, many people don't do this at all, due to the highly changeable nature of the view layer. However, there are some things that are really worth testing, but never the full string of HTML - as you've discovered, just a tiny change would mean that the whole test breaks. What are you really testing in that case, that two strings in separate parts of your code base are the same?

The best thing to do is the load the HTML string from your function/object into an HTML parser library, and you can normally use Xpath or CSS selectors to check for tags with particular classes, IDs or other attributes, and check the number of elements that match certain requirements. Rspec has this built in (the have_tag() method), as do many testing libraries.

Something else you might like to look at is integration testing (e.g. Capybara, Selenium). This will load your web app with a JavaScript engine, so you can check for HTML elements and also JavaScript events.

On the whole mocking/stubbing thing, you generally only want to do this with objects that are dependencies of the object you're testing. Otherwise you can pretty much manipulate anything to assert as true!

As for resources on testing, I'd recommend looking at test driven development books even if you don't plan to practice TDD. The main reason is that they throw you head first into testing. here are a few:

  1. Kent Beck's book Test Driven Development: By Example
  2. Free ebook on TDD with PHP, Practical PHP Testing
  3. This website, Art of Unit Testing
  4. Slideshare - just search for unit testing or BDD and read as many as possible!
  5. David Chelimsky et. al.: The RSpec Book
like image 196
2 revs, 2 users 88% Avatar answered Sep 27 '22 17:09

2 revs, 2 users 88%