views:

378

answers:

7

Recently I've came up with the question is it worth at all to spent development time to generate automatic unit test for web based projects? I mean it seems useless at some point because at some point those projects are oriented on interactions with users/clients, so you cannot anticipate the whole possible set of user action so you be able to check the correctness of content showed. Even regression test can hardly be done.
So I'm very eager to know to know the opinion of other experienced developers.

+1  A: 

Yes, it is. I just ran into an issue this week with a web site I am working on. I just recently switched-out the data access layer and set up unit tests for my controllers and repositories, but not the UI interactions.

I got bit by a pretty obvious bug that would have been easily caught if I had integration tests. Only through integration tests and UI functionality tests do you find issues with the way different tiers of the application interact with one another.

Doanair
I second this. You won't see the value until it saves your butt. Then you'll wonder how you slept at night without it. :)
cwash
Ok, but what do you mean by integration test? How would you do it?
Artem Barger
An integration test tests functionality from end-to-end. Normal unit tests only test the function/method you wish to test, nothing else.For example, to unit test a method in your business logic that gets a list of customers from a database, you would fake-out the database.An integration test, however, would go all the way down to the database and back, to test how it all works together. Same thing on a web page. Using WATIN or Selenium, you can actually hit the web page you are wanting to test and ensure data is getting returned properly, etc. The test would exercise all tiers of your code.
Doanair
I would not spend a ton of time with automated web browser testing, but I think it provides a lot of value, especially for your "critical path" functions (functions you _really_ care about.
Doanair
@Doanair exactly, the sweet spot are those when they don't change much at all. definitely cover those with automated browser testing. cheap regression suite from stuff you're checking manually anyway.
cwash
+3  A: 

I think it's always useful, at least for the most common actions. Yes, you cannot test the unexpected, but current tools allow you to emulate user behaviour quite accurately.

Using a framework like Canoo (http://webtest.canoo.com/webtest/manual/WebTestHome.html) might help you.

Pere Villega
I agree with you here, only thing I would add is be weary of over specifying or spending too much time on these tests. I'd say test the happy path and what's causing you pain at this level and then write tests for defects that come up but definitely no more than that.
cwash
Yes, you right and I aware about couple of this tools, but still, let say I have a web based application with very dynamic content any of those tools won't help me, since they can only deal with static contents.
Artem Barger
+2  A: 

Selenium have a good web testing framework

http://seleniumhq.org/

Telerik are also in the process of developing one for web app testing.

http://www.telerik.com/products/web-ui-test-studio.aspx

Peter
WATIR and WATIN are also good alternatives.
Doanair
+1  A: 

If you're writing a lot of Javascript, there have been a lot of JS testing frameworks that have come around the block recently for unit testing your Javascript.

Other than that, testing the web tier using something like Canoo, HtmlUnit, Selenium, etc. is more a functional or integration test than a unit test. These can be hard to maintain if you have the UI change a lot, but they can really come in handy. Recording Selenium tests is easy and something you could probably get other people (testers) to help you create and maintain. Just know that there is a cost associated with maintaining tests, and it needs to be balanced out.

There are other types of testing that are great for the web tier - fuzz testing especially, but a lot of the good options are commercial tools. One that is open source and plugs into Rails is called Tarantula. Having something like that at the web tier is a nice to have run in a continuous integration process and doesn't require much in the form of maintenance.

cwash
Can you advise JS testing framework other than Firebug?
Artem Barger
Depends on what you're doing. There are a few BDD-style frameworks out now if you're putting a lot of rules/features into custom Javascript. ScrewUnit is one I've played with before.FireUnit is built into Firebug and works OK for general testing. Not great to automate or run continuously, however.JSUnit is a good general purpose one.If you're using Prototype, check out unittest.js from Script.aculo.us and if you're using JQuery look into QUnit.
cwash
There's also Test.Simple. I just wired it together with Selenium so it can be automated and interpreted from the command line so they can be automatically smoke tested. http://use.perl.org/~schwern/journal/39088
Schwern
This looks neat as well:http://misko.hevery.com/2009/05/22/yet-another-javascript-testing-framework/
cwash
+1  A: 

It really depends on the structure and architecture of your web application. If it contains an application logic layer, then that layer should be easy to unit test with automating tools such as Visual Studio. Also, using a framework that has been designed to enable unit testing, such as ASP.NET MVC, helps alot.

Kyberias
Right, but I'm not talking about application logic layer. Each unit at application layer it easy to test, but they integration on the client/browser is something more complicated and it looks like kind of useless to spent time to cover 5-10% of over all possibilities. Looks more common to develop user scenarios and test accordingly.
Artem Barger
A: 

Unit tests make sense in TDD process. They do not have much value if you don't do test-first development. However the acceptance test are a big thing for quality of the software. I'd say that acceptance test is a holy grail of the development. Acceptance tests show whether the application satisfies the requirements. How do I know when to stop developing the feature --- only when all my acceptance test pass. Automation of acceptance testing a big thing because I do not have to do it all manualy each time I make changes to the application. After months of development there can be hundreds of test and it becomes unfeasible (sometime impossible) to run all the test manually. Then how do I know if my application still works?

Automation of acceptance tests can be implemented with use of xUnit test frameworks, which makes a confusion here. If I create an acceptance test using phpUnit or httpUnit is it a unit test? My answer is no. It does not matter what tool I use to create and run test. Acceptance test is the one that show whether the features is working IAW requirements. Unit test show whether a class (or function) satisfies the developer's implementation idea. Unit test has no value for the client (user). Acceptance test has a lot of value to the client (and thus to developer, remember Customer Affinity)

So I strongly recommend creating automated acceptance tests for the web application.

The good frameworks for the acceptance test are:

  • Sahi (sahi.co.in)
  • Silenium
  • Simpletest (I't a unit-test framework for php, but includes the browser object that can be used for acceptance testing).

However

You have mentioned that web-site is all about user interaction and thus test automation will not solve the whole problem of usability. For example: testing framework shows that all tests pass, however the user cannot see the form or link or other page element due to accidental style="display:none" in the div. The automated tests pass because the div is present in the document and test framework can "see" it. But the user cannot. And the manual test would fail.

Thus, all web-applications needs manual testing. The automated test can reduce the test workload drastically (80%), but manual test are as well significant for the quality of the resulting software.

As for the Unit testing and TDD -- it make the code quality. It is beneficial to the developers and for the future of the project (i.e. for projects longer that a couple of month). However TDD requires skill. If you have the skill -- use it. If you don't consider gaining the skill, but mind the time it will take to gain. It usually takes about 3 - 6 month to start creating a good Unit tests and code. If you project will last more that a year, I recommend studding TDD and investing time in proper development environment.

Max Kosyakov
I have to disagree with statement about unit test make sense in TDD process. Unit test is always make sense for many reason.
Artem Barger
A: 

You cannot anticipate the whole possible set of user action so you be able to check the correctness of content showed.

You can't anticipate all the possible data your code is going to be handed, or all the possible race conditions if it's threaded, and yet you still bother unit testing. Why? Because you can narrow it down a hell of a lot. You can anticipate the sorts of pathological things that will happen. You just have to think about it a bit and get some experience.

User interaction is no different. There are certain things users are going to try and do, pathological or not, and you can anticipate them. Users are just inputting particularly imaginative data. You'll find programmers tend to miss the same sorts of conditions over and over again. I keep a checklist. For example: pump Unicode into everything; put the start date after the end date; enter gibberish data; put tags in everything; leave off the trailing newline; try to enter the same data twice; submit a form, go back and submit it again; take a text file, call it foo.jpg and try to upload it as a picture. You can even write a program to flip switches and push buttons at random, a bad monkey, that'll find all sorts of fun bugs.

Its often as simple as sitting someone down who's unfamiliar with the software and watching them use it. Fight the urge to correct them, just watch them flounder. Its very educational. Steve Krug refers to this as "Advanced Common Sense" and has an excellent book called "Don't Make Me Think" which covers cheap, simple user interaction testing. I highly recommend it. It's a very short and eye opening read.

Finally, the client themselves, if their expectations are properly prepared, can be a fantastic test suite. Be sure they understand its a work in progress, that it will have bugs, that they're helping to make their product better, and that it absolutely should not be used for production data, and let them tinker with the pre-release versions of your product. They'll do all sorts of things you never thought of! They'll be the best and most realistic testing you ever had, FOR FREE! Give them a very simple way to report bugs, preferably just a one button box right on the application which automatically submits their environment and history; the feedback box on Hiveminder is an excellent example. Respond to their bugs quickly and politely (even if its just "thanks for the info") and you'll find they'll be delighted you're so responsive to their needs!

Schwern