Testing Javascript that Manipulates the DOM

2019-03-09 16:32发布

问题:

I've been looking into javascript test suites and I have found QUnit to be very interesting. I understand how to test computational code, but...

How do you test javascript applications written primarily for DOM manipulation?

it seems like testing the position/color/etc of DOM elements would be a moot point because you'd end up doing somethign like this:

$("li.my_element").css("background-color", "#f00");

and then in your test...

$(function() {
    module("coloring");
    test("test_my_element", function() {
        var li_element_color = $("li.my_element").css('background-color');
        equals(li_element_color, "#f00");
    });
});

this just doesn't feel right because it basically just doing this:

var my_li= $("li.my_element");
my_li.css("background-color", "#f00");
if ( my_li.css("background-color") == "#f00" ) {
    return true;
}

Am I nuts? How is this supposed to be done?

edit: the heart of the question:

I guess what I'm getting at is, I need to make sure the code isn't broken before I deploy, but the vast majority of it is UI helpers and ajax. How do I test that things are appearing correctly?

A few examples:

  • test that a JQuery UI dialog is appearing on top of all other elements
  • test that the drag-n-drop is working properly
  • test that the color of a droppable changes when an element is dropped on it
  • test that the ajax is all working properly
  • test that there are no extraneous commas that will break IE

回答1:

I have found the Javascript/DOM tests, especially for the simple interactions that you are describing, are not that useful. You'll testing that things are set up right, and since jQuery is so declarative, your tests look a lot like your code.

My current thinking is that if you are writing larger JS components, it makes sense to pull out a set of interrelated behaviors both into a jQuery plugin and a set of tests for it.

But from the examples you mentioned, it sounds like you're really looking for a level of protection within your integrated website. A tool like Selenium will probably be more powerful and appropriate for you. In particular, it

  • can be automated
  • can run against multiple browsers, including IE
  • runs within the context of your web app and pages, so drag-n-drop can be tested where it really happens instead of in some test environment.
  • AJAX can be tested


回答2:

Instead of testing the JQuery css function. Your test should mock the css function, and ensure that it is called only once with the correct color. The code tested should be yours, not the frameworks.



回答3:

In addition to what Jason Harwig is saying, I would say that unit testing is a test to make sure that code is being run as expected. If you want to test that, then Jason is absolutely right about how you should do that. If you are wanting to run tests to check that the DOM manipulation is happening (UI testing) and not the actual code that is doing the DOM manipulation (unit testing), then you may want to check out something like Selenium, WatiN or Watir.



回答4:

I'm guessing that many people test visually: i.e. they look at their browser's output on their monitor, to see whether it looks like the DOM was manipulated as expected.

If that needs to be an automated test case (eg. for regression testing), then maybe they record the output (like screen capture) and do something like compare two screenshots to see whether the results are the same.

Instead of capturing a screenshot, you could just capture the whole DOM, and do a side-by-side comparison of the captured DOM trees (which might be less error-prone that comparing pixels).



回答5:

I test AJAX stuff like this:

  1. Make the AJAX call
  2. Set up a JavaScript timer
  3. Check the DOM to see if the expected changes have happened

Now, it could be that the AJAX call hasn't returned before you do your check, but this is also useful test information; with an AJAX call, there is (usually) some time after which we'd call it a failure. As an example, if we're doing a suggestion popup, and it's taken 30 seconds to come back, that's a fail.