Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reloading fixture for each spec #15

Open
dan-manges opened this issue Jul 19, 2009 · 14 comments
Open

reloading fixture for each spec #15

dan-manges opened this issue Jul 19, 2009 · 14 comments
Labels

Comments

@dan-manges
Copy link

Would it be possible to reload the HTML fixture before each spec? I'm having problems because one spec will modify the dom, affecting the state for all other specs.

@drnic
Copy link

drnic commented Jul 20, 2009

In theory we could clone $('body').html() before each test and then restore it afterwards. Would this retain any events etc attached to all the DOM elements?

@drnic
Copy link

drnic commented Jul 20, 2009

BTW, I see this issue as the only thing (and the Safari bug and acceptance of #14) stopping blue-ridge from being perfect.

@karnowski
Copy link

I use this:

function fixture(element) {
$('

').append(element).appendTo("body");
}

function teardownFixtures() {
$("#fixtures").remove();
}

Then I call the "fixture" function in my spec and "teardownFixtures" in an after block. I've been hesitating to include this as a standard BlueRidge component, though, as it's very jQuery specific. I might have to rethink that.

@dan-manges
Copy link
Author

@karnowski what do you think about reloading the html fixture? Is that something you would welcome in blue-ridge?

@karnowski
Copy link

@dan-manges: I'd definitely be interested.

@jonah-williams
Copy link

I've found myself adding the following to many of my specs and writing my tests to operate only on DOM elements within a #fixtures div:

var bodyContent;

before(function() {
    if (bodyContent == null) {
      bodyContent = $("#fixture").html();
    }
    else {
      $("#fixture").html(bodyContent);
    }
});

I'll probably add that to my fixture and spec templates at some point but I'm not sure it makes sense to try to reload the fixture in all cases. I don't see how you could be certain to reload the fixture's state while still being able to run the tests by opening the fixture's html file. Would including the sort of reset I'm using in the default templates be useful to anyone else?

@botandrose
Copy link

Hello, folks! The following gist is a proof of concept for automatic transactional fixtures (including events).

http://gist.github.com/235556

Is there interest in developing this into a patch?

There is a dependency on jQuery... $.fn.clone(true) is doing all the heavy lifting, but isn't this a moot point since Screw Unit depends on jQuery as well?

@njackson
Copy link

Just as an aside. I've recently found that the pain associated with the non-reloading of the fixture was actually my tests telling me something about my code. Usually, what I found was that I was trying to do too much manipulation of the dom deep down in my code. I started removing most of the dependencies on the fixture, itself, relying on a thing layer that grabbed the node, cloned it, then passed it to the javascript to manipulate.

My general rule has become that only a very thin layer of entry-point javascript functions should be allowed to do $(), rather than $(element).find()

@coreyhaines
Copy link

HAHA! njackson's comment was actually made by me. Pairing station confusion. :)

@jonah-williams
Copy link

I completely agree that most selectors should be given a context rather than allowed to search the entire dom but I don't think I want to start cloning nodes for all of my tests. I like that my tests do change the dom so that when they fail I can inspect the results.

@coreyhaines
Copy link

If you completely agree, then not wanting to clone nodes for all your tests doesn't make much sense. :)

The inherent problem with having your tests manipulate the raw dom of the fixture is that they are no longer isolated from each other. If you create well-isolated, focused unit tests, then you should be able to figure out what happened without having to visually inspect the results.

The other thing I have noticed with my own stuff is that I have begun isolating most of my javascript from the dom for exactly this reason. So, my javascript is becoming more and more decoupled and, thus, ends up being a lot more reusable. If the majority of your javascript code touches the dom, there are some coupling and design issues that could be popping up unnoticed.

@ndp
Copy link

ndp commented Apr 2, 2010

I am happy with this not being in blue ridge itself. Our "workaround" works great, and is only one line in your tests (or spec_helper). It is an evolution of what Jonah posted above: (http://gist.github.com/352871)
// Reset the DOM between BlueRidge/ScrewUnit tests.
// Supports multiple fixtures and allows introspection of DOM state after tests run.
// Usage:
// before(function() { $('#fixture).fixture(); });
jQuery.fn.fixture = function() {
this.each(function() {
if (this.original) {
$(this).html(this.original);
} else {
this.original = $(this).html();
}
});
}

@botandrose
Copy link

Problem is, that still doesn't preserve bound events. Tests will behave differently based on which order you run them in.

@ndp
Copy link

ndp commented Apr 2, 2010

Yes... that's kind of the point... it wipes out everything between tests... which is generally what I want.

But I like that this is not built-in behavior, then you can have fine grained control-- and have different fixtures for different describe blocks, resetting as appropriate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants