7

I use JavaScript with JQuery for a Rails application. I have some dynamic behaviour in this one. As a Ruby developper, I like TDD/BDD, specialy with RSpec. For the moment, I test my JavaScript manualy. It's not the best way because a change, somewhere, can break the code somewhere else. The is a lot of avantages of using TDD.

Testing in javascript seems to be complicated because it should test a lot of user interaction. I can test the behaviour in complete integration, with Capybara for example, but my tests will be very slow.

For example, I have a form with dynamic behaviour. In this form, I have 5 or 6 dynamic fields which change if I select an option, choose a radio button or check a checkbox. In some cases, there is ajax calls. For this form, I think I can make about 20 tests just for a form. Is it really usefull to have this tests?

So, what's your rules for a standard web application?

closed as primarily opinion-based by Robert Harvey, Corbin March, Reactgular, user40980, gnat Aug 8 '13 at 6:24

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 5
    Did you have a specific concern? Otherwise, this seems more like a discussion than a question. – Robert Harvey Aug 7 '13 at 17:15
  • @RobertHarvey I added an example. Not really specific. – Dougui Aug 7 '13 at 17:26
  • 1
    I don't. I think testing is bad for many case and a competitive advantage of mine for not doing. 10 years programming. Many commercially successful apps. No problem ever found for not testing. – MaiaVictor Aug 7 '13 at 17:26
  • 1
    In general, I regard UI testing as a form of integration testing. People sometimes confuse this with unit testing, but that's not really what it is. Automated test frameworks are especially useful in this regard, if you want to mechanize such tests. – Robert Harvey Aug 7 '13 at 17:27
  • Currently I only do functional testing, but dealing with JS unit testing frameworks are in my short-terms plans. – py_script Aug 7 '13 at 18:17
12

Only Test if it Brings Value

I don't test typically, but if I did I certainly wouldn't aim for any percentage number of coverage or loading tests in front of everything I wrote but rather focus on handling of things I don't control and things that were coded poorly that I don't have time to rewrite.

If behavior of things I do control and that I did in fact write is unpredictable, my problem isn't that I don't have tests, it's that I wrote piss-poor code that will be ungainly and a beast to maintain regardless of how soon I find out that it's acting up (which is usually right away on the client-side if you haven't allowed it to be overwhelmed by pointless complexity). You only get so much time and UI tends to involve too many factors to attempt to micromanage the process of writing it successfully with something like a test-first TDD approach. I prefer a focus on keeping the code clean, obvious, minimal and robust.

Bury the DOM

IMO, the key to discovering things that are within reason to test is to bury all the client-side stuff in objects that can be manipulated more at an app-level of architecture. The goal being that at the highest level - so implementation and re-usable code typically - you just have plain vanilla objects. You're not looking at ajax methods being fed large sets of options and $ and document.getViaRidiculouslyExplicitlyNamedMethod, You're looking at stuff like comboFactory.build('combo_class_name') that any server-side dev that was mostly clueless about the client-side could figure out how to use.

What this does for you is split minutiae of the DOM-related stuff where keeping things robust isn't as simple as loading tests in front of every little thing you write, from the more app-level data flow concerns that you can actually think of in terms of a flow chart. That's where I would focus testing efforts if I wanted them.

So in the case of your crazy dynamic form:

If your ajax is all bundled up into service objects or a part of some silly seamless data layer that hides the async communication factor completely, you don't need to test in the context of the form. Service calls work or they don't. They can be tested independently.

For the dynamically populated form inputs, The vast majority of these inputs load from one other thing getting set. I wouldn't consider something like that worth testing as it's more likely to break due to DOM shenanigans tied to CSS or an HTML if your services already check out. So, maybe Selenium at the most. but unit tests don't really make sense to me there. Test-first-TDD never made sense to me but especially not for something like that.

Thoughtful Architecture First

If we have an ultra-complicated form with inputs populating themselves and mutating based on all 20 other input states in that form, assuming I had no power to call for a redesign (which would typically be the real problem in that case), I would go with a data-bound event-driven approach such that each input manipulation alters one set of data, triggering events on the data object itself that might cause other portions of your data model to mutate but the inputs themselves at most set the piece of data they care about and listen for changes to that set of data resulting in at most a handful of different types of behavior.

For each input, that's two simple avenues with minimal branching that work or don't work and we're not likely to change in a way where potential fail-points aren't obvious and it's easy to hand test thoroughly before committing. That keeps the spider web of relationships confined to whatever your data abstraction is, narrowing all the more uncertain stuff down to something that itself only cares about what's left when other data elements get altered.

The question is what you value most, what I've just described or something a little bit more tangled and confusing but with tests all over it. My opinion is fairly strongly weighted on the former, but if you can manage both, power to you.

In UI, the DRY principle is paramount, IMO. Don't add tests unless there's a good argument that they'll add value over more time spent carefully crafting a code base in the first place such that it's easy to read, easy to modify, and easy to re-use portions of elsewhere. All three of those things require a number of other widely acknowledged critical heuristics in the craft of coding for which there is no substitute in my experience. Those are what drive my architecture and as a result it's not hard to add tests most of the time if I want to but I would never let a testing strategy actually drive my architecture. I'm only just starting to become more of a generalist but I'm fairly convinced at this point that these priorities work well for more than just web UI.

  • 1
    Nice answer, especially the part about pushing the UI back into the application logic as much as possible. – Robert Harvey Aug 8 '13 at 17:41
  • Thanks, Selenium was something I was looking for. – Akseli Palén May 9 '15 at 19:57
0

At work we've just started to use jasmine to test our javascript. There's a bit of a learning curve (but if you're familiar with RSpec it won't be too bad) and it may require a bit of a change in how you structure you code but overall it's been a really positive experience.

Keep in mind this is behavior testing for your code. This isn't a replacement for acceptance and integration testing.

0

A lot of individuals I know come from the mindset of the testing occurs from a person, not from a coded test. This is, of course, the lack of a proper understanding of TDD using tools like QUnit (one of my favorites). I used QUnit for a JavaScript game framework to ensure my components did the job.

It depends on how complex your JS really is, how the JS is been designed (unit testing requires it developed in a modular fashion). If it's directly tied to the DOM, it will be more difficult, but not impossible, to test. If you're only testing a few assignments, I wouldn't worry about it per se; however, if a lot of your UI is javascript-based, I would consider using a framework, and modularizing the code where possible.

Not the answer you're looking for? Browse other questions tagged or ask your own question.